/****************************************************************************
	Aplikace pro nastaveni data a casu

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

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


TScreen TimeSetupScreen;												//obrazovka aplikace
TScreenObject timeSetupScreenObjects[TIME_SETUP_OBJECT_COUNT];			//Objekty obrazovky aplikace

TApplicationInternal TimeSetupInternal;									//Ridici objekt aplikace

/****************************************************************************
	Globalni definice fontu aplikace

*****************************************************************************/
FONT timeSetupDivisorFont = {RGB_CYAN,FONT_SMALL,RGB_DARK_GRAY};
FONT timeSetupShowerFont = {RGB_BLUE,FONT_SMALL,RGB_LIGHT_GRAY};
FONT timeSetupChngFont = {RGB_RED,FONT_SMALL,RGB_LIGHT_BLUE};

FONT TimeSetupScreenFont = {RGB_CYAN,FONT_SMALL,RGB_LIGHT_BLUE};

/****************************************************************************
	Globalni definice parametru objektu obrazu

*****************************************************************************/
TScreenObjectParams timeSetupDivisorParams = {TIME_SETUP_DIVISOR_WIDTH,TIME_SETUP_DIVISOR_HEIGHT,&timeSetupDivisorFont};
TScreenObjectParams timeSetupShowFieldParams = {TIME_SETUP_SHOW_FIELD_WIDTH,TIME_SETUP_SHOW_FIELD_HEIGHT,&timeSetupShowerFont};
TScreenObjectParams timeSetupShowChngParams = {TIME_SETUP_SHOW_FIELD_WIDTH,TIME_SETUP_SHOW_FIELD_HEIGHT,&timeSetupChngFont};


ANSWER unsavedChanges = NO;											//flag jestli existuji neulozene zmeny

const int MonthMaxDays[12] = {31,28,31,30,31,30,31,31,30,31,30,31};	//pole poctu dni v tydnu

TIME tmpTime;														//pracovni struktura s casem

/****************************************************************************
	Aktualizuje cas zarizeni v docasne struktury

	Vstup: 
		neni

	Vystup
		neni

*****************************************************************************/
void updateTime(void)
{
	tmpTime.hours = currentTime.hours;
	tmpTime.minutes = currentTime.minutes;
	tmpTime.month = currentTime.month;
	tmpTime.day = currentTime.day;
	tmpTime.year = currentTime.year;
}

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

	Vstup: 
		msg:			obsah zpravy pro aplikaci

	Vystup
		RESULT:			vysledek operace

*****************************************************************************/
RESULT TSMsgBox(MESSAGE * msg)
{
	POSITION* tmpPosition = 0;
	int tmp = 0;
	switch (msg->msg)
	{
	case RUN:
		DebugOut("TimeSetup RUN command received.\n");
		if (TimeSetupInternal.State == TIME_SETUP_READY)			//Pokud je uloha zinicializovana
		{
			TimeSetupInternal.State = TIME_SETUP_RESTART;			//Priprav aplikaci pro spusteni
			unsavedChanges = NO;									//zadne zmeny neexistuji
			updateTime();											//Aktualizuj cas pro potreby aplikace
			return PASSED;											//Operace uspesne dokoncena
		}
		DebugOut("TimeSetup could not be run.\n");
		return FAILED;
			
		break;
	case INIT:
		if (TimeSetupInternal.State == TIME_SETUP_NOT_INITIALIZED)	//pokud neni aplikace inicializovana
		{
			DebugOut("TimeSetup INIT command received.\n");
			TimeSetupInternal.State = TIME_SETUP_INITIALIZE;		//Priprav ji na inicializaci
			return PASSED;											//Uspech		
		}
		break;
	case GET_STATE:
		return (RESULT)TimeSetupInternal.State;						//Vraci aktualni stav aplikace
		break;
	case GET_RESULT:
		return (RESULT)UNDF;										//Neni co vracet... aplespon zatim
		break;
	case APP_CLICK:
		TimeSetupInternal.ClickPosition.isFresh = YES;				//Aplikace prijima kliknuti
		tmpPosition = (POSITION*)msg->data;							//predani pozice kliknuti
		TimeSetupInternal.ClickPosition.x = tmpPosition->x;			
		TimeSetupInternal.ClickPosition.y = tmpPosition->y;
		DebugOut("TimeSetup click received.\n");
		return PASSED;												//uspech
		break;
	default:
		break;
		
	}
	return FAILED;
}

/****************************************************************************
	Funkce pro vykresleni nekolika objektu v obrazovce:
		TIME_SETUP_SHOW_TIME_HOURS,
		TIME_SETUP_SHOW_TIME_MINUTES,
		TIME_SETUP_SHOW_DATE_DAYS,
		TIME_SETUP_SHOW_DATE_MONTHS,
		TIME_SETUP_SHOW_DATE_YEARS

	Vstup: 
		obj:		instance objektu ktera vola callback
		message:	parametry kresleni

	Vystup
		neni

*****************************************************************************/
void DrawTimeSetupShowField(TScreenObject* obj ,OBJECT_MESSAGE message)
{
	DrawDataButtonSkelet(obj,message);							//vykresli tvar objektu
	LCD_Goto_XY(obj->x+15, obj->y+15);							//prejde se na pozici pro tisk
	switch(obj->id)												//podle ID objektu je vytisknut patricny obsah
	{
	case TIME_SETUP_SHOW_TIME_HOURS:
		if (tmpTime.hours < 10)
			LCD_printf((unsigned char*)"0");
		LCD_printf((unsigned char*)int2char(tmpTime.hours));
		break;
	case TIME_SETUP_SHOW_TIME_MINUTES:
		if (tmpTime.minutes < 10)
			LCD_printf((unsigned char*)"0");
		LCD_printf((unsigned char*)int2char(tmpTime.minutes));
		break;
	case TIME_SETUP_SHOW_DATE_DAYS:
		if (tmpTime.day < 10)
			LCD_printf((unsigned char*)"0");
		LCD_printf((unsigned char*)int2char(tmpTime.day));
		break;
	case TIME_SETUP_SHOW_DATE_MONTHS:
		if (tmpTime.month < 10)
			LCD_printf((unsigned char*)"0");
		LCD_printf((unsigned char*)int2char(tmpTime.month));
		break;
	case TIME_SETUP_SHOW_DATE_YEARS:
		LCD_Goto_XY(obj->x+6, obj->y+15);
		LCD_printf((unsigned char*)int2char(tmpTime.year));
		break;
	}
}

/****************************************************************************
	Funkce pro vykresleni nekolika objektu v obrazovce:
		TIME_SETUP_XXXX_DOWN,
		TIME_SETUP_XXXX_UP

	Vstup: 
		obj:		instance objektu ktera vola callback
		message:	parametry kresleni

	Vystup
		neni

*****************************************************************************/
void DrawAdjustButton(TScreenObject* obj ,OBJECT_MESSAGE message)
{
	DrawButtonShape(obj,message);				//Vykresleni tvaru
	LCD_Set_Font(obj->params->font);			//nastaveni fontu
	
	switch(obj->id)								//vypsani obsahu podle ID tlacitka
	{
	case TIME_SETUP_HOURS_DOWN:
	case TIME_SETUP_MINUTES_DOWN:
	case TIME_SETUP_DAYS_DOWN:
	case TIME_SETUP_MONTHS_DOWN:
	case TIME_SETUP_YEARS_DOWN:
		LCD_Goto_XY(obj->x+10,obj->y+10);
		LCD_printf((unsigned char *)"<");
	break;
	default:
		LCD_Goto_XY(obj->x+40,obj->y+10);
		LCD_printf((unsigned char *)">");

	}
}

/****************************************************************************
	Odezva tlacitek se sipkami
		TIME_SETUP_XXXX_DOWN,
		TIME_SETUP_XXXX_UP

	Vstup: 
		obj:		instance objektu ktera vola callback
		message:	parametry volani

	Vystup
		neni

*****************************************************************************/
void TimeSetupChangeValueCallback(TScreenObject* obj ,OBJECT_MESSAGE message)
{
	unsavedChanges = YES;														//Jsou provadeny zmeny
	switch(obj->id)																//Rozhodnuti o typu objektu
	{
	case TIME_SETUP_HOURS_UP:
		if (tmpTime.hours >= 23)												//POkud preteklo pocitadlo hodin
			tmpTime.hours = 0;													//vynuluj
		else
			tmpTime.hours++;													//jinak pricti 1
		TimeSetupInternal.Screen->UpdateObject(TIME_SETUP_SHOW_TIME_HOURS);		//prekresli objekt
		break;
	case TIME_SETUP_HOURS_DOWN:											
		if (tmpTime.hours <= 0)													//Pokud podteklo pocitadlo hodin
			tmpTime.hours = 23;													//nastav maximalni hodinu
		else
			tmpTime.hours--;													//jinak dekrementuj
		TimeSetupInternal.Screen->UpdateObject(TIME_SETUP_SHOW_TIME_HOURS);		//Prekresli objekt
		break;
	case TIME_SETUP_MINUTES_DOWN:											
		if (tmpTime.minutes <= 0)												//Pokud podteklo pocitadlo minut
			tmpTime.minutes = 59;												//minuty nastav na 59
		else
			tmpTime.minutes--;													//dekrementuj minuty
		TimeSetupInternal.Screen->UpdateObject(TIME_SETUP_SHOW_TIME_MINUTES);	//aktualizuj objekt
		break;
	case TIME_SETUP_MINUTES_UP:
		if (tmpTime.minutes >= 59)												//pokud pretekly minuty
			tmpTime.minutes = 0;												//vynuluj
		else
			tmpTime.minutes++;													//jinak inkrementuj
		TimeSetupInternal.Screen->UpdateObject(TIME_SETUP_SHOW_TIME_MINUTES);	//aktualizuj objekt
		break;
	case TIME_SETUP_YEARS_UP:
		if (tmpTime.year >= 2100)												//Pokud preteklo pocitadlo let (asi to nepojede v roce 2100...)
			tmpTime.year = 2007;												//nastav rok na minimum
		else
			tmpTime.year++;														//jinak inkrementuj
		TimeSetupInternal.Screen->UpdateObject(TIME_SETUP_SHOW_DATE_YEARS);
		break;
	case TIME_SETUP_YEARS_DOWN:
		if (tmpTime.year <=2007)												//POkud podteklo pocitadlo let
			tmpTime.year = 2100;												//nastav max. hodnotu
		else
			tmpTime.year--;														//jinak dekrementuj
		TimeSetupInternal.Screen->UpdateObject(TIME_SETUP_SHOW_DATE_YEARS);		//aktualizuj objekt
		break;
	case TIME_SETUP_MONTHS_UP:
		if (tmpTime.month >= 12)												//Pokud preteklo pocitadlo
			tmpTime.month = 1;													//nastav minimalni hodnotu
		else
			tmpTime.month++;													//inkrementuj mesice
		TimeSetupInternal.Screen->UpdateObject(TIME_SETUP_SHOW_DATE_MONTHS);	//aktualizuj objekt
		break;
	case TIME_SETUP_MONTHS_DOWN:
		if (tmpTime.month <=1)													//Pokud podteklo pocitadlo
			tmpTime.month = 12;													//nastav maximalni hodnotu
		else
			tmpTime.month--;													//dekrementuj mesice
		TimeSetupInternal.Screen->UpdateObject(TIME_SETUP_SHOW_DATE_MONTHS);	//aktualizuj objekt
		break;
	case TIME_SETUP_DAYS_UP:
		//nastaveni maximalniho poctu dni v zavislosti na mesici
		if ((tmpTime.day >= MonthMaxDays[tmpTime.month-1] && tmpTime.month!=2) || (tmpTime.day >= MonthMaxDays[tmpTime.month-1] + 1 && tmpTime.month == 2 && tmpTime.year%4 == 0) || (tmpTime.day >= MonthMaxDays[tmpTime.month-1] && tmpTime.month == 2 && tmpTime.year%4 != 0) )
			tmpTime.day = 1;	//nastaveni minimalni hodnoty
		else
			tmpTime.day++;		//inkrementuj
		TimeSetupInternal.Screen->UpdateObject(TIME_SETUP_SHOW_DATE_DAYS);		//aktualizuj objekt
		break;
	case TIME_SETUP_DAYS_DOWN:
		if (tmpTime.day <=1)													//pokud je pocet dni mensi nez 1
		{
			if (tmpTime.month != 2)												//pokud neni unor
				tmpTime.day = MonthMaxDays[tmpTime.month-1];					//vezmeme pocet dni z pole mesicu
			else if (tmpTime.month == 2 && tmpTime.year%4 == 0)					//jinak pokud je prestupny rok
				tmpTime.day = 29;												//mame 29 dni
			else
				tmpTime.day = 28;												//jinak mame 28 dni
		}
		else
			tmpTime.day--;														//jinak dekrementuj dny
		TimeSetupInternal.Screen->UpdateObject(TIME_SETUP_SHOW_DATE_DAYS);		//aktualizuj objekt
		break;
	}
	if (MonthMaxDays[tmpTime.month-1] < tmpTime.day && tmpTime.month !=2)		//kontrola jestli nebylo nastavenim let a mesicu dosazeno neexistujiciho data
	{
		tmpTime.day = MonthMaxDays[tmpTime.month-1];		
		TimeSetupInternal.Screen->UpdateObject(TIME_SETUP_SHOW_DATE_DAYS);
	}
	else if (MonthMaxDays[tmpTime.month-1] < tmpTime.day && tmpTime.month ==2 && tmpTime.year%4 != 0)
	{
		tmpTime.day = MonthMaxDays[tmpTime.month-1];
		TimeSetupInternal.Screen->UpdateObject(TIME_SETUP_SHOW_DATE_DAYS);
	}
	else if (MonthMaxDays[tmpTime.month-1]+1 < tmpTime.day && tmpTime.month ==2 && tmpTime.year%4 == 0)
	{
		tmpTime.day = MonthMaxDays[tmpTime.month-1];
		TimeSetupInternal.Screen->UpdateObject(TIME_SETUP_SHOW_DATE_DAYS);
	}
}

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

	Vstup: 
		obj:		instance objektu ktera vola callback
		message:	parametry volani

	Vystup
		neni

*****************************************************************************/
void timeSetupExitCallback(TScreenObject* obj ,OBJECT_MESSAGE message)
{
	if (unsavedChanges == YES)																		//pokud jsou zmeny neulozene
	{
		TDialogCfg cfg = {QUESTION,COUNTDOWN_NONE,100,(unsigned char*)STR_END_UNSAVED_CHANGES,30};	//konfiguruj dialog
		MESSAGE dialogMessage = {CONFIG,&cfg};														//sestav konfiguraci dialogu
		SendTaskMessage(DIALOG,&dialogMessage);														//posli dialogu konfiguraci
		TimeSetupInternal.RunApplication(DIALOG);													//spust dialog
	}
	else
		TimeSetupInternal.State = TIME_SETUP_STOP;													//jinak ukonci lokalni aplikaci
}

/****************************************************************************
	Odezva ukladaciho tlacitka

	Vstup: 
		obj:		instance objektu ktera vola callback
		message:	parametry volani

	Vystup
		neni

*****************************************************************************/
void timeSetupSaveCallback(TScreenObject* obj ,OBJECT_MESSAGE message)
{
	if (unsavedChanges == NO)								//pokud nejsou neulozene zmeny
		return;												//konec
	unsavedChanges = NO;									//zmeny jsou ulozeny
	currentTime.day = tmpTime.day;
	currentTime.month = tmpTime.month;
	currentTime.year = tmpTime.year;
	currentTime.minutes = tmpTime.minutes;
	currentTime.hours = tmpTime.hours;
	currentTime.seconds = tmpTime.seconds;
	SendTaskMessage(STATUS_BAR,&DEFAULT_MSG_REFRESH);		//Aktualizuj stavovy panel



}

/****************************************************************************
	Funkce pro inicializaci aplikace

	Vstup: 
		neni

	Vystup
		neni

*****************************************************************************/
RESULT timeSetupInitialize(void)
{
	TimeSetupScreen.Init(TIME_SETUP_OBJECT_COUNT,	timeSetupScreenObjects,&TimeSetupScreenFont, YES);					//Inicializace obrazovky
	TimeSetupInternal.Init(TIME_SETUP,TIME_SETUP_XA,TIME_SETUP_YA,TIME_SETUP_XC,TIME_SETUP_YC,&TimeSetupScreen,0,YES);	//Inicializace ridici struktury

	if (TimeSetupInternal.Screen == 0)																					//Pokud neni obrazovka platna
	{	
		return FAILED;																									//selhani aplikace
	}
	/****************************************************************************
		Definice objektu...

	*****************************************************************************/
	TimeSetupInternal.Screen->objects[TIME_SETUP_TIME_BG].Init(	TIME_SETUP_DIVISOR_LEFT,
																TIME_SETUP_DIVISOR_TOP,
																BACKGROUND,
																TIME_SETUP_TIME_BG,
																STR_TIME_SETUP,
																OBJECT_ENABLED,
																&timeSetupDivisorParams,
																0,
																&DrawTextBox);

	TimeSetupInternal.Screen->objects[TIME_SETUP_DATE_BG].Init(	TIME_SETUP_DIVISOR_LEFT,
																TIME_SETUP_DIVISOR_TOP+TIME_SETUP_DIVISOR_HEIGHT+25,
																BACKGROUND,
																TIME_SETUP_DATE_BG,
																STR_DATE_SETUP,
																OBJECT_ENABLED,
																&timeSetupDivisorParams,
																0,
																&DrawTextBox);

	TimeSetupInternal.Screen->objects[TIME_SETUP_SHOW_TIME_HOURS].Init(	TIME_SETUP_DIVISOR_LEFT+TIME_SETUP_DIVISOR_WIDTH/6-TIME_SETUP_SHOW_FIELD_WIDTH/2,
																	TIME_SETUP_DIVISOR_TOP+TIME_SETUP_SHOW_FIELD_TOP,
																	BUTTON,
																	TIME_SETUP_SHOW_TIME_HOURS,
																	STR_HOURS,
																	OBJECT_ENABLED,
																	&timeSetupShowFieldParams,
																	0,
																	&DrawTimeSetupShowField);

	TimeSetupInternal.Screen->objects[TIME_SETUP_HOURS_DOWN].Init(	TIME_SETUP_DIVISOR_LEFT+TIME_SETUP_DIVISOR_WIDTH/6-TIME_SETUP_SHOW_FIELD_WIDTH,
																	TIME_SETUP_DIVISOR_TOP+TIME_SETUP_SHOW_FIELD_TOP,
																	BUTTON,
																	TIME_SETUP_HOURS_DOWN,
																	STR_TIME_SETUP,
																	OBJECT_ENABLED,
																	&timeSetupShowChngParams,
																	&TimeSetupChangeValueCallback,
																	&DrawAdjustButton);

	TimeSetupInternal.Screen->objects[TIME_SETUP_HOURS_UP].Init(	TIME_SETUP_DIVISOR_LEFT+TIME_SETUP_DIVISOR_WIDTH/6,
																	TIME_SETUP_DIVISOR_TOP+TIME_SETUP_SHOW_FIELD_TOP,
																	BUTTON,
																	TIME_SETUP_HOURS_UP,
																	STR_TIME_SETUP,
																	OBJECT_ENABLED,
																	&timeSetupShowChngParams,
																	&TimeSetupChangeValueCallback,
																	&DrawAdjustButton);

	TimeSetupInternal.Screen->objects[TIME_SETUP_SHOW_TIME_MINUTES].Init(	TIME_SETUP_DIVISOR_LEFT+3*TIME_SETUP_DIVISOR_WIDTH/6-TIME_SETUP_SHOW_FIELD_WIDTH/2,
																	TIME_SETUP_DIVISOR_TOP+TIME_SETUP_SHOW_FIELD_TOP,
																	BUTTON,
																	TIME_SETUP_SHOW_TIME_MINUTES,
																	STR_MINUTES,
																	OBJECT_ENABLED,
																	&timeSetupShowFieldParams,
																	0,
																	&DrawTimeSetupShowField);

	TimeSetupInternal.Screen->objects[TIME_SETUP_MINUTES_DOWN].Init(		TIME_SETUP_DIVISOR_LEFT+3*TIME_SETUP_DIVISOR_WIDTH/6-TIME_SETUP_SHOW_FIELD_WIDTH,
																	TIME_SETUP_DIVISOR_TOP+TIME_SETUP_SHOW_FIELD_TOP,
																	BUTTON,
																	TIME_SETUP_MINUTES_DOWN,
																	STR_TIME_SETUP,
																	OBJECT_ENABLED,
																	&timeSetupShowChngParams,
																	&TimeSetupChangeValueCallback,
																	&DrawAdjustButton);

	TimeSetupInternal.Screen->objects[TIME_SETUP_MINUTES_UP].Init(	TIME_SETUP_DIVISOR_LEFT+3*TIME_SETUP_DIVISOR_WIDTH/6,
																	TIME_SETUP_DIVISOR_TOP+TIME_SETUP_SHOW_FIELD_TOP,
																	BUTTON,
																	TIME_SETUP_MINUTES_UP,
																	STR_TIME_SETUP,
																	OBJECT_ENABLED,
																	&timeSetupShowChngParams,
																	&TimeSetupChangeValueCallback,
																	&DrawAdjustButton);

	TimeSetupInternal.Screen->objects[TIME_SETUP_SHOW_DATE_DAYS].Init(	TIME_SETUP_DIVISOR_LEFT+TIME_SETUP_DIVISOR_WIDTH/6-TIME_SETUP_SHOW_FIELD_WIDTH/2,
																	TIME_SETUP_DIVISOR_TOP+TIME_SETUP_SHOW_FIELD_TOP+TIME_SETUP_DIVISOR_HEIGHT+25,
																	BUTTON,
																	TIME_SETUP_SHOW_DATE_DAYS,
																	STR_DAY,
																	OBJECT_ENABLED,
																	&timeSetupShowFieldParams,
																	0,
																	&DrawTimeSetupShowField);

		TimeSetupInternal.Screen->objects[TIME_SETUP_DAYS_DOWN].Init(	TIME_SETUP_DIVISOR_LEFT+TIME_SETUP_DIVISOR_WIDTH/6-TIME_SETUP_SHOW_FIELD_WIDTH,
																	TIME_SETUP_DIVISOR_TOP+TIME_SETUP_SHOW_FIELD_TOP+TIME_SETUP_DIVISOR_HEIGHT+25,
																	BUTTON,
																	TIME_SETUP_DAYS_DOWN,
																	STR_TIME_SETUP,
																	OBJECT_ENABLED,
																	&timeSetupShowChngParams,
																	&TimeSetupChangeValueCallback,
																	&DrawAdjustButton);

	TimeSetupInternal.Screen->objects[TIME_SETUP_DAYS_UP].Init(	TIME_SETUP_DIVISOR_LEFT+TIME_SETUP_SHOW_FIELD_LEFT+45,
																	TIME_SETUP_DIVISOR_TOP+TIME_SETUP_SHOW_FIELD_TOP+TIME_SETUP_DIVISOR_HEIGHT+25,
																	BUTTON,
																	TIME_SETUP_DAYS_UP,
																	STR_TIME_SETUP,
																	OBJECT_ENABLED,
																	&timeSetupShowChngParams,
																	&TimeSetupChangeValueCallback,
																	&DrawAdjustButton);

	TimeSetupInternal.Screen->objects[TIME_SETUP_SHOW_DATE_MONTHS].Init(	TIME_SETUP_DIVISOR_LEFT+3*TIME_SETUP_DIVISOR_WIDTH/6-TIME_SETUP_SHOW_FIELD_WIDTH/2,
																	TIME_SETUP_DIVISOR_TOP+TIME_SETUP_SHOW_FIELD_TOP+TIME_SETUP_DIVISOR_HEIGHT+25,
																	BUTTON,
																	TIME_SETUP_SHOW_DATE_MONTHS,
																	STR_MONTH,
																	OBJECT_ENABLED,
																	&timeSetupShowFieldParams,
																	0,
																	&DrawTimeSetupShowField);

	TimeSetupInternal.Screen->objects[TIME_SETUP_MONTHS_DOWN].Init(	TIME_SETUP_DIVISOR_LEFT+3*TIME_SETUP_DIVISOR_WIDTH/6-TIME_SETUP_SHOW_FIELD_WIDTH,
																	TIME_SETUP_DIVISOR_TOP+TIME_SETUP_SHOW_FIELD_TOP+TIME_SETUP_DIVISOR_HEIGHT+25,
																	BUTTON,
																	TIME_SETUP_MONTHS_DOWN,
																	STR_TIME_SETUP,
																	OBJECT_ENABLED,
																	&timeSetupShowChngParams,
																	&TimeSetupChangeValueCallback,
																	&DrawAdjustButton);

	TimeSetupInternal.Screen->objects[TIME_SETUP_MONTHS_UP].Init(	TIME_SETUP_DIVISOR_LEFT+3*TIME_SETUP_DIVISOR_WIDTH/6,
																	TIME_SETUP_DIVISOR_TOP+TIME_SETUP_SHOW_FIELD_TOP+TIME_SETUP_DIVISOR_HEIGHT+25,
																	BUTTON,
																	TIME_SETUP_MONTHS_UP,
																	STR_TIME_SETUP,
																	OBJECT_ENABLED,
																	&timeSetupShowChngParams,
																	&TimeSetupChangeValueCallback,
																	&DrawAdjustButton);

	TimeSetupInternal.Screen->objects[TIME_SETUP_SHOW_DATE_YEARS].Init(	TIME_SETUP_DIVISOR_LEFT+5*TIME_SETUP_DIVISOR_WIDTH/6-TIME_SETUP_SHOW_FIELD_WIDTH/2,
																	TIME_SETUP_DIVISOR_TOP+TIME_SETUP_SHOW_FIELD_TOP+TIME_SETUP_DIVISOR_HEIGHT+25,
																	BUTTON,
																	TIME_SETUP_SHOW_DATE_YEARS,
																	STR_YEAR,
																	OBJECT_ENABLED,
																	&timeSetupShowFieldParams,
																	0,
																	&DrawTimeSetupShowField);
	TimeSetupInternal.Screen->objects[TIME_SETUP_YEARS_DOWN].Init(	TIME_SETUP_DIVISOR_LEFT+5*TIME_SETUP_DIVISOR_WIDTH/6-TIME_SETUP_SHOW_FIELD_WIDTH,
																	TIME_SETUP_DIVISOR_TOP+TIME_SETUP_SHOW_FIELD_TOP+TIME_SETUP_DIVISOR_HEIGHT+25,
																	BUTTON,
																	TIME_SETUP_YEARS_DOWN,
																	STR_TIME_SETUP,
																	OBJECT_ENABLED,
																	&timeSetupShowChngParams,
																	&TimeSetupChangeValueCallback,
																	&DrawAdjustButton);

	TimeSetupInternal.Screen->objects[TIME_SETUP_YEARS_UP].Init(	TIME_SETUP_DIVISOR_LEFT+5*TIME_SETUP_DIVISOR_WIDTH/6,
																	TIME_SETUP_DIVISOR_TOP+TIME_SETUP_SHOW_FIELD_TOP+TIME_SETUP_DIVISOR_HEIGHT+25,
																	BUTTON,
																	TIME_SETUP_YEARS_UP,
																	STR_TIME_SETUP,
																	OBJECT_ENABLED,
																	&timeSetupShowChngParams,
																	&TimeSetupChangeValueCallback,
																	&DrawAdjustButton);

	TimeSetupInternal.Screen->objects[TIME_SETUP_EXIT_BUTTON].Init(	TIME_SETUP_DIVISOR_LEFT+TIME_SETUP_DIVISOR_WIDTH-PARAMS_BTN_CANCEL.width,
																	230,
																	BUTTON,
																	TIME_SETUP_EXIT_BUTTON,
																	STR_EXIT,
																	OBJECT_ENABLED,
																	&PARAMS_BTN_CANCEL,
																	&timeSetupExitCallback,
																	&DrawButton);

	TimeSetupInternal.Screen->objects[TIME_SETUP_SAVE_BUTTON].Init(	MAX_X/2-PARAMS_BTN_OK.width/2,
																	230,
																	BUTTON,
																	TIME_SETUP_SAVE_BUTTON,
																	STR_SAVE,
																	OBJECT_ENABLED,
																	&PARAMS_BTN_OK,
																	&timeSetupSaveCallback,
																	&DrawButton);


	TimeSetupInternal.Screen->objects[TIME_SETUP_SYNC_BUTTON].Init(	TIME_SETUP_DIVISOR_LEFT,
																	230,
																	BUTTON,
																	TIME_SETUP_SYNC_BUTTON,
																	(unsigned char*)"SYNC",
																	OBJECT_ENABLED,
																	&PARAMS_BTN_INFO_OK,
																	0,
																	&DrawButton);

	return PASSED;
}


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

	Vstup: 
		neni

	Vystup
		neni

*****************************************************************************/
void AppTimeSetup(void)
{
	switch (TimeSetupInternal.State)												//POdle stavu aplikace
	{
	case TIME_SETUP_NOT_INITIALIZED:
		break;																		//Neinicializovana aplikace
	case TIME_SETUP_INITIALIZE:
		TimeSetupInternal.State = TIME_SETUP_READY;									//aplikace je pripravena
		if (timeSetupInitialize() !=PASSED)											//Pokud selze inicializace
		{
			DebugOut("TimeSetup could not be initialized. Falling to error.\n");
			TimeSetupInternal.State = TIME_SETUP_ERROR;								//prejit do stavu chyby
			break;
		}
		DebugOut("TimeSetup initialized.\n");
		break;
	case TIME_SETUP_RESTART:
		TimeSetupInternal.Startup();												//Provest ulohy nezbytne pro start
		
		
		TimeSetupInternal.State = TIME_SETUP_DRAW;									//Prejit do stavu kresleni
		break;
	case TIME_SETUP_DRAW:
		TimeSetupInternal.Screen->Draw();											//Vykresleni obrazovky
		TimeSetupInternal.State = TIME_SETUP_ACTIVE;								//aplikace je aktivni
		break;
	case TIME_SETUP_ACTIVE:
		TimeSetupInternal.ProceedClick();											//zpracuj kliknuti
		break;
	case TIME_SETUP_WAITING:
		switch(TimeSetupInternal.TryToResume())										//Aplikace ceka na ukonceni jine aplikace
		{
		case KEYBOARD:
			break;																	//Klavesnice... nic
		case DIALOG:
			if ((ANSWER)SendTaskMessage(DIALOG,&DEFAULT_MSG_GET_RESULT)==YES)		//Dialog...
			{

				TimeSetupInternal.State = TIME_SETUP_STOP;							//pokud byla odpoved ano, konci
			}
			break;
		case NONE:
			break;
		default:
			DebugOut("Returned to TimeSetup from unknown application.\n");
			break;
		}
		break;
	case TIME_SETUP_READY:
		break;																		//Aplikace ceka na spusteni
	case TIME_SETUP_STOP:
		TimeSetupInternal.Stop();													//Ulohy nezbytne pro korektni ukonceni
		break;
	case TIME_SETUP_ERROR:
		break;																		//Chyba aplikace
	default:
		break;
	}
}