/* ***********************************
 *	Event / Событие
 */


#ifndef SDK_EVENTS_H
#define SDK_EVENTS_H

#include <typedefs.h>
#include <loader.h>

#ifdef __cplusplus
extern "C" {
#endif


// см. EVENT_T и EVENT_DATA_T @apps.h

#define EV_GRANT_TOKEN				30
#define EV_REVOKE_TOKEN				31

#define EV_KEY_PRESS				500 	// key_pressed
#define EV_KEY_RELEASE				501 	// key_pressed

// Возникает при завершении работы диалога
#define EV_DIALOG_DONE				0x201C

// Возникает при нажатии на кнопку "Назад", в CharEditor кнопка "Ok"
#define EV_DONE						0x2020

// CharEditor кнопка "Отмена"
#define EV_CANCEL					0x2008

// Возникает при нажатии джойстика вверх/вниз в списке
#define EV_LIST_NAVIGATE			0x2043 // index

// Возникает при нажатии джойстика в списке или кнопки "Выбор"
#define EV_SELECT					0x2058 // index

// Посылается списками чтобы запросить очередную порцию данных
#define EV_REQUEST_LIST_ITEMS		0x202C // list_items_req
#define UIS_EV_LIST_DATA			0x202C

// Посылается запросами
#define EV_NO						0x2046

// Посылается запросами
#define EV_YES						0x2079

// Приняты данные
#define EV_DATA						0x200F // EVENT_T::attachment

// ?
#define EV_BROWSE					0x2006

// Возникает при изменении пользователем какого-либо поля
#define EV_DATA_CHANGE				0x2011 // index

// Запросить данные
#define EV_REQUEST_DATA				0x202B // data_req

// Сработал таймер
#define EV_TIMER_EXPIRED			0x8205A // (DL_TIMER_DATA_T*)EVENT_T::attachment


/* new events */
#define EV_GAIN_FOCUS				0x14

#define EV_POWER_DOWN				0x11

#define EV_USER_ACTIVITY			0x7EE	// закрытие заставки
#define EV_UIS_ACTIVITY				0x7ED	// перерисовать UIS
// Сперва появляется EV_UIS_ACTIVITY, затем EV_USER_ACTIVITY

#ifdef FTR_L7E
#define EV_CREATE_SHORTCUT			0x20C9	// Зажатие меню
#else
#define EV_CREATE_SHORTCUT			0x20C5	// Зажатие меню
#endif

#define EV_SCREENSAVER_START		0xDFC


#define EV_GREEN_LONG_PRESS			0x205A

#define EV_LIST_ZERO_PRESS			0x203C	// Не работает =(

#define EV_NAV_DOWN					0x208F
#define EV_NAV_UP					0x2090

#define EV_NEXT						0x2071
#define EV_PREV						0x2072

#define EV_PROGRESS_LEFT			0x2055
#define EV_PROGRESS_RIGHT			0x2026



#define FREE_BUF_FLAG_T		UINT8
#define FBF_FREE			100		// ОС должна освободить буффер
#define FBF_LEAVE			101		// Приложение должно следить за освобождением буффера

typedef struct
{
	size_t					bufsize;
	UINT32					index;
	UINT8					unk2;
} REQUEST_DATA_T;

typedef struct
{
	UINT32					ID;		   // ? Идентификатор списка
	UINT32					begin_idx;	// Начальный индекс требуемого списка элементов
	UINT8					count;		// Сколько эдементов списка требуется
} REQUEST_LIST_ITEMS_T;

typedef struct
{	
	UINT32					list_idx;
	UINT32					unk1;
	void *					ptr;
//	void *					func_ptr;
} DATA_CHANGE_DATA_T;

typedef struct
{
	UINT32					id;
	UINT32					status;
	int						hsock;
} SOCK_NOTIFY_T;

/* Структура, отвечающая за данные, передаваемые с событием */
typedef union
{
	UINT8						key_pressed;
	UINT8						val_byte;
	UINT16						val_word;
	UINT32						val_dword;
	void *						val_ptr;
	UINT32						index;
	UINT32						params[16];
	SOCK_NOTIFY_T				socket_notify;
	REQUEST_LIST_ITEMS_T		list_items_req;
	REQUEST_DATA_T				data_req;
	DATA_CHANGE_DATA_T			data_change;

	//ELF parameters
	ELF_PARAMS_T				start_params;
	//padding to real size
	UINT8						pad[0xFB];
} EVENT_DATA_T;

typedef struct
{
	UINT32					data_tag;
	EVENT_DATA_T			data;
} ADD_EVENT_DATA_T;

/* Структура описания события */
typedef struct tagEVENT_T
{
	EVENT_CODE_T			code;
	UINT32					unk1;
	UINT32					ev_port;
	UINT8					unk2;
	BOOL					is_consumed;
	BOOL					is_firstpass;
	UINT8					unk3;			// EV_DONE, =3 если это диалог создал ивент, =2 если юзер нажал красную
	UINT32					unk4;
	UINT32					unk5;
	struct tagEVENT_T *		next;
	UINT32					data_tag;
	EVENT_DATA_T			data;
	BOOL					is_attach;
	UINT16					att_size;
	void *					attachment;
	UINT8					unk6;
} EVENT_T; //size = 296

/* стэк событий */
typedef struct
{
	EVENT_CODE_T			code;
	UINT8					unk1;
	UINT8					unk2;
	EVENT_T					*top;
	void					*unk3;
	UINT8					unk4[6];
	UINT8					unk5;
} EVENT_STACK_T;

// Получить текущий event из списка
EVENT_T* AFW_GetEv( EVENT_STACK_T *		ev_st );

// Функции добавления ивента (в различных вариациях данных для ивента)
UINT32 AFW_AddEvNoD( EVENT_STACK_T *	ev_st,  
					 UINT16				event_code );
// Функции добавления ивента с данными
UINT32 AFW_AddEvEvD( EVENT_STACK_T *	ev_st,
					 UINT16				event_code,
					 ADD_EVENT_DATA_T *	data );
// Функции добавления ивента с аттачем
UINT32 AFW_AddEvAux( EVENT_STACK_T *	ev_st,
					 UINT16				event_code,
					 FREE_BUF_FLAG_T	free_buf,
					 size_t				att_size,
					 void *				attachment );
// Функции добавления ивента с данными и аттачем
UINT32 AFW_AddEvAuxD( EVENT_STACK_T *		ev_st,
					  UINT16				event_code,
					  ADD_EVENT_DATA_T *	data,
					  FREE_BUF_FLAG_T		free_buf,
					  size_t				att_size,
					  void *				attachment );

// Удалет последний ивент из списка
UINT32 APP_ConsumeEv( EVENT_STACK_T * ev_st,  void * app );


// Добавляет ивент EV_LIST_ITEMS (ответ на EV_REQUEST_LIST_ITEMS)
UINT32 APP_UtilAddEvUISListData( EVENT_STACK_T *    ev_st,
								 void *             app,
								 UINT32             param2, // = 0
								 UINT32             begin_index,
								 UINT8              count,
								 FREE_BUF_FLAG_T    free_buf,
								 UINT32             bufsize,
								 void *             buffer );

// Добавляет ивент EV_REQUEST_DATA для поля с нужным индексом
UINT32 APP_UtilAddEvUISGetDataForItem( EVENT_STACK_T *  ev_st,
									   void *           app,
									   UINT32           index ); 

/* Добавляет в стэк событие "изменить содержимое списка" */
UINT32 APP_UtilAddEvUISListChange( EVENT_STACK_T *  ev_st,
								void *		app,
								UINT32		param2, // = 0
								UINT32		pos,
								UINT8		size,
								BOOL		refresh_data,
								UINT8		param6,		  // = 2
								FREE_BUF_FLAG_T  free_buf,
								UINT32		bufsize,
								void *		buffer );

UINT32 AFW_CreateInternalQueuedEvAux( UINT32 ev_id,  FREE_BUF_FLAG_T flags,  size_t att_size,  const void * att_data );

UINT32 AFW_CreateInternalQueuedEvAuxD( UINT32 ev_code, ADD_EVENT_DATA_T * ev_data,
						FREE_BUF_FLAG_T flags, size_t att_size, const void * ev_auxd );

//AFW_TranslateEvEvD



#ifdef __cplusplus
} /* extern "C" */
#endif

#endif // SDK_EVENTS_H
