#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winb.h>
#include <te.h>
#include <fntb.h>
#include <gui.h>
#include <egb.h>
#include <guidbg.h>

char	*guiEgbPtr ;			/*	EGB のワークアドレス	*/

extern int	quitIconID ;
extern int	messageID[] ;
//extern int	taskButtonID[] ;
extern int	aboutDButtonID ;
extern int	dialogMenuID;
extern int	aboutMessageID[];

#include <file_dlg.h>
//#include <eintm.h>
#include <mos.h>
#include <KH.h>
//#define DEBUG
#define ERROR	(-1)
#define MOSWAITPTR	(81)

extern int	readMenuFunc(void);
extern int	aboutFlag ;
extern char	*menuItemMsg ;		//メニューアイテムメッセージ保存用
extern int	memLotID;
extern char	*apliPath;		//アプリパス
extern int	*apliSaveFlag;	//アプリ退避フラグ(TRUE:退避中)
extern int	apliNum;		//登録アプリ数
extern int	MenuItemID[];

extern char *aboutMsg;

void	userIdleTask(void);
void	restartEXG(void);
void	menuENABLE(void);

char *taskListMsg[12] = {
					"┏━━━━━━━━━━━━━━━━━━┓\0",
					"┃┌────────────────┐┃\0",
					"┃│               ▼               │┃\0",
					"┃│      ﾈＴａｓｋｍａｎａﾇ      │┃\0",
					"┃│               ▲               │┃\0",
					"┃│          Version 1.00          │┃\0",
					"┃│                                │┃\0",
					"┃│     ﾂProgrammed by 機拡ﾁ     │┃\0",
					"┃│                                │┃\0",
					"┃└────────────────┘┃\0",
					"┗━━━━━━━━━━━━━━━━━━┛\0",
					"アプリの数:000\0"
				} ;

int taskOldID[10]=-1;
int taskOldCount = 1000;
int taskListUpdateFlag = FALSE ;
int taskFlag=0;

int quitFuncRet = ILLEGAL_FUNCTION ;

int userFunc(apliId, messId, info, data)
int	apliId;
int	messId;
int	info;
int	data;
{
	int		ret;
	EVENT	*ev;
	POINT	pt;

	ret = ILLEGAL_FUNCTION;

	switch(messId)
	{
		case	GM_QUIT :
			MMI_SendMessage( quitIconID, MM_EXEC, 2, 0, 0 );
			ret = quitFuncRet ;
			break;

		case	GM_SLEEP :
			#ifdef DEBUG
			printf("--==<<GM_SLEEP>>==--\n");
			#endif
			if(aboutFlag == TRUE)
			{
				//	消去する
				MMI_SendMessage( aboutDButtonID, MM_EXEC, 2, 0, 0 );
				aboutFlag = FALSE ;
			}
			taskListUpdateFlag = TRUE ;
			//	タスクリスト更新
//			userIdleTask();
			MMI_SendMessage(dialogMenuID,MM_ENABLE,1,FALSE);
			MMI_SendMessage(dialogMenuID,MM_SHOW,0);
			break;

		case	GM_WAKE :
			#ifdef DEBUG
			printf("--==<<GM_WAKE>>==--\n");
			#endif
/*			static int	argv[2] = { 1, 1 } ;
			EVENT	ev ;
			ev.what = EVEXEC ;
			ev.shift = 0 ;
			ev.info = (int)menuENABLE;
			ev.data = (int)argv ;
			MMI_SetEvnt(&ev) ;
*/

			if(MMI_SnsEvnt(EVMOSDN,&ev)==0)
			{
				pt.x=(( POINT * )&( ev->info ))->x;
				pt.y=(( POINT * )&( ev->info ))->y;
				#ifdef DEBUG
				printf("EVMOSDN(%d,%d)=",pt.x,pt.y);
				#endif
				if(MMI_CheckInside( dialogMenuID, &pt )!=FOUTSIDE)
				{
					MMI_FlushEvnt();
					#ifdef DEBUG
					printf("FINSIDE\n");
					#endif
				}
				#ifdef DEBUG
				else printf("FOUTSIDE\n");
				#endif

			}
			MMI_SendMessage(dialogMenuID,MM_ENABLE,1,TRUE);
			MMI_SendMessage(dialogMenuID,MM_SHOW,0);
			//	タスクリスト更新
			taskListUpdateFlag = ENABLE ;
			taskFlag=0;
			break;

		default : break;
	}

	return(ret);
}
/*
void menuENABLE(void)
{
	MMI_SendMessage(dialogMenuID,MM_ENABLE,1,TRUE);
	MMI_SendMessage(dialogMenuID,MM_SHOW,0);

	return ;
}
*/

void restartEXG(void)
{
	int i;

	//退避されてたEXGを再起動
	for(i=0;i<apliNum;i++)
		if(apliSaveFlag[i] == TRUE)
		{
			MMI_CallMessage(MMI_GetApliId(),GM_INVOKE,FALSE,
												(int)&(apliPath[i*128]));
			apliSaveFlag[i] = FALSE;
		}

	taskListUpdateFlag = ENABLE ;
	taskFlag=0;
	userIdleTask();
//	taskListUpdateFlag = FALSE ;

	return ;
}

void main(int argc,char *argv[])
{
	int mret,mptr;

	//パラメータをチェック
/*	while(--argc>0)
	{
		if(argv[argc][0] == '-')
			switch(argv[argc][1])
			{
				case	'E' :
			}
	}*/

	static MMICTRL mmi ={
				SCREEN16|SCREENIGNORE,		// ページ0側解像度
				SCREENUNUSED,				// ページ1側解像度
				0, 							// 書き込みページ
				SCREENAVAILABLE, 			// 表示ページ
				0, 							// 表示プライオリティ
				SCREENAVAILABLE,			// 色数
				SCREENEXPAND, 				// VRAMの横の長さ
				0, 							// メモリ領域の大きさ
				NULL, 						// メモリ領域のアドレス
				0, 							// ユーザ領域の大きさ
				NULL, 						// ユーザ領域のアドレス
				0, 0, 						// 画面枠	lupx,lupy
				0, 0,						//			rdwx,rdwy
				-16384, -16384,				// 移動枠	lupx,lupy
				16383, 16383,				//			rdwx,rdwy
				15, 						// 白色
				8,  						// 黒色
				7,  						// 灰色
				6	 						// 反転色
	};

	extern int APL_init() ;
	extern int APL_end() ;

	/*	初期化処理	*/
	if (MMI_Open( &mmi ) == NOERR)
	{
		mret = MG_PushPtr(MOSWAITPTR,&mptr);
		/*	初期化に成功すればメインループに入る.	*/
		if (APL_init() == NOERR)
		{
			if(mret==0) MG_PopPtr( mptr );
			MMI_ExecSystem() ;
			mret = MG_PushPtr(MOSWAITPTR,&mptr);
			APL_end();
			if(mret==0) MG_PopPtr( mptr );
		} else if(mret==0) MG_PopPtr( mptr );
	}

	/*	終了処理	*/
	MMI_Close() ;

}

int APL_init()
{
	extern MMIINIT	initDataGUI ;
	extern MMIINIT	initDataABOUTGUI ;
	extern MMIINIT	initDataSRCGUI ;
	extern MMIINIT	initDataCMNDGUI ;

	int	ret ;

	/*	EGB ワークアドレスの取得.	*/
	guiEgbPtr = MMI_GetEgbPtr() ;

	/*	ユーザアイコン設定		*/
	extern unsigned char *iconTbl[];
	extern int iconMaxId;
	MMI_SetIconTable(iconTbl, iconMaxId);

	/*	ハイパ型部品の初期化			*/
	if ((ret = MMI_initHyper()) < 0)
		return ret ;
	/*	ダイアログ型部品の初期化		*/
	if ((ret = MMI_initDialogL40()) < 0)
		return ret ;
	/*	アラート型部品の初期化			*/
	if ((ret = MMI_initAlertL40()) < 0)
		return ret ;
	/*	メッセージ型部品の初期化		*/
	if ((ret = MMI_initMessageL40()) < 0)
		return ret ;
	/*	メニュー型部品の初期化			*/
	if ((ret = MMI_initMenuL40()) < 0)
		return ret ;
	/*	ボタン型部品の初期化			*/
	if ((ret = MMI_initButtonL40()) < 0)
		return ret ;
	/*	ドロウボタン型部品の初期化		*/
	if ((ret = MMI_initDrawButtonL40()) < 0)
		return ret ;
	/*	アイコンボタン型部品の初期化	*/
	if ((ret = MMI_initIconL40()) < 0)
		return ret ;
	/*	メニューアイテム型部品の初期化	*/
	if ((ret = MMI_initMenuItemL40()) < 0)
		return ret ;
	/*	スクロール型部品の初期化		*/
	if ((ret = MMI_initScrollBarL40()) < 0)
		return ret ;
	/*	テキスト型部品の初期化			*/
	if ((ret = MMI_initTextL40()) < 0)
		return ret ;
	/*	リストメニュー型部品の初期化	*/
	if ((ret = MMI_initListMenuL40()) < 0)
		return ret ;

	/*	背景データの初期化						*/

	/*	データの登録		*/
	if ((ret = MMI_Init(&initDataGUI)) < 0)
		return ret ;
	if ((ret = MMI_Init(&initDataABOUTGUI)) < 0)
		return ret ;
	if ((ret = MMI_Init(&initDataSRCGUI)) < 0)
		return ret ;
	if ((ret = MMI_Init(&initDataCMNDGUI)) < 0)
		return ret ;

	//	Tmenuにパレットを合わせる
	KH_initGuiColor();
//	EIN_initGuiColor();

	//	初期化
	int id;
	id = MMI_GetApliId();
	//	タスクリストの初期化
	int i;
	char *t;
	for(i=0;i<12;i++)
		MMI_SendMessage(messageID[i],MM_SETMSG,1,taskListMsg[i]);
	//	シェルの名前をシェルボタンに登録
	i = MMI_CallMessage(id, GM_QUERYID, QM_ALLKIND, 0 );
	t = ( char * )MMI_CallMessage( i, GM_TITLE, (int)NULL, 0 );
	i=0;
	while(t[i]!='\0') {taskListMsg[10][i]=t[i];i++;}
	for(;i<40;i++) taskListMsg[10][i]=' ';
	taskListMsg[10][40]='\0';

	MMI_SendMessage( aboutMessageID[2],MM_SETMSG,1, aboutMsg);

//	MMI_CallMessage(id, GM_SLEEP, 0, 0 );

	//｢圧縮｣メニューは未対応
	MTL_setAtrObj(MenuItemID[8],MS_INACTIVEL40);

	/*	背景を表示する							*/
	MMI_SendMessage(MMI_GetBaseObj(), MM_SHOW, 0) ;

	MMI_SendMessage(MMI_GetBaseObj(), MM_SETEXEC, 1, userFunc);
	MMI_CallMessage(id, GM_TITLE, (int)"taskmana                        By 機拡", 0);

	//メニュー読み込み
	if(readMenuFunc()!=NOERR) return ERROR ;

	//	アイドルタスク
	MMI_SetIdleTaskFunc( userIdleTask );
	taskListUpdateFlag = TRUE ;
	userIdleTask();
	taskListUpdateFlag = FALSE ;
	#ifdef DEBUG
	printf("アイドルタスクセット\n");
	#endif

	//┏━━━━━━━━━━━┓
	//┃ファイルダイアログ設定┃
	//┗━━━━━━━━━━━┛
	//	起動時のカレントドライブ･ディレクトリを保存
	FDG_SaveCurDir() ;
	//	ファイルダイアログの初期化
	FDG_InitFileDlg() ;
	//	ファイルダイアログのタイトルを設定する
	FDG_SetTitle("実行ファイル選択", "実 行", "取 消") ;

	return NOERR ;
}

int APL_end()
{
	//メニュー用領域開放
	TL_freeLot( memLotID ); 

	//	ファイルダイアログのメモリ解放
	FDG_FreeFileDlg() ;
	//	カレントドライブ･ディレクトリを復帰
	FDG_RecovCurDir() ;

	return NOERR ;
}

void userIdleTask(void)
{
	int mx,my,myID,count,id,i,j ;
	char *t;

	if(taskListUpdateFlag == FALSE) return ;
	else
	{
		myID  = MMI_GetApliId();

		if(taskListUpdateFlag==ENABLE)
		{
			for(i=0;i<10;i++) taskOldID[i]=-1;
			taskOldCount=1000;
			if(taskFlag>0)
			{
				--taskFlag;
				return;
			}
			else
				taskListUpdateFlag=FALSE;
		}
		else
		{
			MOS_rdpos( &i, &mx, &my );
			if(mx==0 && my==0)
			{
				if(myID!=MMI_CallMessage(myID, GM_QUERYID, QM_ALLKIND, 1 ))
				MMI_CallMessage(myID, GM_WAKE, 0, 0 );
			}
		}
	}

	count = MMI_CallMessage( myID, GM_QUERYID, QM_ALLCOUNT, 0 );
	#ifdef DEBUG
	printf("count = %d\n",count);
	#endif
	count--;
	if(count>10) count = 10;

	for(i=0;i<count;i++)
	{
		id = MMI_CallMessage( myID, GM_QUERYID, QM_ALLKIND, i+1 );
		if(taskOldID[i]!=id)
		{
			taskOldID[i] = id;
			t = ( char * )MMI_CallMessage( id, GM_TITLE, (int)NULL, 0 );
			j=0;
			while(t[j]!='\0') {taskListMsg[i][j]=t[j];j++;}
			for(;j<40;j++) taskListMsg[i][j]=' ';
			taskListMsg[i][40]='\0';
			#ifdef DEBUG
			printf("%s(%d)\n",taskListMsg[i],i);
			#endif
			MMI_SendMessage(messageID[i],MM_SHOW,0);
		}
	}

	if(count<taskOldCount)
	{
		for(i=count;i<10;i++)
		{
			taskOldID[i] = -1;
			for(j=0;j<40;j++) taskListMsg[i][j] = '-' ;
			taskListMsg[i][40] = '\0';
			#ifdef DEBUG
			printf("----------------------------------------(%d)\n",i);
			#endif
			MMI_SendMessage(messageID[i],MM_SHOW,0);
		}
	}

	if(count!=taskOldCount)
	{
		taskListMsg[11][11] = '0' + ((count/100)%10);
		taskListMsg[11][12] = '0' + ((count/ 10)%10);
		taskListMsg[11][13] = '0' + ( count     %10);
		MMI_SendMessage(messageID[11],MM_SHOW,0);
		taskOldCount = count;
	}

	return ;
}
