/* DIVIDE_START=main.c */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <snd.h>
#include <winb.h>
#include <te.h>
#include <fntb.h>
#include <gui.h>
#include	<fnt.h>
#include	<file_dlg.h>

#include	"..\common.h"

#define	MAIN	2		// common.h より後で宣言すること
#include	"var.h"

void	main( int argc , char **argv )
{
	extern	int		APL_init() ;
			char	*p;

	/*	初期化に成功すればメインループに入る.	*/
	if ( APL_init() == NOERR ) {
		/*	ファイルダイアログ関係の初期化処理		*/
		FDG_SaveCurDir();		/*	カレントディレクトリを保存する		*/
		FDG_InitFileDlg();		/*	ファイルダイアログの初期化			*/

		/* about 画面に表示する Version を設定する */
		sprintf( Version, "Ver. %s", VERSION );
		MMI_SendMessage( VersionNameId, MM_SETMSG, 1, Version );

		// 各種変数を初期化する
		*CatlogMesFileName = *InDir = *OutDir = '\0';

		/* ここで、CATLOG の内部情報を初期化する */
		InitialInsideVars();

		/* カレントディレクトリに定義ファイルを探す */
		FM_GetCurrentDir( FM_GetCurrentDisk(), FileName );
		if ( *FileName == '\0' ) {
			sprintf( CatlogDefFileName, "%c:\\%s",
				FM_GetCurrentDisk(),	DEF_FILE_NAME
			);
		} else {
			sprintf( CatlogDefFileName, "%c:\\%s\\%s",
				FM_GetCurrentDisk(),	FileName,		DEF_FILE_NAME
			);
		};
		if ( LoadDefFile( NO ) == NO ) {
			sprintf( str, "\n<%s>が見つかりません", CatlogDefFileName );
			PrintMessage( str );
			/* なければ、起動ドライブに定義ファイルを探す */
//			sprintf(CatlogDefFileName,"%c:%s",FM_GetCurrentDisk(), *argv );
			strcpy( str, *argv );	p= last_yen( str );	*p= '\0';
			strcpy( CatlogDefFileName, str );
			append_yen( CatlogDefFileName );
			strcat( CatlogDefFileName, DEF_FILE_NAME );
/*
			sprintf( str, "\n<%s>を検索します", CatlogDefFileName );
			PrintMessage( str );
*/
			if ( LoadDefFile( NO ) == YES ) {
				sprintf( str, "\n<%s>で、処理を行います", CatlogDefFileName );
				PrintMessage( str );
			} else {
					FILE	*fpi;
				
				SetLineHelpAlert(
"ＦＡＰＸ (FAPXSET.SET) があるディレクトリを指定して下さい。"
"FAPXSET.SET ファイルから ログ・ディレクトリとＣＡＴＬＯＧ用ディレクトリを読み取ります"
				);
				strcpy( FAPXDir, GetPathName( FAPXDir ) );
				if ( (fpi=fopen(FAPXDir, "r")) != NULL ) {
					// ファイルが指定された場合ファイル名を削除する
					fclose( fpi );
					p= last_yen( FAPXDir );
					*p= '\0';
				};
				// FAPXSET.SET から直接値を得る
				/* カレントディレクトリに定義ファイルを探す */
				FM_GetCurrentDir( FM_GetCurrentDisk(), FileName );
				if ( *FileName == '\0' ) {
					sprintf( CatlogDefFileName, "%c:\\%s",
						FM_GetCurrentDisk(),	DEF_FILE_NAME
					);
				} else {
					sprintf( CatlogDefFileName, "%c:\\%s\\%s",
						FM_GetCurrentDisk(),	FileName,	DEF_FILE_NAME
					);
				};
				if ( getFAPXSET( FAPXDir ) == NO ) {
					if ( *OutDir == '\0' ) {
						SetLineHelpAlert(
"FAPXSET.SET が見つかりませんでした。標準設定で処理を行います。\n"
"ＣＡＴＬＯＧは「出力ディレクトリ（整理済のファイルを書き出すディレクトリ）」の設定がないと処理を行えません。設定して下さい。"
						);
						strcpy( OutDir, GetPathName( OutDir ) );
					};
				};
				SaveDefFile();
//				WriteCatlogDef( CatlogDefFileName );
			};
			PrintMessage( "\n" );
		};

		if (	CatlogAutoRunSw != YES
		&&		*CatlogMesFileName != '\0'
		) {
			// CatlogAutoRunSw が YES の時は追加型で書き出していく
			RemoveCATLOGMessageFile();
		};

		sprintf( str, "\nＣＡＴＬＯＧ    %s          DefFile=<%s>\n",
						Version, CatlogDefFileName
		);
		PrintMessage( str );

		while( --argc )		SetOptions( *++argv );
		if ( CatlogAutoRunSw == YES ) {
			int		storeLZHSw ;

			PrintMessage( "\n" );
			print_now_time();
			PrintMessage( "処理を開始します" );
			if ( DeleteOldFileSw == YES ) {
				storeLZHSw= StoreLZHSw;
				StoreLZHSw= YES;
			};
			CheckMain( InDir );
			print_now_time();
			PrintMessage( "処理を終了しました\n" );
			StoreLZHSw= storeLZHSw ;
		};

/****************** テスト ********************************************
		while( get_yesno( "\n非常に長いメッセージの場合はどうなるかというテストをしていますが、中断しますか？" ) == NO ) ;
****************** テスト ********************************************/

		/****************************************/
		/* END_sw == NO → GUI 入力モードに入る */
		/****************************************/
		if ( CatlogAutoEndSw == NO ) {
			MMI_ExecSystem();
			if ( DetailsSubSw == YES ) {
				if ( get_yesno( "\n DEF ファイルを書き出しますか？" ) == YES) {
					SaveDefFile( );		// ..\common.c
				};
				DetailsSubSw= NO;
			};
		};

		/*	ファイルダイアログ関係の終了処理		*/
		/*	メモリ開放			*/
		FDG_FreeFileDlg();
		FDG_RecovCurDir();		// カレントディレクトリを復帰する
	};

	MMI_Close() ;			/*	終了処理	*/
	SND_end() ;				/*	サウンドの終了	*/
	FM_ResetVector() ;		/*	致命的エラーハンドラの復帰	*/
}

int APL_init()
{
	extern MMIINIT	initDataABOUT ;
	extern MMIINIT	initDataDETAILS ;
	extern MMIINIT	initDataEXIT ;
	extern MMIINIT	initDataGETPATH ;
	extern MMIINIT	initDataHELP ;
	extern MMIINIT	initDataMESSAGE ;
	extern MMIINIT	initDataTOPMENU ;
	extern MMIINIT	initDataWINDOW ;
	extern MMIINIT	initDataSEARCHID ;

	extern	void	WindowInitial();

	register int	ret ;
	char	*ptr;

	MMICTRL	ctrl ;

	ctrl.page0 = 3 ;			/*	16色2画面に設定する		*/
	ctrl.page0 = 3 ;
	ctrl.writePage = 0 ;		/*	page0 を書き込みページ	*/
	ctrl.displayPage = 1 ;		/*	1画面表示				*/
	ctrl.priority = 0 ;
	ctrl.mode = 0 ;				/*	16色モードに設定する	*/
	ctrl.width = 512 ;			/*	画面モード3 では512		*/
	ctrl.size = 0 ;				/*	メモリの初期化は 		*/
	ctrl.ptr = NULL ;			/*	GUIﾗｲﾌﾞﾗﾘに任せる		*/
	ctrl.asize = 0 ;			/*	ｱﾌﾟﾘｹｰｼｮﾝで必要とする	*/
	ctrl.aptr = NULL ;			/*	初期メモリは無し		*/
	ctrl.fr.lupx = 0 ;			/*	画面の大きさを			*/
	ctrl.fr.lupy = 0 ;			/*  (0,0)-(639,479)			*/
	ctrl.fr.rdwx = 639 ;		/*	に設定する				*/
	ctrl.fr.rdwy = 479 ;
	ctrl.move = ctrl.fr ;		/*	移動枠の Y 座標を		*/
	ctrl.move.lupy = 22 ;		/*		22 に設定する		*/
//	ctrl.move.rdwy = 479 - 12 ;
	ctrl.white = 15 ;			/*	白色は   15 番			*/
	ctrl.black = 0 ;			/*	黒色は    0 番			*/
	ctrl.gray = 7 ;				/*	灰色は    7 番			*/
	ctrl.xor = 15 ;				/*	反転色は 15 番			*/

	FM_SetVector();				/*	致命的エラーハンドラの登録	*/
	SND_init(guiSndPtr);		/*	サウンドの初期化	*/

	/*	初期化処理	*/
	ptr= malloc( 500 * 0x200 );
	if ((ret = MMI_Open( &ctrl )) < 0)			return ret ;
	if ( ptr != NULL )		free( ptr );

	/*	EGB ワークアドレスの取得.	*/
	guiEgbPtr = MMI_GetEgbPtr() ;

	/*	ハイパ型部品の初期化			*/
	if ((ret = MMI_initHyper()) < 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_initListMenuL40()) < 0)		return ret ;

	/*	デフォルトビジュアルイフェクトの登録	*/
	MMI_SetUpVisualEffect() ;

	/*	デフォルトサウンドイフェクトの登録		*/
	MMI_SetUpSoundEffect() ;

	/*	背景データの初期化						*/

	/*	データの登録		*/
	if ((ret = MMI_Init(&initDataABOUT)) < 0)		return ret ;
	if ((ret = MMI_Init(&initDataDETAILS)) < 0)		return ret ;
	if ((ret = MMI_Init(&initDataEXIT)) < 0)		return ret ;
	if ((ret = MMI_Init(&initDataGETPATH)) < 0)		return ret ;
	if ((ret = MMI_Init(&initDataHELP)) < 0)		return ret ;
	if ((ret = MMI_Init(&initDataMESSAGE)) < 0)		return ret ;
	if ((ret = MMI_Init(&initDataTOPMENU)) < 0)		return ret ;
	if ((ret = MMI_Init(&initDataWINDOW)) < 0)		return ret ;
	if ((ret = MMI_Init(&initDataSEARCHID)) < 0)	return ret ;

	/*	背景を表示する							*/
	MMI_SendMessage(MMI_GetBaseObj(), MM_SHOW, 0) ;

	MMI_SetUpSDKMenu( mitemBarId[0] , -1 );	// ｻｲﾄﾞﾜｰｸﾒﾆｭｰを登録する

	WindowInitial();

	return NOERR ;
}

#include	<time.h>

static	int	kanamoji[]={
	/* 0xa0 - 0xaf */
	0x2121,	0x2123,	0x2156,	0x2157,	0x2122,	0x2126,
	0x2572,	0x2521,	0x2523,	0x2525,	0x2527,	0x2529,
	0x2563,	0x2565,	0x2567,	0x2543,
	/* 0xb0 - 0xbf */
	0x213d,	0x2522,	0x2524,	0x2526,	0x2528,	0x252a,
	0x252b,	0x252d,	0x252f,	0x2531,	0x2533,	0x2535,
	0x2537,	0x2539,	0x253b,	0x253d,
	/* 0xc0 - 0xcf */
	0x253f,	0x2541,	0x2544,	0x2546,	0x2548,	0x254a,
	0x254b,	0x254c,	0x254d,	0x254e,	0x254f,	0x2552,
	0x2555,	0x2558,	0x255b,	0x255e,
	/* 0xd0 - 0xdf */
	0x255f,	0x2560,	0x2561,	0x2562,	0x2564,	0x2566,
	0x2568,	0x2569,	0x256a,	0x256b,	0x256c,	0x256d,
	0x256f,	0x2573,	0x212b,	0x212c
};

static	int	asciimoji1[]={	/* !"#$%&'()*+,-./  */
	0x2121,	0x212a,	0x2149,	0x2174,	0x2170,	0x2173,
	0x2175,	0x212d,	0x214a,	0x214b,	0x2176,	0x215c,
	0x2124,	0x215d,	0x2125,	0x213f
};

static	int	asciimoji2[]={	/* :;<=>? */
	0x2127,	0x2128,	0x2163,	0x2161,	0x2164,	0x2129
};

static	int	asciimoji3[]={	/* [\]^_ */
	0x214c,	0x216f,	0x214d,	0x2130,	0x2132
};

static	int	asciimoji4[]={	/* {|}~ */
	0x2150,	0x2143,	0x2151,	0x2131
};

static	int	to_jis_zen( int c )	/* JIS の全角コードに変換する */
{
	if ( isalnum(c) ) return(0x2300+c);	/* '0'-'9' 'A'-'Z' 'a'-'z' */
	if ( (0x20<=c) && (c<=0x2f) ) return( asciimoji1[c-0x20] );
	if ( (0x3a<=c) && (c<=0x3f) ) return( asciimoji2[c-0x3a] );
	if ( (0x5b<=c) && (c<=0x5f) ) return( asciimoji3[c-0x5b] );
	if ( (0x7b<=c) && (c<=0x7f) ) return( asciimoji4[c-0x7b] );

	if ( c=='`' ) return(0x212e);
	if ( 0xa0<=c && c<=0xdf ) return( kanamoji[c-0xa0] );
	return(c);
}

static	int	to_shift_zen( int c )	/* SHIFT_JIS の全角コードに変換する */
{
	int	c0;

	if ( c == ' ' )		return( 0x08140 );
	if ( isalnum( c ) )	return( 0x0821f + c );
	c0=to_jis_zen(c);
	if ( c0!=c )		return( FNT_jisToSjis( c0 ) );
	return(c);
}

void	to_shift_zen_s( const char *src , char *targ )
{
	int	c;

	while ( ( c = *src++ ) != 0 ) {
		c = to_shift_zen( c );
		*targ++ = ( c >> 8 ) & 0xff;
		*targ++ = c & 0xff;
	};
	*targ = '\0';
}

static	void	print_now_time_sub( int time , char *str0 )
{
	char	str1[ 20 ] , str2[ 20 ];

	sprintf(str1,"%2d",time);
	to_shift_zen_s(str1,str2);	strcat(str,str2);	strcat(str,str0);
}

void	print_now_time()
{
	struct	tm		*timeptr;
			time_t	secsnow;

	/********************************/
	/* 現在の日付をシステムから知る */
	/********************************/
	time( &secsnow );					/* 現在の時刻 */
	timeptr = localtime( &secsnow );	/* 構造体に変換 */
	strcpy( str , "\n現在の時刻は１９" );
	print_now_time_sub( timeptr->tm_year    , "年" );
	print_now_time_sub( timeptr->tm_mon + 1 , "月" );
	print_now_time_sub( timeptr->tm_mday    , "日 " );
	print_now_time_sub( timeptr->tm_hour    , "時" );
	print_now_time_sub( timeptr->tm_min     , "分" );
	print_now_time_sub( timeptr->tm_sec     ,"秒です。");
	PrintMessage( str );
}

void	CATLOG_exit( int re )
{
	if ( DetailsSubSw == YES ) {
		if ( get_yesno( "\n DEF ファイルを書き出しますか？" ) == YES ) {
			SaveDefFile( );		// ..\common.c
		};
		DetailsSubSw= NO;
	};

	/**********************/
	/* メモリーを解放する */
	/**********************/

	// ファイルダイアログ関係の終了処理
		FDG_FreeFileDlg();		// メモリ開放
		FDG_RecovCurDir();		// カレントディレクトリを復帰する
	// 終了処理
		MMI_Close();
		SND_end();				// サウンドの終了
		FM_ResetVector();		// 致命的エラーハンドラの復帰
								// INT 23H/24H終了

	// CATLOG メッセージファイルのクローズ
	CloseCATLOGMessageFile();

	exit( re );
}

void	error_end()
{
	print_now_time();	showKakunin( );
	CATLOG_exit( 1 );
}

void	error_bug( const char *mes )
{
	char	str[ 512 ];

	sprintf( str , "\nCATLOG %s のバグ<%s>です。"
		// "すみませんが、詳しい状況を\nNIFTY ID:NAA02244までお知らせ下さい"
		,Version,mes
	);
	PrintMessage( str );	showKakunin( );
	error_end();
}

void	er_memory( const char *com )
{
	sprintf( str, "\n%s でメモリーが足りません", com );
	PrintMessage( str );	showKakunin( );
	error_end();
}

void	er_open( const char *file, int mode, char *mes )
{
	char	str1[ 512 ];

	sprintf( str1, "\n%s で can't open→<%s> ", mes, file);
	switch( mode ) {
		case 0:	strcat( str1, "(read)" );	break;
		case 1:	strcat( str1, "(write)" );	break;
		case 2:	strcat( str1, "(append)" );	break;
	};
	PrintMessage( str1 );	showKakunin( );
	error_end();
}

/* エラーコード　 */

struct	GUI_ERROR	{
			int		ErrNum;			// エラー番号
			char	*ErrMes;		// エラーメッセージ
};
static	struct	GUI_ERROR	gui_error_mes[] = {
	{	MEMORY_SHORTAGE,	"メモリ不足"						},

	{	EVENT_Q_FULL,		"イベントキューが一杯"				},
	{	EVENT_Q_EMPTY,		"イベントキケーが空"				},
	{	HASH_OVER_FLOW,		"ハッシュテーブル登録数超過"		},
	{	HASH_TABLE_OVER,	"該当するハッシュがない"			},

	{	UNUSED,				"未使用"							},
	{	UNTACHABLE,			"使用不可"							},
	{	OBJECT_NOT_FOUND,	"オブジェクトが存在しない"			},
	{	OUTSIDE,			"指定外である"						},

	{	ILLIGAL_CODE,		"未定義コード"						},
	{	ILLIGAL_EVENT,		"未定義イベント"					},
	{	ILLIGAL_FUNCTION,	"未定義関数"						},
	{	ILLIGAL_TYPE,		"未定義型"							},
	{	ILLIGAL_LOT,		"未定義ロット"						},
	{	ILLIGAL_ADDRESS,	"未定義アドレス"					},
	{	ILLIGAL_FONT,		"未定義フォント"					},
	{	ILLIGAL_SIZE,		"未定義サイズ"						},

	{	UNMATCH_SUPER_CLASS,	"スーパクラスに属さない"		},
	{	OBJLIST_SHORTAGE,		"オブジェクトが生成出来ない"	},
	{	METHOD_TBL_SHORTAGE,	"クラスが登録出来ない"			},
	{	UNUSED_OBJECT,			"未使用のオブジェクト"			},

	{	NOT_SUPPORT_KEY,		"キー処理不可"					},
	{	NOT_SUPPORT_MOVE,		"移動処理不可"					},
	{	NOT_SUPPORT_WAKE,		"ウェイク処理不可"				},
	{	NOT_SUPPORT_SLEEP,		"スリープ処理不可"				},
	{	NOT_ENOUGH_PAGE,		"ページ不足"					},

	{	CAN_NOT_SWAPOUT,		"スワップアウト出来ない"		},

	{	EXECEVNT_ERROR,			"イベントエラー"				},
	{	0,						NULL							}
};

void	gui_error( int err )
{
	int		i;

	if ( err == 0 )					return;
	for ( i=0; gui_error_mes[i].ErrNum!=0; i++ ) {
		if ( err== gui_error_mes[i].ErrNum ) {
			error_bug( gui_error_mes[i].ErrMes );
		};
	};
}

/* DIVIDE_END */
