//----------------------------------------------------
/**
	\file		ctk/inc/wnd.h
	\ingroup	visualization
	\ingroup	all

	\brief		Automat pro rizeni prepinani oken terminalu
				<<< ALL >>>

	\author		ConTeK s.r.o., Petr Cernin
	\version	01.02
	\date		10.08.2006
*/
//----------------------------------------------------


#ifndef _WND_H_
#define _WND_H_

#include <ctktypes.h>
#include <timeticks.h>
#include <display.h>

//! \name Typy udalosti
//@{
#define EVENT_IDLE			0x00	//!< Bez udalosti (necinnost uzivatele)
#define EVENT_ENTER			0x01	//!< Prvni vyvolani okna
#define EVENT_LEAVE			0x02	//!< Opusteni okna
#define EVENT_KEY			0x04	//!< Stisk klavesy
#define EVENT_TIMER			0x08	//!< Vyprseni casovace
//@}

//----------------------------------------------------
/**
	\def EVENT_ENTER

		Tato udalost je generovana pri prvnim zobrazeni okna.
		Pokud bylo okno vyvolane navratem z vnoreneho okna,
		pak parameter udalosti ma hodnotu 1, jinak ma hodnotu 0

		Úkolem obsluhy je vykreslit obsah okna a inicializovat
		dalsi promenne okna. Na zaklade parametru je mozne
		rozhodnout, do jake miry bude inicializace provedena.

	\def EVENT_LEAVE

		Tato udalost je generovana pri opusteni okna, jedna
		se o posledni volani callback funkce okna pred
		prepnutim na jine okno.
		Pokud je prepnuti zpusobene volanim funkce wndCall nebo
		vyvolanim warning okna, pak parametr udalosti ma hodnotu 1,
		jinak ma hodnotu 0

		Úkolem obsluhy teto udalosti je "uklidit". Bezna callback
		funkce tuto udalost neobsluhuje.

	\def EVENT_KEY

		Tato udalost je generovana pri stisku/uvolnenni klavesy
		Parametr udalosti obsahuje kod klavesy

	\def EVENT_TIMER

		Tato udalost je generovana pri vyprseni drive naplanovaneho
		casovace (funkce wndSetTimer) nebo v nasledujicim tiku
		po volani funkce wndTriggerTimer()

	\def EVENT_IDLE

		Tato udalost je generovana v pripade necinnosti. Tj. kdykoli,
		kdyz neni k dispozici jina udalost.
*/
//----------------------------------------------------


//----------------------------------------------------

static const uint8_t WND_MAX_WARNING_COUNT = 4U;	//!< Maximalni pocet warning oken
#define WND_MAX_STACK_DEPTH		12U					//!< Maximalni vnoreni pri volani oken

//!	Typ udalosti okna
typedef uint8_t			wndevent_t;

//!	Typ predavaneho parametru okna
typedef uint8_t			wndinfo_t;

//!	Typ parametru okna ukladaneho v kontextu
typedef uint16_t		wndparam_t;

//----------------------------------------------------
/**
	\typedef	CTKWNDPROC
	\brief		Prototyp callback funkce okna

	\note		Callback funkce okna musi byt definovany nasledovne:
				\code
					void wndProc( uint8_t event, uint8_t param )
				\endcode
				\param	event	urcuje typ udalosti, tzn. obsahuje jednu z konstant EVENT_xxx
				\param	param	obsahuje parametr udalosti
*/
//----------------------------------------------------

typedef void (* ctkWndProc_t) (const wndevent_t _event, const wndinfo_t _param);


//----------------------------------------------------
/**
	\brief	Tabulka popisujici callback funkce jednotlivych oken

	\note	Prvnich n zaznamu tabulky (WND_MAX_WARNING_COUNT) obsahuje
			ukazatele na warning okna. Tj. okna, ktera lze vyvolat
			pomoci funkce wndWarning().

			Okno s indexeme WND_MAX_WARNING_COUNT je zobrazeno
			jako prvni po inicializaci automatu oken
*/
//----------------------------------------------------

typedef struct
{
	uint8_t			Count;			//!< Pocet oken
	ctkWndProc_t 	Callbacks[64];	//!< Ukazatele na funkce oken
} WNDPROCTABLE;



//----------------------------------------------------
//! Externi deklarace tabulky callback funkci oken

extern const WNDPROCTABLE PCONST p_gWND_PROC_TABLE;


//----------------------------------------------------
//! Callback volany po delsi necinnosti uzivalele.

typedef void (* wndIdleProc_t) (void);


//----------------------------------------------------
/**
	\brief	Funkce vraci kontext displaye, na ktery se kresli
*/
//----------------------------------------------------

DISPDESC * wndGetDisp(void);


//----------------------------------------------------
/**
	\brief	Funkce vraci index aktualne zobrazeneho okna
*/
//----------------------------------------------------

uint8_t	wndGetIdx(void);


//----------------------------------------------------
/**
	\brief	Funkce vraci parametr predani oknu pri
			 volani funkci wndCall nebo wndJump

	\note	Tuto funkci lze volat pouze v ramci callback funkce okna
*/
//----------------------------------------------------

wndparam_t wndGetParam(void);


//----------------------------------------------------
/**
	\brief	Funkce prepise parametr predani oknu pri
			 volani funkci wndCall nebo wndJump

	\param	param	Nova hodnota parametru

	\note	Tuto funkci lze volat pouze v ramci callback funkce okna
*/
//----------------------------------------------------

void wndSetParam(const wndparam_t _param);


//------------------------------------------------
/**
	\brief	Funkce pro navrat z vnoreneho okna,
			 ktere bylo drive zavolano funkci wndCall

	\note	Tuto funkci lze volat pouze v ramci callback funkce okna
*/
//------------------------------------------------

void wndReturn(void);

//------------------------------------------------
/**
	\brief	Funkce pro vyvolani jineho okna

	\param	wndIdx	index okna (0..n)
	\param	param	parameter predany oknu

	\note	Tuto funkci lze volat pouze v ramci callback funkce okna
*/
//------------------------------------------------

void wndJump(const uint8_t _wndIdx, const wndparam_t _param);

//------------------------------------------------
/**
	\brief	Funkce pro vyvolani jineho okna.

	\param	wndIdx	index okna (0..n)
	\param	param	parameter predany oknu

	\note	Funkce ulozi na zasobnik cislo a parameter
			 aktualniho okna, navrat je mozny pomoci wndReturn()
	\note	Tuto funkci lze volat pouze v ramci callback funkce okna
*/
//------------------------------------------------

void wndCall(const uint8_t _wndIdx, const wndparam_t _param);


//------------------------------------------------
/**
	\brief	Funkce pro vyvolani warning okna

	\param	wndIdx	index okna (0 .. WND_MAX_WARNING_COUNT - 1)

	\note	Tuto funkci muze volat kdokoli, odkudkoli z aplikace
*/
//------------------------------------------------

void wndWarning(const uint8_t _wndIdx);


//------------------------------------------------
/**
	\brief	Funkce pro naplanovani casovace

	\param	count	pocet tiku (milisekund)

	\note	Po uplynuti zadanehio poctu tiku, bude
			 callback funkce okna zavolana s udalosti EVENT_TIMER
	\note	Tuto funkci lze volat pouze v ramci callback funkce okna
*/
//------------------------------------------------

void wndSetTimer(const ticks_t _time);


//------------------------------------------------
/**
	\brief	Funkce pro nucene vyvolani udalosti EVENT_TIMER

	\note	Tuto funkci lze volat pouze v ramci callback funkce okna
*/
//------------------------------------------------

void wndTriggerTimer(void);

//------------------------------------------------
/**
	\brief	Funkce pro inicializaci automatu wndTick

	\param	disp			Vystupni display
	\param  idleTimeout		Doba necinnosti uzivatele, po ktere je volan callback onIdle
	\param	onIdle			Callback volany po delsi dobe necinnosti uzivatele. Muze byt 0.

	\note	Tuto funkci je nutne zavolat po startu aplikace, pred
			prvnim volanim wndTick
*/
//------------------------------------------------

void wndInit(DISPDESC * const  _disp, const lticks_t _idleTimeout, wndIdleProc_t _onIdle);


//------------------------------------------------
/**
	\brief	Funkce pro provedeni jednoho kroku automatu rizeni oken

	\note	Tuto metodu je potreba periodicky volat
			v ramci hlavniho automatu aplikace
*/
//------------------------------------------------

void wndTick(void);


#endif // _WND_H_
