#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winb.h>
#include <te.h>
#include <fntb.h>
#include <gui.h>
#include <file_dlg.h>
#include <egb.h>
#include <mos.h>
#include <snd.h>
#include <guidbg.h>
#include "tetujin.h"


char	*guiEgbPtr ;			/*	EGB のワークアドレス	*/

/*	アラートメッセージ						*/
static char	*alertStrMem[] = 
				{"画像処理の鉄人達：\nメモリが不足しています", "確認"};

/*	checkMemFunc関数／alertMemFunc関数の追い越し禁止フラグ	*/
static int		checkMemFlag = 0x00 ;

/****************************************************************/
/*	メモリ不足時のアラート関数（イベント登録関数）				*/
/****************************************************************/
void alertMemFunc()
{
	/*	メモリ不足のアラート表示	*/
	MMI_CallMessage(MMI_GetApliId(), GM_ALERT, 
						AM_ALERT1 | AM_ALERTB0E,(int)alertStrMem) ;

	/* checkMemFunc関数/alertMemFunc関数の追い越し禁止解除	*/
	checkMemFlag &= 0xef ;
}

/****************************************************************/
/*	メモリ開放関数												*/
/****************************************************************/
int checkMemFunc(useMem)
int	useMem ;
{
	int		ret ;

	/*	メモリチェック					*/
	if(TL_checkMemory(1) * 4096 >= useMem)
		return NOERR ;		/*	メモリがあれば正常復帰		*/

	do
	{
		/*	メモリ開放処理				*/
		ret = MMI_CallMessage(MMI_GetApliId(), GM_PURGE, 0, 0) ;

		/*	メモリチェック				*/
		if(TL_checkMemory(1) * 4096 >= useMem)
			break ;
	} while(ret == NOERR) ;

	return	ret ;
}


/****************************************************************/
/*	Townsシェル呼び出し関数										*/
/****************************************************************/
int userFunc(aplId, messId, info, data)
int		aplId ;
int		messId ;
int		info ;
int		data ;
{
	extern int wakeSet() ;
	extern int sleepSet() ;
	extern int quitFunc2() ;

	register int	ret ;
	int				sw ;
	POOLDATA		*ptr ;

	ret = ILLEGAL_FUNCTION ;

	switch (messId)
	{
		case	GM_WAKE :
		{
			EVENT	ev ;

			/*	checkMemFunc関数の追い越し禁止判定			*/
			if(checkMemFlag & 0x01)
				break ;

			/*	動作メモリのチェック						*/
			/*	checkMemFunc関数の追い越し禁止		*/
			checkMemFlag |= 0x01 ;
			if(checkMemFunc(MinMem) != NOERR)
			{
				/*	alertMemFunc関数の追い越し禁止	*/
				checkMemFlag |= 0x10 ;
				/*	メモリ不足の場合はアラート処理関数をイベント登録する	*/
				MMI_FlushEvnt() ;
				ev.what = EVEXEC ;
				ev.shift = 0 ;
				ev.info = (int)alertMemFunc ;
				MMI_SetEvnt(&ev) ;
				break ;
			}

			wakeSet() ;
			break ;
		}

		case	GM_SLEEP :
		{
			/* alertMemFunc関数がイベント登録されてなければ、checkMemFunc関数
				の追い越し禁止解除											*/
			if((checkMemFlag & 0x10) == 0x00)
				checkMemFlag &= 0xfe ;

			sleepSet() ;
			break ;
		}

		case	GM_QUIT :
		{
			ret = quitFunc2() ;
			break ;
		}

	}
	return ret ;

}

void main()
{
	extern int APL_init() ;
	extern int startSet() ;

	MMICTRL ctrl ;
	int kobj ;

	/*	初期化処理	*/

    ctrl.page0=SCREEN32K;
    ctrl.page1=SCREENUNUSED;
    ctrl.writePage=0;
    ctrl.displayPage=1;
    ctrl.priority=0;
    ctrl.mode=SCREENAVAILABLE;
    ctrl.width=SCREENEXPAND;

    ctrl.size=0;
    ctrl.ptr=NULL;

    ctrl.asize=0;
    ctrl.aptr=NULL;

    ctrl.move.lupx=-16384;
    ctrl.move.lupy=    20;
    ctrl.move.rdwx= 16383;
    ctrl.move.rdwy= 16383;

	ctrl.white = 15 ;
	ctrl.black = 8 ;		/* GUIの表示色を変更(黒)	 */
	ctrl.gray = 7 ;			/*      〃          (灰色)   */
	ctrl.xor = 15 ;			/*      〃          (反転色) */

	/*	二重起動のチェック		*/
	if((kobj = MMI_CallMessage(MMI_GetApliId(),
									GM_QUERYID, QM_KIND, 1)) > NOERR)
	{
		/*	同一ファイル名のアプリが既に存在する場合は
			自アプリを終了する					*/
		MMI_CallMessage(MMI_GetApliId(), GM_SWITCH, FALSE, kobj) ;

	}
	/*	初期化処理				*/
	else if (MMI_Open( &ctrl ) == NOERR)
	{
		/*	初期化に成功すればメインループに入る.	*/
		if (APL_init() == NOERR)
		{
			/*	動作メモリのチェック	*/
			/*	checkMemFunc関数の追い越し禁止	*/
			checkMemFlag |= 0x01 ;
			if(checkMemFunc(MinMem) != NOERR)
			{
				/*	alertMemFunc関数の追い越し禁止	*/
				checkMemFlag |= 0x10 ;
				alertMemFunc();			/*	メモリ不足のアラート表示	*/
			}
			/*	checkMemFunc関数の追い越し禁止解除	*/
			checkMemFlag &= 0xfe ;

			FDG_SaveCurDir() ;		/*	カレントディレクトリ保存	*/
		    FDG_InitFileDlg() ;		/*	ファイルダイアログ初期化	*/

			if( startSet() == NOERR )
				MMI_ExecSystem() ;		/*	メインのイベントループ		*/

		    FDG_FreeFileDlg() ;		/*	ファイルダイアログ終了処理	*/
			FDG_RecovCurDir() ;		/*	カレントディレクトリ復元	*/

			MMI_SendMessage(MMI_GetSleepObj(), MM_SLEEP, 0) ;
			MMI_SetWakeObj(UNUSED);
		}
		/*	終了処理				*/
		MMI_Close() ;
	}

}



int APL_init()
{
	extern MMIINIT	initDataIGRABOU ;
	extern MMIINIT	initDataIGRDSK ;
	extern MMIINIT	initDataIGRERR ;
	extern MMIINIT	initDataIGRWIN ;
	extern MMIINIT	initDataIGRFILE ;
	extern MMIINIT	initDataIGRSET ;

	extern GRAPHWIN	window[] ;
	extern int windowId ;
	extern int vscrollId ;
	extern int hscrollId ;

	extern int		mItemId[] ;

	register int	ret ;
	int i ;

	/*	EGB ワークアドレスの取得.	*/
	guiEgbPtr = MMI_GetEgbPtr() ;

	/*	ハイパ型部品の初期化			*/
	if ((ret = MMI_initHyper()) < 0)
		return ret ;
	/*	リストメニュー型部品の初期化	*/
	if ((ret = MMI_initListMenuL40()) < 0)
		return ret ;
	/*	ダイアログ型部品の初期化		*/
	if ((ret = MMI_initDialogL40()) < 0)
		return ret ;
	/*	アラート型部品の初期化			*/
	if ((ret = MMI_initAlertL40()) < 0)
		return ret ;
	/*	ウインドウ型部品の初期化		*/
	if ((ret = MMI_initWindowL40()) < 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_initToggleIconL40()) < 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_initNumBoxL40()) < 0)
		return ret ;

	/*	パレット変更 */
	setPalette() ;

	/*	背景データの初期化						*/

	/*	データの登録		*/
	if ((ret = MMI_Init(&initDataIGRABOU)) < 0)
		return ret ;

	if ((ret = MMI_Init(&initDataIGRDSK)) < 0)
		return ret ;

	if ((ret = MMI_Init(&initDataIGRERR)) < 0)
		return ret ;

	if ((ret = MMI_Init(&initDataIGRWIN)) < 0)
		return ret ;

	if ((ret = MMI_Init(&initDataIGRFILE)) < 0)
		return ret ;

	if ((ret = MMI_Init(&initDataIGRSET)) < 0)
		return ret ;

	/* 解像度にあわせてボタンの位置を変更 */

	extern int	quitIconId ;
	extern int	outIconId ;
	extern int	boundWidth ;

	WINCTRL *pctrl ;
	HYPER hyp ;

	MMI_GetControl( &pctrl ) ;
	boundWidth = pctrl->bound.rdwx + 1 ;
	MMI_SendMessage( quitIconId, MM_GETHYPER, 1, &hyp ) ;
	hyp.fr.lupx = pctrl->bound.rdwx - 28 ;
	hyp.fr.lupy = 0 ;
	hyp.fr.rdwx = pctrl->bound.rdwx -  9 ;
	hyp.fr.rdwy = 19 ;
	MMI_SendMessage( quitIconId, MM_MOVE, 1, &(hyp.fr) ) ;

	MMI_SendMessage( outIconId, MM_GETHYPER, 1, &hyp ) ;
	hyp.fr.lupx = pctrl->bound.rdwx - 59 ;
	hyp.fr.lupy = 0 ;
	hyp.fr.rdwx = pctrl->bound.rdwx - 40 ;
	hyp.fr.rdwy = 19 ;
	MMI_SendMessage( outIconId, MM_MOVE, 1, &(hyp.fr) ) ;

	/* 解像度にあわせて基準になるウインドウの位置を変更 */

	HYPER	winhyp ;
	HYPER	vschyp ;
	HYPER	hschyp ;
	FRAME	org ;
	FRAME	size ;

	MMI_SendMessage( windowId , MM_GETHYPER , 1 , &winhyp );
	MMI_SendMessage( vscrollId , MM_GETHYPER , 1 , &vschyp );
	MMI_SendMessage( hscrollId , MM_GETHYPER , 1 , &hschyp );
	MMI_SendMessage( windowId , MM_GETUSER , 2 , &org , &size );

	winhyp.fr.rdwx = winhyp.fr.rdwx + boundWidth - 512 ;
	org.rdwx = org.rdwx             + boundWidth - 512 ;
	size.rdwx = size.rdwx           + boundWidth - 512 ;

	vschyp.fr.lupx = vschyp.fr.lupx + boundWidth - 512 ;
	vschyp.fr.rdwx = vschyp.fr.rdwx + boundWidth - 512 ;
	hschyp.fr.rdwx = hschyp.fr.rdwx + boundWidth - 512 ;

	MMI_SendMessage( windowId , MM_SETHYPER , 1 , &winhyp ) ;
	MMI_SendMessage( vscrollId , MM_SETHYPER , 1 , &vschyp ) ;
	MMI_SendMessage( hscrollId , MM_SETHYPER , 1 , &hschyp ) ;
	MMI_SendMessage( windowId , MM_SETUSER , 2 , &org , &size ) ;


	/*	ウィンドウの影の存在から実態を生成する				*/
	for( i = 0 ; i < WINCOUNT ; i++ )
	{
		/*	ウィンドウ,テキスト,スクロールバーを生成する	*/
		window[i].windowId = -(MMI_SendMessage( windowId , MM_NEW , 0)) ;
		window[i].vscrollId = MMI_SendMessage( vscrollId , MM_NEW , 0);
		window[i].hscrollId = MMI_SendMessage( hscrollId , MM_NEW , 0);
		window[i].buf16m = NULL ;
		window[i].bufAlpha = NULL ;
		window[i].buf32k = NULL ;
		window[i].loadPath[0] = 0 ;
		window[i].savePath[0] = 0 ;
	}

	/*	タスクリストとサイドワークメニューを登録する	*/
	MMI_SetUpPrgMenu( mItemId[0], 2 ) ;
	MMI_SetUpSDKMenu( mItemId[0], 4 ) ;

	/*	呼び出し関数を登録する	*/
	MMI_SendMessage(MMI_GetBaseObj(), MM_SETEXEC, 1, userFunc) ;

	/*	アプリケーション名を登録する	*/
	MMI_CallMessage(MMI_GetApliId(), GM_TITLE, (int)"画像処理の鉄人達", 0) ;

	/*	背景を表示する							*/
	MMI_SendMessage(MMI_GetBaseObj(), MM_SHOW, 0) ;

	return NOERR ;
}

/*	32kモード専用パレット設定 */
static int	setPalette()
{
	int temp ;
	unsigned int *table ;

	table = MG_getColorTable( 2 ) ;	/* mode 0:16色, 1:256色 2:32768色 */

	void 	set1Pal( int n, int b, int r, int g )
	{
		temp = (b * 2) + ((r * 2) << 5) + ((g * 2) << 10) ;
		table[ n ] = temp + ( temp << 16 ) ;
	}

/*	16色のパレットだと思って設定すればよい */
	set1Pal( 0, 0, 0, 0 ) ;
	set1Pal( 1, 4, 4, 8 ) ;
	set1Pal( 2, 4, 12, 6 ) ;
	set1Pal( 3, 5, 5, 5 ) ;		// ( 3, 10, 15, 12 )
	set1Pal( 4, 9, 9, 9 ) ;
	set1Pal( 5, 7, 0, 12 ) ;
	set1Pal( 6, 12, 12, 12 ) ;
	set1Pal( 7, 8, 8, 8 ) ;		// ( 7, 7, 7, 7 )
	set1Pal( 8, 1, 1, 1 ) ;
	set1Pal( 9, 8, 10, 12 ) ;	/* file selector */
	set1Pal( 10, 0, 13, 0 ) ;
	set1Pal( 11, 10, 0, 0 ) ;
	set1Pal( 12, 0, 0, 15 ) ;
	set1Pal( 13, 15, 0, 15 ) ;
	set1Pal( 14, 0, 15, 13 ) ;
	set1Pal( 15, 15, 15, 15 ) ;

	return NOERR ;
}

