#ifndef _DISPLAY_H
#define _DISPLAY_H

#include "../../stdafx.h"

class Display : public IO_Module
{
public:
	Display()
	{
		this->parent = NULL;
		this->moduleId = 0;
		this->cursorVisible = false;
		this->illuminationEnabled = true;
		this->commandClear = 0;
		this->commandReturnCursor = 0;
		this->commandNewLine = 0;
		this->commandSetting = 0;
		this->settingCursorVisible = 0;
		this->settingIllumination = 0;
		this->settingCursorPosition = 0;
	}

	Display(uint32 displayId)
	{
		this->parent = NULL;
		this->moduleId = displayId;
		this->cursorVisible = false;
		this->illuminationEnabled = true;
		
		switch(displayId)
		{
			case IO_DISPLAY_MAIN:
				this->commandClear = 12;
				this->commandReturnCursor = 13;
				this->commandNewLine = 10;
				this->commandSetting = 27;
				this->settingCursorVisible = 67;
				this->settingIllumination = 76;
				this->settingCursorPosition = 79;
				msleep(100);
				uart1_init(103);//9600 BAUD at 16MHz Atmel
				msleep(100);
				break;
			default:
				this->commandClear = 0;
				this->commandReturnCursor = 0;
				this->commandNewLine = 0;
				this->commandSetting = 0;
				this->settingCursorVisible = 0;
				this->settingIllumination = 0;
				this->settingCursorPosition = 0;
				break;
		}
	}

protected:
	bool cursorVisible;
	bool illuminationEnabled;
	//Commands
	uint8 commandClear;
	uint8 commandReturnCursor;
	uint8 commandNewLine;
	uint8 commandSetting;
	//Settings
	uint8 settingCursorVisible;
	uint8 settingIllumination;
	uint8 settingCursorPosition;

	void SendCommand(uint8 newCommand)
	{
		switch(moduleId)
		{
			case IO_DISPLAY_MAIN:
				uart1_putc(newCommand);
				break;
			default:
				break;
		}
	}

public:
	void Print(char* newString)
	{
		switch(moduleId)
		{
			case IO_DISPLAY_MAIN:
				uart1_puts(newString);
				break;
			default:
				break;
		}
	}

	void Print(int32 newInteger)
	{
		char buffer[12];
		ltoa(newInteger, buffer, 10);
		Print(buffer);
	}

	void PrintFloat(float newFloat)
	{
		Print((int32)(newFloat));
		Print(".");
		Print(abs((uint32)(newFloat - float((int32)(newFloat)) * 100000)));
	}

	void Print(char* newString, uint8 xPos, uint8 yPos)
	{
		SetCursorPosition(xPos, yPos);
		Print(newString);
	}

	void Print(int32 newInteger, uint8 xPos, uint8 yPos)
	{
		SetCursorPosition(xPos, yPos);
		Print(newInteger);
	}

	void PrintFloat(float newFloat, uint8 xPos, uint8 yPos)
	{
		SetCursorPosition(xPos, yPos);
		PrintFloat(newFloat);
	}

	void Clear()
	{
		SendCommand(commandClear);
	}

	void ReturnCursor()
	{
		SendCommand(commandReturnCursor);
	}

	void NewLine()
	{
		SendCommand(commandNewLine);
	}

	bool GetCursorVisible()
	{
		return cursorVisible;
	}

	void SetCursorVisible(bool newStatus)
	{
		cursorVisible = newStatus;

		SendCommand(commandSetting);
		SendCommand(settingCursorVisible);

		if(cursorVisible)
		{
			SendCommand(1);
		}
		else
		{
			SendCommand(0);
		}
	}

	bool GetLightingEnabled()
	{
		return illuminationEnabled;
	}

	void SetLightingEnabled(bool newStatus)
	{
		illuminationEnabled = newStatus;

		SendCommand(commandSetting);
		SendCommand(settingIllumination);

		if(illuminationEnabled)
		{
			SendCommand(1);
		}
		else
		{
			SendCommand(0);
		}
	}

	void SetCursorPosition(uint8 newX, uint8 newY)
	{
		if(!newX || newX > 20) return;
		if(!newY || newY > 4) return;

		SendCommand(commandSetting);
		SendCommand(settingCursorPosition);
		SendCommand(newX);
		SendCommand(newY);
	}
};

#endif
