/****************************************************************************
	Aplikace pro nastaveni parametru podsvetleni

*****************************************************************************/
#ifdef PCSIM
	#include "stdafx.h"
#endif

#include "Applications.h"
#include "GRAPHICS.h"
#include "OS.h"
#include "GLCD.h"
#include "Drivers.h"


TScreen BacklightSetupScreen;												//Obrazovka aplikace
TScreenObject BacklightSetupScreenObjects[BACKLIGHT_SETUP_OBJECT_COUNT];	//Pole grafickych objektu

TApplicationInternal BacklightSetupInternal;								//Ridici objekt aplikace
char backlightIndex = 0;													//Uroven podsvetleni

/****************************************************************************
	Definice pisem aplikace

*****************************************************************************/
FONT BacklightSetupDivisorFont = {RGB_CYAN,FONT_SMALL,RGB_DARK_GRAY};
FONT BacklightSetupScreenFont = {RGB_CYAN,FONT_SMALL,RGB_DARK_BLUE};
FONT BacklightSetupShowerFont = {RGB_BLUE,FONT_SMALL,RGB_LIGHT_GRAY};
FONT BacklightSetupChngFont = {RGB_RED,FONT_SMALL,RGB_LIGHT_BLUE};

/****************************************************************************
	Definice parametru grafickych objektu

*****************************************************************************/
TScreenObjectParams BacklightSetupParams = {BACKLIGHT_SETUP_DIVISOR_WIDTH,BACKLIGHT_SETUP_DIVISOR_HEIGHT,&BacklightSetupDivisorFont};
TScreenObjectParams BacklightSetupShowFieldParams = {BACKLIGHT_SETUP_SHOW_FIELD_WIDTH,BACKLIGHT_SETUP_SHOW_FIELD_HEIGHT,&BacklightSetupShowerFont};
TScreenObjectParams BacklightSetupShowChngParams = {BACKLIGHT_SETUP_SHOW_FIELD_CHNG_WIDTH,BACKLIGHT_SETUP_SHOW_FIELD_HEIGHT,&BacklightSetupChngFont};

int BacklightSetupResult = -1;												//Vysledek po ukonceni aplikace							


/****************************************************************************
	Postovni schranka aplikace

	Vstup: 
		msg:		zprava pro aplikaci

	Výstup:
		RESULT:		Vysledek operace

*****************************************************************************/
RESULT BSMsgBox(MESSAGE * msg)
{
	POSITION* tmpPosition = 0;
	int tmp = 0;
	switch (msg->msg)
	{
	case RUN:
		DebugOut("BacklightSetup RUN command received.\n");
		if (BacklightSetupInternal.State == BACKLIGHT_SETUP_READY)				//Pokud je aplikace zinicializovana
		{
			BacklightSetupResult = -1;
			BacklightSetupInternal.State = BACKLIGHT_SETUP_RESTART;				//Proved spusteni aplikace
			return PASSED;
		}
		DebugOut("BacklightSetup could not be run.\n");
		return FAILED;
			
		break;
	case INIT:
		if (BacklightSetupInternal.State == BACKLIGHT_SETUP_NOT_INITIALIZED)	//POkud neni zinicializovana
		{
			DebugOut("BacklightSetup INIT command received.\n");
			BacklightSetupInternal.State = BACKLIGHT_SETUP_INITIALIZE;			//Inicializuj
			return PASSED;
		}
		break;
	case GET_STATE:
		return (RESULT)BacklightSetupInternal.State;							//Vraci interni stav aplikace
		break;
	case GET_RESULT:
		return (RESULT)BacklightSetupResult;									//Vraci vysledek aplikace
		break;
	case APP_CLICK:
		BacklightSetupInternal.ClickPosition.isFresh = YES;						//Pokud byl prijat klik od operacniho systemu
		tmpPosition = (POSITION*)msg->data;										//uloz data pro zpracovani
		BacklightSetupInternal.ClickPosition.x = tmpPosition->x;
		BacklightSetupInternal.ClickPosition.y = tmpPosition->y;
		DebugOut("BacklightSetup click received.\n");
		return PASSED;
		break;
	default:
		break;
		
	}
	return FAILED;
}


/****************************************************************************
	Funkce vykresli objekty dle jejich ID.

	Vstup: 
		obj:			instance objektu
		message:		parametr kresleni

	Výstup:
		neni

*****************************************************************************/
void DrawBacklightSetupFields(TScreenObject* obj ,OBJECT_MESSAGE message)
{
	DrawDataButtonSkelet(obj,message);														//Vykresli tvar objektu
	LCD_Goto_XY(obj->x + 40,obj->y + 15);													//Presun na pozici pro tisk
	switch(obj->id)																			//Vypsani patricneho textu do objektu
	{
	case BACKLIGHT_SETUP_TIMEOUT:
		LCD_printf((unsigned char*)int2char(integerDiv(currentBacklight.TimeOut,1000)));
		LCD_printf((unsigned char*)"s");
		break;
	case BACKLIGHT_SETUP_HARD_TIMEOUT:
		LCD_printf((unsigned char*)int2char(integerDiv(currentBacklight.HardTimeOut,1000)));
		LCD_printf((unsigned char*)"s");
		break;
	case BACKLIGHT_SETUP_BRIGHTNESS:
		LCD_Goto_XY(obj->x + 50,obj->y + 15);
		backlightIndex = BACKLIGHT_DAC_STEP_COUNT-integerDiv(currentBacklight.DACMaximum-MAXIMUM_BACKLIGHT_DAC_VALUE,BACKLIGHT_DAC_STEP);
		LCD_printf((unsigned char*)int2char(backlightIndex));
		break;
	}
}

/****************************************************************************
	Odezva ukoncovaciho tlacitka

	Vstup: 
		obj:			instance objektu
		message:		parametr kresleni

	Výstup:
		neni

*****************************************************************************/
void BacklightSetupEndCallback(TScreenObject* obj ,OBJECT_MESSAGE message)
{
	BacklightSetupInternal.State = BACKLIGHT_SETUP_STOP;				//Ukonceni aplikace
}


/****************************************************************************
	Vykresleni tlacitek se sipkami

	Vstup: 
		obj:			instance objektu
		message:		parametr kresleni

	Výstup:
		neni

*****************************************************************************/
void BacklightSetupDrawChng(TScreenObject* obj ,OBJECT_MESSAGE message)
{
	DrawButtonShape(obj,message);								//tvar tlacitka
	switch(obj->id)
	{
	case BACKLIGHT_SETUP_TIMEOUT_DOWN:							//tlacitka snizujici
	case BACKLIGHT_SETUP_HARD_TIMEOUT_DOWN:
	case BACKLIGHT_SETUP_BRIGHTNESS_DOWN:
		LCD_Goto_XY(obj->x+5,obj->y+10);
		LCD_printf((unsigned char*)"<");
		break;
	case BACKLIGHT_SETUP_TIMEOUT_UP:							//tlacitka zvysujici
	case BACKLIGHT_SETUP_HARD_TIMEOUT_UP:
	case BACKLIGHT_SETUP_BRIGHTNESS_UP:
		LCD_Goto_XY(obj->x+obj->params->width-17,obj->y+10);
		LCD_printf((unsigned char*)">");
		break;
	}
}

/****************************************************************************
	Odezva sipkovych tlacitek

	Vstup: 
		obj:			instance objektu
		message:		parametr kresleni

	Výstup:
		neni

*****************************************************************************/
void BacklightSetupSHowChngCallback(TScreenObject* obj ,OBJECT_MESSAGE message)
{
	/****************************************************************************
		Principy jsou stejne pro nastaveni jasu i casu zhasinani, bude proto 
		okomentovan pouze blok nastaveni jasu.

	*****************************************************************************/
	switch(obj->id)												
	{
	case BACKLIGHT_SETUP_BRIGHTNESS_DOWN:																							//Snizeni urovne jasu
	if (backlightIndex > 0)																										//Pokud je jas vetsi nez 0
	{
	backlightIndex--;																											//sniz jas
	BacklightForceValue(BACKLIGHT_DAC_STEP*(BACKLIGHT_DAC_STEP_COUNT-backlightIndex)+MAXIMUM_BACKLIGHT_DAC_VALUE+1);			//Vynut uroven podsvetleni
    
	currentBacklight.DACMaximum = BACKLIGHT_DAC_STEP*(BACKLIGHT_DAC_STEP_COUNT-backlightIndex)+MAXIMUM_BACKLIGHT_DAC_VALUE+1;	//ulozeni hodnoty do pameti
	BacklightSetupScreen.UpdateObject(BACKLIGHT_SETUP_BRIGHTNESS);																//aktualizace objektu
	}
	break;
	case BACKLIGHT_SETUP_BRIGHTNESS_UP:																							//zvyseni jasu																							
	if (backlightIndex < 9)																										//Pokud neni maximalni jas
	{
	backlightIndex++;																											//Zvyseni intenzity
	BacklightForceValue(BACKLIGHT_DAC_STEP*(BACKLIGHT_DAC_STEP_COUNT-backlightIndex)+MAXIMUM_BACKLIGHT_DAC_VALUE+1);			//Vynuceni hodnoty
    
	currentBacklight.DACMaximum = BACKLIGHT_DAC_STEP*(BACKLIGHT_DAC_STEP_COUNT-backlightIndex)+MAXIMUM_BACKLIGHT_DAC_VALUE+1;	//Ulozeni hodnoty
	BacklightSetupScreen.UpdateObject(BACKLIGHT_SETUP_BRIGHTNESS);																//Aktualizace objektu
	}
	break;
	case BACKLIGHT_SETUP_TIMEOUT_DOWN:
		if (currentBacklight.TimeOut > BACKLIGHT_TIMEOUT_MINIMUM)
		{
			currentBacklight.TimeOut -=BACKLIGHT_TIMEOUT_SETP;
			BacklightSetupScreen.UpdateObject(BACKLIGHT_SETUP_TIMEOUT);
		}
		break;
	case BACKLIGHT_SETUP_TIMEOUT_UP:
		if (currentBacklight.TimeOut < BACKLIGHT_TIMEOUT_MAXIMUM)
		{
			currentBacklight.TimeOut +=BACKLIGHT_TIMEOUT_SETP;
			BacklightSetupScreen.UpdateObject(BACKLIGHT_SETUP_TIMEOUT);
		}
		break;

		case BACKLIGHT_SETUP_HARD_TIMEOUT_DOWN:
		if (currentBacklight.HardTimeOut > BACKLIGHT_TIMEOUT_MINIMUM)
		{
			currentBacklight.HardTimeOut -=BACKLIGHT_TIMEOUT_SETP;
			BacklightSetupScreen.UpdateObject(BACKLIGHT_SETUP_HARD_TIMEOUT);
		}
		break;
	case BACKLIGHT_SETUP_HARD_TIMEOUT_UP:
		if (currentBacklight.HardTimeOut < BACKLIGHT_TIMEOUT_MAXIMUM)
		{
			currentBacklight.HardTimeOut +=BACKLIGHT_TIMEOUT_SETP;
			BacklightSetupScreen.UpdateObject(BACKLIGHT_SETUP_HARD_TIMEOUT);
		}
		break;
	}
}

/****************************************************************************
	Funkce inicializuje aplikaci

	Vstup: 
		neni

	Výstup:
		RESULT:			vyledek inicializace

*****************************************************************************/
RESULT BacklightSetupInitialize(void)
{
	BacklightSetupScreen.Init(BACKLIGHT_SETUP_OBJECT_COUNT,BacklightSetupScreenObjects,&BacklightSetupScreenFont, YES);										//inicializace obrazovky
	BacklightSetupInternal.Init(BACKLIGHT_SETUP,BACKLIGHT_SETUP_XA,BACKLIGHT_SETUP_YA,BACKLIGHT_SETUP_XC,BACKLIGHT_SETUP_YC,&BacklightSetupScreen,0,YES);	//Inicializace ridici struktury

	if (BacklightSetupInternal.Screen == 0)
	{
		return FAILED;
	}

	/****************************************************************************
		Inicializace jednotlivych grafickych objektu

	*****************************************************************************/
	BacklightSetupInternal.Screen->objects[BACKLIGHT_SETUP_DIVISOR].Init(	BACKLIGHT_SETUP_XA,
																			BACKLIGHT_SETUP_YA,
																			BACKGROUND,
																			BACKLIGHT_SETUP_DIVISOR,
																			STR_DISPLAY_SETUP,
																			OBJECT_ENABLED,
																			&BacklightSetupParams,
																			0,
																			&DrawTextBox);

	BacklightSetupInternal.Screen->objects[BACKLIGHT_SETUP_TIMEOUT].Init(	BACKLIGHT_SETUP_XA+BACKLIGHT_SETUP_DIVISOR_WIDTH/2-BACKLIGHT_SETUP_SHOW_FIELD_WIDTH/2,
																			BACKLIGHT_SETUP_YA+BACKLIGHT_SETUP_SHOW_FIELD_TOP,
																			BACKGROUND,
																			BACKLIGHT_SETUP_TIMEOUT,
																			STR_BACKLIGHT_TIMEOUT,
																			OBJECT_ENABLED,
																			&BacklightSetupShowFieldParams,
																			0,
																			&DrawBacklightSetupFields);

	BacklightSetupInternal.Screen->objects[BACKLIGHT_SETUP_TIMEOUT_DOWN].Init(	BACKLIGHT_SETUP_XA+BACKLIGHT_SETUP_DIVISOR_WIDTH/2-BACKLIGHT_SETUP_SHOW_FIELD_WIDTH/2-BACKLIGHT_SETUP_CHANGE_WIDTH,
																			BACKLIGHT_SETUP_YA+BACKLIGHT_SETUP_SHOW_FIELD_TOP,
																			BUTTON,
																			BACKLIGHT_SETUP_TIMEOUT_DOWN,
																			0,
																			OBJECT_ENABLED,
																			&BacklightSetupShowChngParams,
																			&BacklightSetupSHowChngCallback,
																			&BacklightSetupDrawChng);

	BacklightSetupInternal.Screen->objects[BACKLIGHT_SETUP_TIMEOUT_UP].Init(	BACKLIGHT_SETUP_XA+BACKLIGHT_SETUP_DIVISOR_WIDTH/2+BACKLIGHT_SETUP_SHOW_FIELD_WIDTH/2-( BACKLIGHT_SETUP_SHOW_FIELD_CHNG_WIDTH-BACKLIGHT_SETUP_CHANGE_WIDTH),
																			BACKLIGHT_SETUP_YA+BACKLIGHT_SETUP_SHOW_FIELD_TOP,
																			BUTTON,
																			BACKLIGHT_SETUP_TIMEOUT_UP,
																			0,
																			OBJECT_ENABLED,
																			&BacklightSetupShowChngParams,
																			&BacklightSetupSHowChngCallback,
																			&BacklightSetupDrawChng);

	BacklightSetupInternal.Screen->objects[BACKLIGHT_SETUP_HARD_TIMEOUT].Init(	BACKLIGHT_SETUP_XA+BACKLIGHT_SETUP_DIVISOR_WIDTH/2-BACKLIGHT_SETUP_SHOW_FIELD_WIDTH/2,
																			BACKLIGHT_SETUP_YA+BACKLIGHT_SETUP_SHOW_FIELD_TOP+BACKLIGHT_SETUP_SHOW_FIELD_HEIGHT+BACKLIGHT_SETUP_SHOW_FIELD_DISTANCE,
																			BACKGROUND,
																			BACKLIGHT_SETUP_HARD_TIMEOUT,
																			STR_BACKLIGHT_HARD_TIMEOUT,
																			OBJECT_ENABLED,
																			&BacklightSetupShowFieldParams,
																			0,
																			&DrawBacklightSetupFields);

	BacklightSetupInternal.Screen->objects[BACKLIGHT_SETUP_HARD_TIMEOUT_DOWN].Init(	BACKLIGHT_SETUP_XA+BACKLIGHT_SETUP_DIVISOR_WIDTH/2-BACKLIGHT_SETUP_SHOW_FIELD_WIDTH/2-BACKLIGHT_SETUP_CHANGE_WIDTH,
																			BACKLIGHT_SETUP_YA+BACKLIGHT_SETUP_SHOW_FIELD_TOP+BACKLIGHT_SETUP_SHOW_FIELD_HEIGHT+BACKLIGHT_SETUP_SHOW_FIELD_DISTANCE,
																			BUTTON,
																			BACKLIGHT_SETUP_HARD_TIMEOUT_DOWN,
																			0,
																			OBJECT_ENABLED,
																			&BacklightSetupShowChngParams,
																			&BacklightSetupSHowChngCallback,
																			&BacklightSetupDrawChng);

	BacklightSetupInternal.Screen->objects[BACKLIGHT_SETUP_HARD_TIMEOUT_UP].Init(	BACKLIGHT_SETUP_XA+BACKLIGHT_SETUP_DIVISOR_WIDTH/2+BACKLIGHT_SETUP_SHOW_FIELD_WIDTH/2-( BACKLIGHT_SETUP_SHOW_FIELD_CHNG_WIDTH-BACKLIGHT_SETUP_CHANGE_WIDTH),
																			BACKLIGHT_SETUP_YA+BACKLIGHT_SETUP_SHOW_FIELD_TOP+BACKLIGHT_SETUP_SHOW_FIELD_HEIGHT+BACKLIGHT_SETUP_SHOW_FIELD_DISTANCE,
																			BUTTON,
																			BACKLIGHT_SETUP_HARD_TIMEOUT_UP,
																			0,
																			OBJECT_ENABLED,
																			&BacklightSetupShowChngParams,
																			&BacklightSetupSHowChngCallback,
																			&BacklightSetupDrawChng);

	BacklightSetupInternal.Screen->objects[BACKLIGHT_SETUP_BRIGHTNESS].Init(	BACKLIGHT_SETUP_XA+BACKLIGHT_SETUP_DIVISOR_WIDTH/2-BACKLIGHT_SETUP_SHOW_FIELD_WIDTH/2,
																			BACKLIGHT_SETUP_YA+BACKLIGHT_SETUP_SHOW_FIELD_TOP+2*BACKLIGHT_SETUP_SHOW_FIELD_HEIGHT+2*BACKLIGHT_SETUP_SHOW_FIELD_DISTANCE,
																			BACKGROUND,
																			BACKLIGHT_SETUP_BRIGHTNESS,
																			STR_BACKLIGHT_BRIGHTNESS,
																			OBJECT_ENABLED,
																			&BacklightSetupShowFieldParams,
																			0,
																			&DrawBacklightSetupFields);

	BacklightSetupInternal.Screen->objects[BACKLIGHT_SETUP_BRIGHTNESS_DOWN].Init(	BACKLIGHT_SETUP_XA+BACKLIGHT_SETUP_DIVISOR_WIDTH/2-BACKLIGHT_SETUP_SHOW_FIELD_WIDTH/2-BACKLIGHT_SETUP_CHANGE_WIDTH,
																			BACKLIGHT_SETUP_YA+BACKLIGHT_SETUP_SHOW_FIELD_TOP+2*BACKLIGHT_SETUP_SHOW_FIELD_HEIGHT+2*BACKLIGHT_SETUP_SHOW_FIELD_DISTANCE,
																			BUTTON,
																			BACKLIGHT_SETUP_BRIGHTNESS_DOWN,
																			0,
																			OBJECT_ENABLED,
																			&BacklightSetupShowChngParams,
																			&BacklightSetupSHowChngCallback,
																			&BacklightSetupDrawChng);

	BacklightSetupInternal.Screen->objects[BACKLIGHT_SETUP_BRIGHTNESS_UP].Init(	BACKLIGHT_SETUP_XA+BACKLIGHT_SETUP_DIVISOR_WIDTH/2+BACKLIGHT_SETUP_SHOW_FIELD_WIDTH/2-( BACKLIGHT_SETUP_SHOW_FIELD_CHNG_WIDTH-BACKLIGHT_SETUP_CHANGE_WIDTH),
																			BACKLIGHT_SETUP_YA+BACKLIGHT_SETUP_SHOW_FIELD_TOP+2*BACKLIGHT_SETUP_SHOW_FIELD_HEIGHT+2*BACKLIGHT_SETUP_SHOW_FIELD_DISTANCE,
																			BUTTON,
																			BACKLIGHT_SETUP_BRIGHTNESS_UP,
																			0,
																			OBJECT_ENABLED,
																			&BacklightSetupShowChngParams,
																			&BacklightSetupSHowChngCallback,
																			&BacklightSetupDrawChng);

	BacklightSetupInternal.Screen->objects[BACKLIGHT_SETUP_END].Init(	BACKLIGHT_SETUP_XA+BACKLIGHT_SETUP_DIVISOR_WIDTH/2-PARAMS_BTN_OK.width/2,
																			BACKLIGHT_SETUP_YA+BACKLIGHT_SETUP_SHOW_FIELD_TOP+3*BACKLIGHT_SETUP_SHOW_FIELD_HEIGHT+3*BACKLIGHT_SETUP_SHOW_FIELD_DISTANCE,
																			BUTTON,
																			BACKLIGHT_SETUP_END,
																			STR_OK,
																			OBJECT_ENABLED,
																			&PARAMS_BTN_OK,
																			&BacklightSetupEndCallback,
																			&DrawButton);
	return PASSED;
}

/****************************************************************************
	Ridici stavovy automat aplikace

	Vstup: 
		neni

	Výstup:
		neni

*****************************************************************************/
void AppBacklightSetup(void)
{
	switch (BacklightSetupInternal.State)
	{
	case BACKLIGHT_SETUP_NOT_INITIALIZED:
		break;
	case BACKLIGHT_SETUP_INITIALIZE:
		BacklightSetupInternal.State = BACKLIGHT_SETUP_READY;								//prechod do dalsiho stavu
		if (BacklightSetupInitialize() !=PASSED)											//Pokud se nepodarila inicializace
		{
			DebugOut("BacklightSetup could not be initialized. Falling to error.\n");
			BacklightSetupInternal.State = BACKLIGHT_SETUP_ERROR;							//Selzi
			break;
		}
		DebugOut("BacklightSetup initialized.\n");
		break;
	case BACKLIGHT_SETUP_RESTART:
		BacklightSetupInternal.Startup();													//Startovaci ulohy aplikace
		BacklightSetupInternal.State = BACKLIGHT_SETUP_DRAW;								//prechod do dalsiho stavu
		break;
	case BACKLIGHT_SETUP_DRAW:
		BacklightSetupInternal.Screen->Draw();												//Vykresleni aplikace
		BacklightSetupInternal.State = BACKLIGHT_SETUP_ACTIVE;								//Prechod do aktivniho stavu
		break;
	case BACKLIGHT_SETUP_ACTIVE:
		BacklightSetupInternal.ProceedClick();												//Zpracovani kliknuti
		break;
	case BACKLIGHT_SETUP_WAITING:
		switch(BacklightSetupInternal.TryToResume())										//Cekani na ukonceni aplikace
		{
		case KEYBOARD:
			break;
		case NONE:
			break;
		default:
			DebugOut("Returned to BacklightSetup from unknown application.\n");
			break;
		}
		break;
	case BACKLIGHT_SETUP_READY:
		break;
	case BACKLIGHT_SETUP_STOP:
		BacklightSetupInternal.Stop();														//Ukoncovaci akce
		break;
	case BACKLIGHT_SETUP_ERROR:
		break;
	default:
		break;
	}
}