#include "app.h"
#include "background.h"

AHIBITMAP_T 		*image_icons;

UINT8				state, item_select, download_state, http_state;			
static WCHAR        file_cfg[256]; 			// Jabber.cfg
static UINT16       status;
static char			viewer_content[2048+1]; // Буффер для просмотощика	

LIST 				download;
UIS_DIALOG_T        dialog; 				// Диалог
ldrElf       	 	elf;					// Структура эльфа
DRAWING_BUFFER_T 	bufd = {NULL, 176, 220};// Буфер для рисования, Canvas.
							
/* Название приложения. Длина строки именно такая и никакая иначе */
const char app_name[APP_NAME_LEN] = ELF_NAME; 

/* Обработчики событий для каждого state-а */
/* Обработчики событий для APP_STATE_ANY (используется в любом state) */
static EVENT_HANDLER_ENTRY_T any_state_handlers[] =
{
	{ EV_REVOKE_TOKEN,	  APP_HandleUITokenRevoked },
	{ EV_TIMER_EXPIRED,       		   HandleTimer },
	{ EV_PM_API_EXIT,				 HandleReqExit },	// PM API: cmd EXIT
    { STATE_HANDLERS_END,           		  NULL },
};
static EVENT_HANDLER_ENTRY_T init_state_handlers[] =
{
	{ EV_GRANT_TOKEN,	      HandleUITokenGranted },
	{ STATE_HANDLERS_END,					  NULL }
};

/* Таблица соответствий обработчиков, состояний и функций входа-выхода из состояния.
   Порядок состояний такой же, как в enum-e */
static const STATE_HANDLERS_ENTRY_T state_handling_table[] =
{
    { APP_STATE_ANY,              // State
      NULL,                       // Обработчик входа в state
      NULL,                       // Обработчик выхода из state
      any_state_handlers          // Список обработчиков событий
    },
	{ APP_STATE_INIT,
      NULL,
      NULL,
      init_state_handlers
    },
	{ APP_STATE_BACKGROUND,
      BackgroundStateEnter,
	  BackgroundStateExit,
      background_state_handlers
    },
    { APP_STATE_MAIN,
      MainStateEnter,
      StateExit,
      NULL
    },
	{ APP_STATE_EDIT,
      EditStateEnter,
      StateExit,
      NULL
	},
	{ APP_STATE_DOWNLOAD,
      DownloadStateEnter,
      StateExit,
      NULL
	}
	
};

static const APP_STATE_NAME_TABLE_T state_name_table[] =
{
	{APP_STATE_ANY,			"ANY"},
	{APP_STATE_INIT,		"INIT"},
	{APP_STATE_BACKGROUND,	"BACKGROUND"},
	{APP_STATE_MAIN,		"MAIN"},
	{APP_STATE_EDIT,		"EDIT"},
	{APP_STATE_DOWNLOAD,	"DOWNLOAD"},
	{APP_STATE_MAX,			NULL}
};

/* Это entry для всех эльфов, должна быть объявлена именно так */
/* uri - путь к эльфу (аналогично argv[0]) */
/* params - параметры эльфа (аналогично остальным argv) */
ldrElf * _start( WCHAR * uri, WCHAR * params )
{
    ldrElf *	pelf;
	UINT32		reserve;
	int			i;
	
	dbg("-----------------------------------");
	dbg("_start: Enter");
	
		// ищем запущеный эльф по имени эльфа
	pelf = ldrFindElf(app_name);
	if ( pelf != NULL ) {
		// приложение уже запущено, вызвать запущеное
		ldrSendEvent( pelf->evbase );
		return NULL;
	}
	// база ивентов
	reserve = ldrRequestEventBase();
	// заполняем структуру эльфа
	elf.name = (char *)app_name;
	elf.app = NULL;
	
	// инитим таблицы ивентов
	for ( i=0; i<APP_STATE_MAX; i++ )
		reserve = ldrInitEventHandlersTbl((EVENT_HANDLER_ENTRY_T *)state_handling_table[i].htable, reserve);
	
	i = u_strlen( uri ) - 1;
	while ( i >= 0 && uri[i] != L'/' ) i--;
	i++;
	elf.dir = malloc( i * sizeof(WCHAR) );
	if ( elf.dir )
		u_strncpy( elf.dir, uri, i );
		
	u_mkpath(file_cfg, elf.dir, L"dm.cfg", 0);
	
	elf.evbase = reserve ++;
	
	/* Регистрируем приложение */
	 status = APP_Register( &elf.evbase,            // На какое событие должно запускаться приложение
                           1,                       // Кол-во событий, на которое должно запускаться приложение
                           state_handling_table,    // Таблица состояний
                           APP_STATE_MAX,            // Количество состояний
                           (void*)startApp );   // Функция, вызываемая при запуске
	
	if ( status == RESULT_OK )
		ldrSendEvent( elf.evbase );
	 else {
		cprint(DEBUG_APP_NAME ":\x84 can't register app\n");
		return NULL;
	}

#ifdef DEBUG
	ReportPhoneInfo();
#endif

    return &elf; 
}

/* Функция вызываемая при старте приложения */
UINT32 startApp( EVENT_STACK_T *ev_st,  REG_ID_T reg_id,  UINT32 param2 )
{
	APP_ELF_T *			papp;
	
	if( AFW_InquireRoutingStackByRegId( reg_id ) == RESULT_OK ) {
		appShow( elf.app );
		return RESULT_FAIL;
	}
	
    papp = (APP_ELF_T*)APP_InitAppData((void*)APPHandleEvent, 
                                            sizeof(APP_ELF_T), // Размер структуры приложения
                                            reg_id,
                                            0,
											0,			// history size
											1,			// priority
											AFW_APP_CENTRICITY_SECONDARY,
											AFW_FOCUS,
											AFW_POSITION_TOP );	
	
	if ( !papp )
	{
		dbg("can't init app data");
		ldrUnloadElf();
		return RESULT_FAIL;
	}

	List_Init(&download, DOWNLOAD_T);
	ReadSetting();
	
    status = APP_Start( ev_st,
                        &papp->apt,
                        APP_STATE_INIT, // Начальное состояние
                        state_handling_table,
                        destroyApp,
                        app_name,
                        state_name_table );
	
	// Теперь приложение может обрабатывать события
	if ( status == RESULT_OK ) {
		elf.app = &papp->apt;
	}
    return RESULT_OK;
}


/* Функция выхода из приложения */
UINT32 destroyApp( EVENT_STACK_T *ev_st,  APPLICATION_T *app )
{
	EVENT_T *		event;

	event = AFW_GetEv(ev_st);
	dbgf("destroyApp: Enter, event = 0x%p, code = 0x%X", event, event->code);
	
	if ( event != NULL ) {
		// это нажатие красной кнопки
		appHide(app);
		return RESULT_OK;
	}
	
	if ( state_handling_table[app->state].exit_fn != NULL && app->state != APP_STATE_BACKGROUND )
		(state_handling_table[app->state].exit_fn)(ev_st, app, EXIT_STATE_EXIT);
		
	cprint( ELF_NAME ":\x8E Exit\n" );
	SaveSetting();
	List_Clear(&download);
	
    /* Завершаем работу приложения */
    status = APP_ExitStateAndApp( ev_st, app, 0 );
	
	ldrUnloadElf();
   
    return status;
}

// Изменить стэйт + насильно показать
UINT32 AppChangeState( APPLICATION_T * app, UINT8 new_state, BOOL force_show )
{
	ADD_EVENT_DATA_T	ed;
	UINT32				ev_code;
	
	dbgf("AppChangeState: state = %s / %d",  state_name_table[new_state].name, force_show);
	
	ed.data_tag = 0;
	ed.data.pad[0] = new_state;
	ed.data.pad[1] = force_show;
	
	ev_code = ldrFindEventHandlerTbl(any_state_handlers, HandleChangeState);
	if ( ev_code > 0 )
		return
		AFW_CreateInternalQueuedEvPriv( ev_code, 0,
										app->afw_id,
										0, 0,
										&ed,
										FBF_FREE, 0, NULL, 0 );
	else
		return RESULT_FAIL;
}
UINT32 HandleChangeState( EVENT_STACK_T * ev_st, APPLICATION_T * app )
{
	APP_ELF_T *		papp = (APP_ELF_T *)(app);
	UINT32			status;
	EVENT_T *		event;
	
	status = RESULT_OK;
	event = AFW_GetEv(ev_st);
	dbgf("HandleChangeState: Enter, state = %s / %d", state_name_table[event->data.pad[0]].name, event->data.pad[1]);
	APP_ConsumeEv(ev_st, app);
	if ( app->state == APP_STATE_BACKGROUND && event->data.pad[0] != APP_STATE_BACKGROUND ) {
		// если уже в бэке
		papp->prev_state = event->data.pad[0];
		if ( event->data.pad[1] == TRUE ) {
			// нужно вызвать из бэка
			status = APP_UtilChangeState(papp->prev_state, ev_st, app);
		}
	}
	else if ( event->data.pad[0] == APP_STATE_BACKGROUND ) {
		// отправить в бэк
		if ( app->state != APP_STATE_BACKGROUND ) {
			papp->prev_state = app->state;
			status = APP_UtilChangeState(APP_STATE_BACKGROUND, ev_st, app);
		}
	}
	else {
		// просто изменить стэйт
		status = APP_UtilChangeState(event->data.pad[0], ev_st, app);
	}
	return status;
}
/* Обработчик входа в main state */
UINT32 MainStateEnter( EVENT_STACK_T *ev_st,  APPLICATION_T *app,  ENTER_STATE_TYPE_T type )
{
	APP_ELF_T				*papp = (APP_ELF_T *)(app);
	UIX_CALL_BACK_F 		*CallBackArr[3];
	UINT32					num;
	
	dbg("MainStateEnter: start");
	if(type != ENTER_STATE_ENTER) return UIX_Render( app->dialog );
	
	CallBackArr[0] = (void *)HandleSelect;
	CallBackArr[1] = (void *)HandleBack;
	CallBackArr[2] = (void *)HandleNavigate;

	item_select = 0;
	
	switch (state)
	{
		case MAIN:
			num =  List_GetNum(&download);
			break;
			
		case EDIT_ITEM:
			num = 3;
			break;
		
	}

	app->dialog = UIX_CreateListDialog(app, num, MainEntryReq, CallBackArr);
	
	UIX_DialogSetTitle(app->dialog, "Downloader by R.U.S.H.A.N.", ElfGetIcon(0));
	
	switch (state)
	{
		case MAIN:
		UIX_DialogAddAction(app->dialog, "New item", ( void *)HandleNew, 0 );
		UIX_DialogAddAction(app->dialog, "Delete item", ( void *)HandleDelete, 0 );
		UIX_DialogAddAction(app->dialog, "Hide", (void *)HandleHide, 0);
		UIX_DialogAddAction(app->dialog, "Exit", ( void *)HandleExit, 0 );
		break;
			
		case EDIT_ITEM:
		UIX_DialogAddAction(app->dialog, "Start Download", ( void *)HandleStartDownLoad, 0 );
		UIX_DialogAddAction(app->dialog, "Paste URL from clipboard", ( void *)HandlePaste, 0 );
		break;
	}

	UIX_Render(app->dialog);
	
	dbg("MainStateEnter: end");
	
    return RESULT_OK;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
UINT32 EditStateEnter( EVENT_STACK_T *ev_st,  APPLICATION_T *app,  ENTER_STATE_TYPE_T type )
{
	dbgf("EditStateEnter: start, type = %d, substate = %d", type, state );
	if(type != ENTER_STATE_ENTER) return UIX_Render( app->dialog );
	
	char					buf[64];
	
	switch(state)
	{
		case EDIT_URL:
		app->dialog = UIX_CreateInputDialog(app, 256, ElfGetDItem(item_select)->url, INP_NO_ENDLINE | INP_NO_SPACE | INP_USE_DIGITAL | INP_USE_ENGLISH, ( void *)EditDone );
		UIX_DialogSetTitle(app->dialog, "Enter URL:", ElfGetIcon(0));
        break;
		
		case EDIT_NAME:
		app->dialog = UIX_CreateInputDialog(app, 64, ElfGetDItem(item_select)->file_name, INP_NO_ENDLINE | INP_NO_SPACE | INP_USE_DIGITAL | INP_USE_ENGLISH | INP_USE_OTHERS, ( void *)EditDone );
		UIX_DialogSetTitle(app->dialog, "Enter name:", ElfGetIcon(0));
        break;

		case EDIT_FILE_PATH:
		app->dialog = UIX_CreateInputDialog(app, 256, ElfGetDItem(item_select)->file_path, INP_NO_ENDLINE | INP_NO_SPACE | INP_USE_DIGITAL | INP_USE_ENGLISH | INP_USE_OTHERS, ( void *)EditDone );
		UIX_DialogSetTitle(app->dialog, "Enter file path:", ElfGetIcon(0));
        break;
		
	} 
	UIX_Render(app->dialog);
	   
	return RESULT_OK;
}

UINT32 DownloadStateEnter( EVENT_STACK_T *ev_st,  APPLICATION_T *app,  ENTER_STATE_TYPE_T type )
{
	APP_ELF_T        	    *papp = (APP_ELF_T*)app;
    UIX_CALL_BACK_F 		*CallBackArr[2];
	
	dbgf("DownloadStateEnter: start, type = %d, substate = %d", type, state );
	
	if(type != ENTER_STATE_ENTER) return UIX_Render( app->dialog );
	
	app->dialog = UIX_CreateProgress( app );
	
	UIX_DialogSetTitle(app->dialog, "Starting Download...", ElfGetIcon(0));
	
	StartDownload();
	UIX_Render(app->dialog);

	dbg("DownloadStateEnter: end");
    return RESULT_OK;
}

UINT32 StateExit( EVENT_STACK_T *ev_st,  APPLICATION_T *app,  EXIT_STATE_TYPE_T type )
{
	dialog = app->dialog;
	status = APP_UtilUIXDialogDelete( &app->dialog );

	return status;
}
UINT32 HandleUITokenGranted( EVENT_STACK_T * ev_st, APPLICATION_T * app )
{
	UINT32			status;

	dbg("HandleUITokenGranted: Enter");
	
	// Call standart event handler
	status = APP_HandleUITokenGranted( ev_st, app );
	dbgf("HandleUITokenGranted: APP_HandleUITokenGranted DONE, status = %d", status);
	
	// Application is ready, now change init state to main state with UI
	if( (status == RESULT_OK) && (app->token_status == 2) ) {
		status = APP_UtilChangeState( APP_STATE_MAIN, ev_st, app );
	}

	dbg("HandleUITokenGranted: END");
	return status;
}
UINT32 HandleReqExit( EVENT_STACK_T *ev_st,  APPLICATION_T *app )
{
	dbg("HandleReqExit");
	cprint("\0x82"ELF_NAME": HandleReqExit\n");
	
	APP_ConsumeEv( ev_st, app );
	app->exit_status = TRUE;
	
	return RESULT_OK;
}
UINT32 HandleNavigate( EVENT_STACK_T * ev_st, APPLICATION_T * app, UINT32 idx )
{
	if ( state == MAIN )
		item_select = idx;
		
	return RESULT_OK;
}
UINT32 HandleSelect( EVENT_STACK_T * ev_st, APPLICATION_T * app, UINT32 param )
{	
	
	dbg("HandleSelect");
	APP_ConsumeEv( ev_st, app );
	
	if( state == MAIN ) {
	
		state = EDIT_ITEM;
		return APP_UtilChangeState( APP_STATE_MAIN, ev_st, app );
		
	} else if ( state == EDIT_ITEM ) {
	
		switch (param)
		{
			case 0:
				state = EDIT_URL;
				return APP_UtilChangeState( APP_STATE_EDIT, ev_st, app );
			case 1:
				state = EDIT_NAME;
				return APP_UtilChangeState( APP_STATE_EDIT, ev_st, app );
			case 2:
				state = EDIT_FILE_PATH;
				return APP_UtilChangeState( APP_STATE_EDIT, ev_st, app );
				
		}
	}
	return RESULT_OK;
}

UINT32 HandleBack( EVENT_STACK_T * ev_st, APPLICATION_T * app, UINT32 param )
{
	APP_ConsumeEv( ev_st, app );

	switch (app->state)
    {
		case APP_STATE_MAIN:
			if( state == MAIN ) {
			
				return destroyApp( ev_st, app );
			} else if ( state == EDIT_ITEM ) {
	
				state = MAIN;
				return APP_UtilChangeState( APP_STATE_MAIN, ev_st, app );
			}
		case APP_STATE_DOWNLOAD:
			return APP_UtilChangeState( APP_STATE_MAIN, ev_st, app );
		
	}
	
	return RESULT_OK;
}


UINT32 HandleNew( EVENT_STACK_T * ev_st, APPLICATION_T * app, UINT32 idx )
{
	APP_ELF_T			*papp = (APP_ELF_T*)app;
	DOWNLOAD_T 			d;

	memclr( &d, sizeof(DOWNLOAD_T) );
		
	strcpy( d.url, "http://" );	
	strcpy( d.file_path, "/b/mobile/" );	

	List_AppendItem( &download, &d );
	
	state = MAIN;
	return APP_UtilChangeState( APP_STATE_MAIN, ev_st, app );
}

UINT32 HandleDelete( EVENT_STACK_T * ev_st, APPLICATION_T * app, UINT32 idx )
{
	APP_ELF_T			*papp = (APP_ELF_T*)app;

	List_DeleteItem( &download, item_select );
	
	state = MAIN;
	return APP_UtilChangeState( APP_STATE_MAIN, ev_st, app );
}

UINT32 HandleHide( EVENT_STACK_T * ev_st, APPLICATION_T * app, UINT32 mode )
{	
	if ( mode == ACTION_KEY_RELEASE || mode == ACTION_LIST )
		return appHide(app);
	return RESULT_OK;
}

UINT32 HandleExit( EVENT_STACK_T * ev_st, APPLICATION_T * app, UINT32 mode )
{
	if ( mode == ACTION_KEY_RELEASE || mode == ACTION_LIST )
		return HandleReqExit(ev_st, app);
	return RESULT_OK;
}

UINT32 HandleStartDownLoad( EVENT_STACK_T * ev_st, APPLICATION_T * app, UINT32 param )
{	

	return APP_UtilChangeState( APP_STATE_DOWNLOAD, ev_st, app );
}

UINT32 HandlePaste( EVENT_STACK_T * ev_st, APPLICATION_T * app, UINT32 param )
{

	if( !u_strlen(clipboard) ) return APP_UtilChangeState( APP_STATE_MAIN, ev_st, app );
	
	UCS2toCP1251(clipboard, ElfGetDItem(item_select)->url);

	return APP_UtilChangeState( APP_STATE_MAIN, ev_st, app );
}

UINT32 EditDone( EVENT_STACK_T * ev_st, APPLICATION_T * app, UINT32 l  )
{
	char			*data;
	
	if ( l == (UINT32)(-1) || l == 0 ) {
		// Cancel
		switch(state)
		{
			case EDIT_URL:
			case EDIT_NAME:
			case EDIT_FILE_PATH:		
				return APP_UtilChangeState( APP_STATE_MAIN, ev_st, app );
		
		}
	}
	
	data = malloc( sizeof(char)*(l+1) );
	
	UIX_InputGetData(app->dialog, data, 0);
	
		switch(state)
		{
			case EDIT_URL:
				strcpy( ElfGetDItem(item_select)->url, data );
				return APP_UtilChangeState( APP_STATE_MAIN, ev_st, app );
			case EDIT_NAME:
				strcpy( ElfGetDItem(item_select)->file_name, data );
				return APP_UtilChangeState( APP_STATE_MAIN, ev_st, app );
			case EDIT_FILE_PATH:
				strcpy( ElfGetDItem(item_select)->file_path, data );
				return APP_UtilChangeState( APP_STATE_MAIN, ev_st, app );				
		}
		
	mfree(data);
	
    return UIX_Render(app->dialog);
}

static void * MainEntryReq( APPLICATION_T * app, UINT32 idx )
{
	UIX_LIST_ENTRY_T    *e;
	UIX_ICON_T			icon;
	
	// динамически создаем
	e = suAllocMem(sizeof(UIX_LIST_ENTRY_T), NULL);
	memclr(e, sizeof(UIX_LIST_ENTRY_T));
	
	e->flags = LE_FLAG_HAS_DATA;
	e->dtype = LE_DATA_TYPE_STR;
	
	switch ( idx )
    {
		case 0:
			e->name = "URL:";
			e->dtype = LE_DATA_TYPE_STR;
			e->d.s = (char*)ElfGetDItem(item_select)->url;
		break;
		
		case 1:
			e->name = "File name:";
			e->dtype = LE_DATA_TYPE_STR;
			if ( strlen(ElfGetDItem(item_select)->file_name) )
				e->d.s = (char*)ElfGetDItem(item_select)->file_name;
			else
				e->d.s = (char*)"Auto";
		break;
		
		case 2:
			e->name = "File path:";
			e->dtype = LE_DATA_TYPE_STR;
			e->d.s = (char*)ElfGetDItem(item_select)->file_path;
		break;
	}
	
	return e;
}

UINT32 HandleTimer( EVENT_STACK_T *ev_st,  APPLICATION_T *app )
{
	UINT32 			id = ((DL_TIMER_DATA_T*)(AFW_GetEv(ev_st)->attachment))->ID;
	char			title[32];
	if ( id == 0 ) 
	{
		if( app->state == APP_STATE_DOWNLOAD ) {
		
			switch( download_state ) {
			
				case DOWNLOAD_ERROR:
					UIX_DialogSetTitle(app->dialog, "Error...", ElfGetIcon(0));
					break;
					
				case DOWNLOAD_CONNECT:
					UIX_DialogSetTitle(app->dialog, "Connecting...", ElfGetIcon(0));
					break;
				
				case DOWNLOAD_GET_INFO:
					UIX_DialogSetTitle(app->dialog, "Getting info...", ElfGetIcon(0));
					break;
				
				case DOWNLOAD_DATA:
					sprintf(title, "Downloadind: %d/%d", ElfGetDItem(item_select)->file_size, ElfGetDItem(item_select)->file_loaded_size);
					
					UIX_DialogSetTitle(app->dialog, title, ElfGetIcon(0));
					break;
					
				case DOWNLOAD_COMPLETE:
					UIX_DialogSetTitle(app->dialog, "Complete!!!", ElfGetIcon(0));
					break;
					
				case DOWNLOAD_STOPPED:
					UIX_DialogSetTitle(app->dialog, "Stopped...", ElfGetIcon(0));
					break;
				
			}		
			UIX_Render( app->dialog );
		}	
	} 

	return RESULT_OK;
}
UINT32 ReadSetting() 
{
	FILE_HANDLE_T 		f;
	
	// читаем данные из конфига
	if (DL_FsFFileExist(file_cfg)) { // проверяем есть ли файл
	
		f = DL_FsOpenFile(file_cfg, FILE_READ_MODE, 0);
		
		List_ReadFile( &download, f );
		
        DL_FsCloseFile(f);
		
        dbg("ReadSetting: done");
    }
	
	return RESULT_OK;
}

// записываем в конфиг
UINT32 SaveSetting()
{
	FILE_HANDLE_T 			f;

	
	// запись в файл
	f = DL_FsOpenFile(file_cfg, FILE_WRITE_MODE, 0);
	
	List_WriteFile( &download, f );
		
	DL_FsCloseFile(f);
	
	dbg("Save Setting");
	return RESULT_OK;
}

DOWNLOAD_T * ElfGetDItem( UINT8 i )
{

	return (DOWNLOAD_T *)List_GetItem(&download, i);
}

UIX_ICON_T ElfGetIcon( UINT8 i )
{
	UIX_ICON_T		icon;
	
		icon.bmp = image_icons;
		icon.point.x = i * 16;
		icon.point.y = 0;
	
	return icon;
}

int StartDownload()
{
	dbg("StartDownload");
	
	http_state = HTTP_HEADER;
	download_state = DOWNLOAD_CONNECT;
	
	strcpy( ElfGetDItem(item_select)->url, "http://myforums.us/" );
	strcpy( ElfGetDItem(item_select)->file_name, "dm_data.txt" );
			
	CP1251toUCS2( ElfGetDItem(item_select)->file_path, ElfGetDItem(item_select)->full_file_name );
	CP1251toUCS2( ElfGetDItem(item_select)->file_name, ElfGetDItem(item_select)->full_file_name + u_strlen(ElfGetDItem(item_select)->full_file_name) ); // Получаем полное имя файла
	
	
	URLParse( ElfGetDItem(item_select)->url );

	ElfGetDItem(item_select)->file_handle = FILE_INVALID;
	ElfGetDItem(item_select)->file_loaded_size = DL_FsSGetFileSize( ElfGetDItem(item_select)->full_file_name, 0 );
	
	
	sprintf( ElfGetDItem(item_select)->header, "GET /%s HTTP/1.1\r\n"
					"Host: %s\r\n",
					"Range: bytes=%d-\r\n",
					"Referer: %s\r\n",
					"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n",
					"Connection: close\r\n"
					"\r\n",
					ElfGetDItem(item_select)->path,
					ElfGetDItem(item_select)->host,
					ElfGetDItem(item_select)->file_loaded_size,
					ElfGetDItem(item_select)->referer
					);
  
	return SockCreatSocket();
}
#define ST_ERR -1
#define ST_FINISH 0
#define ST_HOST 1
#define ST_PORT 2
#define ST_PATH 3
#define ST_PARAM 4
#define ST_FRAGMENT 5

char host_term[] = ":/?#";
int  host_st[] = {ST_PORT, ST_PATH, ST_PARAM, ST_FRAGMENT};
char port_term[] = ":/?#";
int  port_st[] = {ST_ERR, ST_PATH, ST_PARAM, ST_FRAGMENT};
char path_term[] = "?#";
int  path_st[] = {ST_PARAM, ST_FRAGMENT};
char param_term[] = "#";
int  param_st[] = {ST_FRAGMENT};

int URLParse(char * s_url)
{
	dbgf("URLParse: enter, url = %s", s_url);

	char * tmp = s_url;
	char * scheme;
	char * scheme_delim = strstr(tmp, "://");
	
	if (scheme_delim) {
		int schlen = scheme_delim - tmp;
		scheme = malloc( schlen + 1 );
		strncpy( scheme, tmp, schlen );
		scheme[schlen] = 0;
		tmp += schlen + 3;
	} else {
		scheme = malloc( 5 );
		strcpy( scheme, "http" );
	}
	int st = ST_HOST;
	int len = strlen(tmp);
	int clen = 0;
	while ( st > 0 )
	{
		switch( st )
		{
			case ST_HOST:
				if (strchr(host_term, tmp[clen]) || !tmp[clen]) {
					if (tmp[clen])
						st = host_st[strchr(host_term, tmp[clen])-host_term];
					else
						st = ST_FINISH;
					
					strncpy(ElfGetDItem(item_select)->host, tmp, clen);
					ElfGetDItem(item_select)->host[clen] = 0;
					tmp += clen+1;
					len -= clen+1;
					clen = 0;
				} else
					clen++;
				break;
			
			case ST_PORT:
				ElfGetDItem(item_select)->port = strtoul(tmp, &tmp, 10);
				
				if (tmp[clen])
					st = port_st[strchr(port_term, *tmp++)-port_term];
				else
					st = ST_FINISH;
					
				break;
			
			case ST_PATH:
				if (strchr(path_term, tmp[clen]) || !tmp[clen]) {
				
					if (tmp[clen])
						st = path_st[strchr(path_term, tmp[clen])-path_term];
					else
						st = ST_FINISH;

					strncpy(ElfGetDItem(item_select)->path, tmp, clen);
					ElfGetDItem(item_select)->path[clen] = 0;
					tmp += clen+1;
					len -= clen+1;
					clen = 0;
				} else
					clen++;
				break;
				
			/* case ST_PARAM:
				if (strchr(param_term, tmp[clen]) || !tmp[clen])
				{
				if (tmp[clen])
				st = param_st[strchr(param_term, tmp[clen])-param_term];
				else
				st = ST_FINISH;
				this->param = new char[clen+1];
				strncpy(this->param, tmp, clen);
				this->param[clen] = 0;
				tmp += clen+1;
				len -= clen+1;
				clen = 0;
				}
				else
				clen++;
				break;
				
			case ST_FRAGMENT:
				if (!tmp[clen])
				{
				st = ST_FINISH;
				this->fragment = new char[clen+1];
				strncpy(this->fragment, tmp, clen);
				this->fragment[clen] = 0;
				tmp += clen+1;
				len -= clen+1;
				clen = 0;
				}
				else
				clen++;
				break;*/
		}
	}
	if ( !ElfGetDItem(item_select)->port )
		ElfGetDItem(item_select)->port = 80;
	
	dbg("URLParse: done");
	
	return 1;
}

int
header_process (const char *header, const char *name,
		int (*procfun) (const char *, void *),
		void *arg)
{
  /* Check whether HEADER matches NAME.  */
  while (*name && (tolower (*name) == tolower (*header)))
    ++name, ++header;
  if (*name || *header++ != ':')
    return 0;

  header += skip_lws (header);

  return ((*procfun) (header, arg));
}

/* Strdup HEADER, and place the pointer to CLOSURE.  */
int
header_strdup (const char *header, void *closure)
{
  *(char **)closure = strdup (header);
  return 1;
}

/* Skip LWS (linear white space), if present.  Returns number of
   characters to skip.  */
int skip_lws (const char *string)
{
  const char *p = string;

  while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
    ++p;
  return p - string;
}

#ifdef	DEBUG
void ReportPhoneInfo()
{
	dbg("");
	
	dbgf("PhoneInfo: PhoneName = %s", ldrGetPhoneName());
	dbgf("PhoneInfo: PlatformName = %s", ldrGetPlatformName());
	dbgf("PhoneInfo: FirmwareVersion = %s", ldrGetFirmwareVersion());
	
	dbg("");
	const AHIDRVINFO_T	*ahi = ldrGetAhiDrvInfo();
	dbgf("PhoneInfo: ahi.drvName = %s", ahi->drvName);
	dbgf("PhoneInfo: ahi.drvVer = %s", ahi->drvVer);
	dbgf("PhoneInfo: ahi.totalMemory = %d b", ahi->totalMemory);
	dbgf("PhoneInfo: ahi.internalMemSize = %d b", ahi->internalMemSize);
	dbgf("PhoneInfo: ahi.externalMemSize = %d b", ahi->externalMemSize);
	dbg("");
}
#endif
