//----------------------------------------------------
/**
	\file		ctk/inc/display.h
	\ingroup	visualization
	\ingroup	all
	
	\brief		Knihovna ovladani obecneho displaye
				<<< ALL >>>
			
	\author		ConTeK s.r.o., Ing. Pavel Bazika
	\version	01.01
	\date		06.01.2009
*/
//----------------------------------------------------

#ifndef _DISPLAY_H_
#define _DISPLAY_H_

#include <ctktypes.h>
#include <sync.h>

#include <string.h>

struct _DISPDESC;

//----------------------------------------------------
/**
	 \brief	Metoda vykresleni videopameti na display
*/
//----------------------------------------------------

typedef void (*dmDispRefresh) ( struct _DISPDESC * disp, bool_t force );


//----------------------------------------------------
//! Deskriptor displaye

typedef struct _DISPDESC
{
	uint8_t *	Buffer;			//!< Videopamet
	dmDispRefresh	Refresh;	//!< Metoda obnoveni videopameti
	bool_t		Changed;		//!< Priznak zmeny obsahu videopameti
	bool_t		Inverted;		//!< Invertovane barvy obrazu
	uint8_t		Width;			//!< Viditelna sirka v pixelech
	uint8_t		Height;			//!< Viditelna vyska v pixelech
	uint8_t		ScanLine;		//!< Viditelna sirka v bytech
	uint8_t		FullLine;		//!< Delka radky v bytech ve videopameti displaye (muze byt cast neviditelna)
	bool_t		Ready;			//!< Priznak, zda lze zapisovat do videopameti
} DISPDESC;


//----------------------------------------------------
/**
	\brief	Funkce nastavuje priznak zmeny obsahu displaye

	\param	disp	Kontext displaye
*/
//----------------------------------------------------

static inline void dispChanged(DISPDESC * const disp)
{
	disp->Changed = TRUE;
}


//----------------------------------------------------
/**
	\brief	Funkce pro vynulovani vyrovnavaci pameti displeje

	\param	disp	Kontext displaye
*/
//----------------------------------------------------

static inline void dispClear(DISPDESC * const disp)
{
	memset( disp->Buffer, 0x00, disp->ScanLine * disp->Height);
	dispChanged(disp);
}


//----------------------------------------------------
/**
	\brief	Funkce nastavuje ci rusi barevnou inverzi obrazu

	\param	disp	Kontext displaye
	\param	invert	Stav inverze
*/
//----------------------------------------------------

static inline void dispInvert(DISPDESC * const disp, const bool_t invert)
{
	disp->Inverted = invert;
	dispChanged(disp);
}


//----------------------------------------------------
/**
	\brief	Funkce zjistuje, zda lze zapisovat do videopameti displeje
			Pokud ano, rezervuje display

	\param	disp	Kontext displaye
*/
//----------------------------------------------------

static inline bool_t dispGet(DISPDESC * const disp)
{
	flock_t lock = FastLock();
	bool_t res = disp->Ready;
	if (res)
	{
		disp->Ready = FALSE;
	}

	FastUnlock(lock);
	return res;
}


//----------------------------------------------------
/**
	\brief	Funkce zjistuje, zda lze zapisovat do videopameti displeje
			Pokud ano, rezervuje display

	\param	disp	Kontext displaye
*/
//----------------------------------------------------

static inline void dispPut(DISPDESC * const disp)
{
	AtomWrite(disp->Ready, TRUE);
}


#endif //_DISPLAY_H_
