#ifndef START_MENU_H
#define START_MENU_H
#include <apps.h> 	// Первым! Приложение!
#include <loader.h>
#include <ATI.h>
#include <bmp.h>
#include <paint.h>
#include <u.h>
#include <mem.h>
#include <utilities.h>
#include <func.h>
#include <charset_conv.h>
#include <file.h>
#include <socket.h>
#include <list_ctrl.h>

#include "sockio.h"

#include "../../libuix/include/api.h"
#include "../../libuix/include/cs.h"


#define  ELF_NAME					"DM"
#define  DEBUG_APP_NAME				ELF_NAME
#define  LOG_FILE  					L"file://b/"ELF_NAME".log"

#define  VERSION_NAME				ELF_NAME
#define  VERSION_VER				"v0.1"

#define	DEBUG_DATA

#include <tadbg.h> 	// Отладчик

// ----------------------------------------------------------------------------------------- //

/* Эта структура идентифицирует приложение. Передаётся в любой обработчик событий */
typedef struct
{ 
    APPLICATION_T           apt; /* Должно обязательно присутствовать, причём первым */
	UINT8       			entries_num;		// Кол-во пунктов в меню.
	UINT32                  prev_state; 		// Предидущий стейт, до сворачивания.
	
} APP_ELF_T;

/* Состояния приложения */
typedef enum
{
    APP_STATE_ANY, /* ANY-state всегда первым */
	APP_STATE_INIT, 
	APP_STATE_BACKGROUND, 	// Свернутое состояние.
	APP_STATE_MAIN, 		// Контакт лист.
	APP_STATE_EDIT, 		// Диалог-Редактора
	APP_STATE_DOWNLOAD,
    APP_STATE_MAX /* Для удобства */
} APP_STATES_T;

typedef enum
{
	MAIN,
	EDIT_ITEM,
	EDIT_URL,	 		// URL.
	EDIT_NAME,	 		// имя.
	EDIT_FILE_PATH,	 	// папка файла.	
	ABOUT, 				// О программе...
	EXIT 				// Выход
}STATES_T;

enum HTTP_STATE   // Статус HTTP
{
  HTTP_IDLE,      // Простой
  HTTP_RESOLVE,   // Получение IP
  HTTP_REDIRECT,  // Редирект
  HTTP_HEADER,    // Получение заголовка
  HTTP_STREAM,    // Получение данных
};

enum DOWNLOAD_STATE   // Статус закачки
{
  DOWNLOAD_ERROR,     // Ошибка
  DOWNLOAD_CONNECT,   // Соединение
  DOWNLOAD_GET_INFO,  // Получение заголовка
  DOWNLOAD_DATA,      // Получение файла
  DOWNLOAD_COMPLETE,  // Успешно завершено
  DOWNLOAD_STOPPED    // Остановлено
};


typedef struct
{
	char        	header[512];	// загаловок HTTP-запроса
	
	char        	url[256];
	char 			referer[256];		// Referer
	char        	path[256];
	
	char			host[32];
	int 			port;
	char 			file_name[256];		// Имя файла - если file_name != NULL, то имя указано юзером и его не следует менять
	char 			file_path[256];		// Папка сохранения
	WCHAR			full_file_name[256];// Полное имя файла с путем

	int				download_type;
	int				file_size;			// Полный размер файла
	int				file_loaded_size;	// Размер закачанной части
	FILE_HANDLE_T	file_handle;
  
} DOWNLOAD_T; // настройки

extern LIST		download;
extern UINT8	state, item_select, download_state, http_state;

ldrElf * _start( WCHAR * uri, WCHAR * params );

static UINT32 startApp( EVENT_STACK_T *ev_st,  REG_ID_T reg_id,  UINT32 param2 ); 
static UINT32 destroyApp( EVENT_STACK_T *ev_st,  APPLICATION_T *app ); // Выход
	   UINT32 AppChangeState( APPLICATION_T * app, UINT8 new_state, BOOL force_show );
static UINT32 HandleChangeState( EVENT_STACK_T * ev_st, APPLICATION_T * app );

static UINT32 MainStateEnter( EVENT_STACK_T *ev_st,  APPLICATION_T *app,  ENTER_STATE_TYPE_T type );
static UINT32 EditStateEnter( EVENT_STACK_T *ev_st,  APPLICATION_T *app,  ENTER_STATE_TYPE_T type );
static UINT32 DownloadStateEnter( EVENT_STACK_T *ev_st,  APPLICATION_T *app,  ENTER_STATE_TYPE_T type );

static UINT32 StateExit( EVENT_STACK_T *ev_st,  APPLICATION_T *app,  EXIT_STATE_TYPE_T type );

static UINT32 HandleUITokenGranted( EVENT_STACK_T * ev_st, APPLICATION_T * app );
static UINT32 HandleReqExit( EVENT_STACK_T *ev_st,  APPLICATION_T *app );

static UINT32 HandleNavigate( EVENT_STACK_T * ev_st, APPLICATION_T * app, UINT32 idx );
static UINT32 HandleSelect( EVENT_STACK_T * ev_st, APPLICATION_T * app, UINT32 param );
static UINT32 HandleBack( EVENT_STACK_T * ev_st, APPLICATION_T * app, UINT32 param );
static UINT32 HandleNew( EVENT_STACK_T * ev_st, APPLICATION_T * app, UINT32 param );
static UINT32 HandleDelete( EVENT_STACK_T * ev_st, APPLICATION_T * app, UINT32 param );
static UINT32 HandleHide( EVENT_STACK_T * ev_st, APPLICATION_T * app, UINT32 mode );
static UINT32 HandleExit( EVENT_STACK_T * ev_st, APPLICATION_T * app, UINT32 mode );
static UINT32 HandleStartDownLoad( EVENT_STACK_T * ev_st, APPLICATION_T * app, UINT32 param );
static UINT32 HandlePaste( EVENT_STACK_T * ev_st, APPLICATION_T * app, UINT32 param );

static UINT32 EditDone( EVENT_STACK_T * ev_st, APPLICATION_T * app, UINT32 l );

static void * MainEntryReq( APPLICATION_T * app, UINT32 idx );

static UINT32 HandleTimer( EVENT_STACK_T *ev_st,  APPLICATION_T *app );

static UINT32 ReadSetting( void ); 	// Читаем конфиг
static UINT32 SaveSetting( void ); 	// Сохраняем конфиг

DOWNLOAD_T * ElfGetDItem( UINT8 i );
static UIX_ICON_T ElfGetIcon( UINT8 i );

static int StartDownload( void );
static int URLParse( char * s_url );

int header_process (const char *header, const char *name,
		int (*procfun) (const char *, void *),
		void *arg);
		
int header_strdup (const char *header, void *closure);
int skip_lws (const char *string);
char * strdup (const char *s);

#ifdef	DEBUG
static void	ReportPhoneInfo( void );
#endif	

#endif
