/*<Header>==============================================================
*
*	WIZME / "MAIN.C"	WIZリンクソフト
*
*		[ EIN(tm) project : サンプルプログラム ]
*
*	COPYRIGHT  Nam  1995, All rights reserved.
*
*	配付・組込・改変・商利用すべて自由。ただし無保証っす
*
*-----------------------------------------------------------------------
*	V1.0L01α	95.08.02/Nam	プロトタイプ
*	V1.0L03β	95.08.09/Nam	メタタスク拡張メッセージ対応
*	V1.0L03γ	95.10.31/Nam	存在しないファイル名のチェック/DRAG&DROP対応
*</Header>==============================================================*/
#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<snd.h>
#include	<winb.h>
#include	<te.h>
#include	<fntb.h>
#include	<gui.h>
#include	<egb.h>
#include	<file_dlg.h>
//#include	<tifflib.h>
#include	<msdos.cf>
#include	<loader.h>
#include	<math.h>
#include	<io.h>
#include	<guidbg.h>
#include	<wgb.h>
// ※ ここまでが平均的に使用されるヘッダ

#include	<time.h>		// このサンプルでのみ必要
#include	<mos.h>			// このサンプルでのみ必要
#include	<pocket.h>			// このサンプルでのみ必要

#include	"..\ein\eintm.h"	// EIN(TM)関連ライブラリのヘッダ
#include	"..\eindd\eindd.h"	// DRAG&DROPライブラリのヘッダ


#define	ERROR	(-1)
#define	PSET	(0)

#define	DISPMODE_ICON	(0)
#define	DISPMODE_PANEL	(1)

#define	ID_msg1		(22)
#define	ID_msg2		(23)
#define	ID_fname	(7)

int		ID_ICON[4];					// アイコン部品のID
int		ID_IWIN[24];					// メモウィンドゥ部品のID
int		ID_T1[2] ;					// (〃 トグルアイコン部品ID)
int		ID_T2[2] ;
int		ID_T3[2] ;

char	fname[128]="";

int		dispMode=DISPMODE_PANEL;	// 表示状態(0:アイコン,1:メモウィンドゥ)
int		termMode=0;					// 通信モード(0:同報,1:同期)
int		convMode=0;					// 変換モード(0:無変換[CSV],1:変換[メモ])
int		fileMode=0;					// 入出力先(0:ファイル,1:ポケット)

/*= リジューム用設定=================================================*/
FRAME	RSM_ICONFR;
FRAME	RSM_IWINFR;
char	RSMID[]="%%% WizMe %%%";
char	RSMTITLE[]="ＷｉｚＭｅ  V0.1 L11";
char	RSMFNAME[128];
int		RSMDMODE=DISPMODE_ICON;
int		RSMTMODE=0;
int		RSMCMODE=0;
int		RSMFMODE=0;
/*===================================================================*/

void	( *GV_defIdleTask )();
int		GV_apliLot;

MMICTRL	mmic = {
				 SCREEN16 | SCREENIGNORE,		//	resolution
				 SCREENUNUSED,
				 0, SCREENAVAILABLE, 0,	//	write_page,display_page,priority
				 SCREENAVAILABLE,	//	mode
				 SCREENEXPAND,		//	vram_x
				 0,0,0,0,			//	size,*ptr,asize,*atpr
				 0,0,0,0,			//	frame
				 -32767,			//	move
				 -32767,
				  32767,
				  32767,
				 15,8,7,15			//	color
				} ;

/*===================================================================*/
/*  メインループ                                                     */
/*===================================================================*/
void main()
{
	extern int APL_init() ;
	extern int func_HIDE();

	int		kobj;

	// 初期化処理
	if (MMI_Open( &mmic ) == NOERR){
		// 二重起動のcheck
		if ( (kobj = MMI_CallMessage( MMI_GetApliId(), GM_QUERYID, QM_KIND, 1)) > NOERR ){
			MMI_CallMessage( MMI_GetApliId(), GM_SWITCH, FALSE, kobj );
		} else {
			// アイドルタスクに登録
			setIdleTask();
			// 初期化に成功すればメインループに
			if ( APL_init()==NOERR ){
				// メインループ
				MMI_ExecSystem();
			}
			// アイドルの解除
			resetIdleTask();
			// ウィンドゥ消去(※SHELLに消去させると遅いので)
			func_HIDE( ID_ICON[0] );
			func_HIDE( ID_IWIN[0] );
		}
	}
	// 終了処理
	MMI_Close() ;
}

/*===================================================================*/
/*  初期化処理                                                       */
/*===================================================================*/
int APL_init()
{
	extern	MMIINIT	initDataRES_ICON ;
	extern	MMIINIT	initDataRES_WIN ;

	extern	int ICONmaxId;
	extern	unsigned char *ICONTbl[];

	extern int	userFunc();			// イベントループ関数
	extern int	func_TGset();		// トグルボタン設定
	extern int	func_setFname();	// ファイル名設定

	HYPER	hyp;
	register int	ret ;

	// 
	GV_apliLot = TL_getLot() ;

	// GUI部品の初期化
	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_initToggleIconL40()) < 0)	//	トグルボタン型
		return ret;
	if ((ret = MMI_initIconL40()) < 0)			//	アイコン型
		return ret;
	if ((ret = MMI_initScrollBarL40()) < 0)		//	スクロールバー型
		return ret;
	if ((ret = MMI_initTextL40()) < 0)			//	テキスト型
		return ret;
	if ((ret = MMI_initMenuItemL40()) < 0)		//	メニューアイテム型
		return ret;
	if ((ret = MMI_initWindowL40()) < 0)		//	ウィンドウ型
		return ret;
//	if ((ret = MMI_initNumBoxL40()) < 0)		//	数値入力パネル型
//		return ret;
	/*	ファイルダイアログを使うときはさらにリストメニューの初期化も必要	*/
	/*	リストメニュー型部品の初期化			*/
	if ((ret = MMI_initListMenuL40()) < 0)
		return ret ;

	// リソースを登録
	if ((ret = MMI_Init(&initDataRES_ICON)) < 0)
		return ret ;
	if ((ret = MMI_Init(&initDataRES_WIN)) < 0)
		return ret ;

	// ユーザアイコンを登録
	MMI_SetIconTable( ICONTbl, ICONmaxId ) ;

	// GUI色をメニュー色に設定
	EIN_initGuiColor();

	/*----------------------------------------------------------------*/
	/*  リジューム読み込み (※のついた処理は必ず行ってください)       */
	/*----------------------------------------------------------------*/
	char	work[RSMWORKSIZE];	// リジュームマネージャのワークエリア
	char	buf[1024];
	char	*ptr;
	int		size, x, y, i, j;
	char	s[128];

	// ※リジュームマネージャの初期化(アプリのIDタグ登録)
	EIN_rsmInit( work, RSMID );
	// ※読み込みバッファ設定
	EIN_rsmBufSet( work, buf, 1023 );
	// ※リジューム情報読み込み
	size = EIN_rsmLoad( work );
	#ifdef DEBUG
	printf(" resume size(%d)\n",size);
	#endif
	if ( size > 0 ){
		// ICON表示位置
		if ( ((ptr = strstr(buf,"\nICON: ")) != NULL ) &&
			 (sscanf(ptr,"\nICON: %d %d\n", &x, &y) > 1 ) ){
			// 枠座標を得る
			MMI_SendMessage( ID_ICON[0], MM_GETHYPER, 1, &hyp );
			RSM_ICONFR.lupx = x;
			RSM_ICONFR.lupy = y;
			RSM_ICONFR.rdwx = x+(hyp.fr.rdwx-hyp.fr.lupx);
			RSM_ICONFR.rdwy = y+(hyp.fr.rdwy-hyp.fr.lupy);
			#ifdef DEBUG
			printf("ICON: move to (%d,%d)\n", x, y);
			#endif
			if ( x<-31 ){	x=0;	}
			if ( y<-31 ){	y=0;	}
			MMI_SendMessage( ID_ICON[0], MM_MOVE, 1, &RSM_ICONFR ) ;
		}
		// メモウィンドゥ表示位置
		if ( ((ptr = strstr(buf,"\nIWIN: ")) != NULL ) &&
			 (sscanf(ptr,"\nIWIN: %d %d\n", &x, &y) > 1 ) ){
			// 枠座標を得る
			MMI_SendMessage( ID_IWIN[0], MM_GETHYPER, 1, &hyp );
			RSM_IWINFR.lupx = x;
			RSM_IWINFR.lupy = y;
			RSM_IWINFR.rdwx = x+(hyp.fr.rdwx-hyp.fr.lupx);
			RSM_IWINFR.rdwy = y+(hyp.fr.rdwy-hyp.fr.lupy);
			#ifdef DEBUG
			printf("IWIN: move to (%d,%d)\n", x, y);
			#endif
			if ( x<-31 ){	x=0;	}
			if ( y<-31 ){	y=0;	}
			MMI_SendMessage( ID_IWIN[0], MM_MOVE, 1, &RSM_IWINFR ) ;
		}
		// 各種状態
		if ( ((ptr = strstr(buf,"\nMODE: ")) != NULL ) &&
			 (sscanf(ptr,"\nMODE: %d %d %d %d\n", &x, &y, &i, &j) > 3 ) ){
			dispMode = (x==0) ?DISPMODE_ICON :DISPMODE_PANEL;
			RSMDMODE = dispMode;
			termMode = (y==0) ?0 :1;
			RSMTMODE = termMode;
			convMode = (i==0) ?0 :1;
			RSMCMODE = convMode;
			fileMode = (j==0) ?0 :1;
			RSMFMODE = fileMode;
			#ifdef DEBUG
			printf("MODE: %d %d %d %d\n", x, y, i, j);
			#endif
		}
		// ファイル名を得る
		if ( ((ptr = strstr(buf,"\nFNAME: ")) != NULL ) &&
			 (sscanf(ptr,"\nFNAME: %s\n", &s) > 0 ) ){
			#ifdef DEBUG
			printf("FNAME: %s\n", s);
			#endif
			strcpy( RSMFNAME, s );
			strcpy( fname, s );
			MMI_SendMessage( ID_IWIN[ID_fname], MM_SETMSG, 1, fname );
		}
	}
	if ( strlen(fname) < 1 ){
		// ファイル名が存在しないのでポケットで入出力
		fileMode = 1;
		RSMFMODE = fileMode;
	}
	func_setFname();	// ファイル名をMSG部品に設定

	// ウィンドウ類をベース部品にATTACH
	if ( dispMode == DISPMODE_ICON ){
		MMI_SendMessage( ID_ICON[0], MM_ATTACH, 1, MMI_GetBaseObj() ) ;
	} else {
		MMI_SendMessage( ID_IWIN[0], MM_ATTACH, 1, MMI_GetBaseObj() ) ;
	}

	// トグルボタンの値を設定
	func_TGset( 0 );

	// スイッチャー対応関数の登録
	MMI_SendMessage( MMI_GetBaseObj(), MM_SETEXEC, 1, userFunc ) ;

	// タスクリストにタイトルを登録
	MMI_CallMessage( MMI_GetApliId(), GM_TITLE, (int)RSMTITLE, 0 ) ;

	//	背景を表示
	MMI_SendMessage( MMI_GetBaseObj(), MM_SHOW, 0 ) ;

	return NOERR ;
}

/*===================================================================*/
/* リジューム情報更新 (※がついた処理は必ず行って下さい)             */
/*===================================================================*/
void	SaveResumeFile()
{
	char	work[RSMWORKSIZE];
	char	buf[1024];
	char	aplpath[128];
	HYPER	hyp1, hyp2;
	register int ret;
	
	// 枠座標を得る
	MMI_SendMessage( ID_ICON[0], MM_GETHYPER, 1, &hyp1 );
	MMI_SendMessage( ID_IWIN[0],  MM_GETHYPER, 1, &hyp2 );
	
	// 移動していたらセーブ
	if ( (RSM_ICONFR.lupx  != hyp1.fr.lupx) ||
	     (RSM_ICONFR.lupy  != hyp1.fr.lupy) ||
	     (RSM_IWINFR.lupx  != hyp2.fr.lupx) ||
	     (RSM_IWINFR.lupy  != hyp2.fr.lupy) ||
		 (RSMDMODE         != dispMode)||		// 表示状態が違う
		 (RSMTMODE         != termMode)||		// 通信状態が違う
		 (RSMCMODE         != convMode)||		// 変換形式が違う
		 (RSMFMODE         != fileMode)||		// 入出力先が違う
	     (strcmp(RSMFNAME,fname)!=0) ){			// ファイル名が違う
		// ※マネージャ初期化
		EIN_rsmInit( work, RSMID );
		// ※バッファ設定(アプリ識別ID,更新時刻は自動設定されます)
		EIN_rsmBufSet( work, buf, 1023 );
		// ※アプリディレクトリ保存
		MMI_CallMessage( MMI_GetApliId(), GM_QUERYID, QM_PATH, (int)aplpath );
		EIN_rsmBufPrintf( work, "APLPATH: %s", aplpath );
		// ※アプリ名保存
		EIN_rsmBufPrintf( work, "TITLE:   %s", RSMTITLE );
		// ※コメント保存
		EIN_rsmBufCat( work, "COMMENT: ＃のＷｉｚと連携するっす。");
		// アイコン位置保存
		EIN_rsmBufPrintf( work, "ICON: %d %d", hyp1.fr.lupx, hyp1.fr.lupy );
		// メモウィンドゥ位置保存
		EIN_rsmBufPrintf( work, "IWIN: %d %d", hyp2.fr.lupx, hyp2.fr.lupy );
		// 各種モード保存
		EIN_rsmBufPrintf( work, "MODE: %d %d %d %d", dispMode, termMode, convMode, fileMode );
		// メモファイル名保存
		EIN_rsmBufPrintf( work, "FNAME: %s", fname );
		// ※バッファ終端(^A)設定
		EIN_rsmBufTail( work );
		// ※バッファをセーブ
		ret = EIN_rsmSave( work );
		#ifdef DEBUG
		printf(" resume save size(%d)   ptr:(%d,%d)\n",ret, hyp1.fr.lupx, hyp1.fr.lupy);
		#endif
	}
}

/*===================================================================*/
/*  イベントループ関数                                               */
/*===================================================================*/
int		userFunc( int apliId, int messId, int info, int data )
{
    // メタタスク拡張メッセージ ( GM_EXECUSER で、info で渡す )
    #define MTL_ICONIZE     0x8000      // アイコン化
    #define MTL_RESTORE     0x8001      // 復元
    #define MTL_MAXIMIZE    0x8002      // 最大化

	// 入力ウィンドゥ表示 & アイコン消去
	extern int	func_show();
	// 入力ウィンドゥ一時消去
	extern int	func_hide();

	register	int		ret ;

	ret = ILLEGAL_FUNCTION ;
	switch( messId ){
		//	他タスクからスイッチしてきた
		case GM_WAKE :
			break ;

		//	他タスクにスイッチする
		case GM_SLEEP :
			break ;

		//	画面変更前処理
		case GM_PRESCRCHG :
			break ;

		//	画面変更後処理
		case GM_POSTSCRCHG :
			break ;

		//	一時停止要求が出た
		case GM_PAUSE :
			break ;

		//	一時停止解除要求が出た
		case GM_CONTINUE :
			break ;

		//	終了要求が出た
		case GM_QUIT :
			// リジューム
			SaveResumeFile();
			//	正常終了
			MMI_SetHaltFlag( TRUE ) ;	//	イベントループを終了させるフラグ
			ret = NOERR ;
			break ;

		// メタタスク拡張メッセージ対応
		case GM_EXECUSER :				// メタタスクが送信する
			if ( info == MTL_ICONIZE ){
				// アイコン化メッセージだったら
				func_hide();
			} else if ( info == MTL_RESTORE ){
				// サイズ復元メッセージだったら
				func_show();
			} else if ( info == MTL_MAXIMIZE ){
				// 最大化メッセージだったら
				func_show();
			}
			ret = NOERR ;
			break;
		// DRAG&DROPメッセージ対応 '95.10.31
		case GM_SENDDATA :
			// プールからファイル名を受け取る
			if ( EINDD_receivePool( info, data, fname, NULL )== NOERR ){
				// ファイル名を設定して再表示
				func_showFname();
			}
			ret = NOERR ;
			break ;

	}

	return ret ;
}

/*===================================================================*/
/*  アイドルタスク関数(アイコン上に時計表示)                         */
/*===================================================================*/
void	userIdleTask()
{
	static int		btime = 0;
	register int	ntime;

	static int		optn = 0;
	register int	ptn;

	// アイコンモードで無いならなら何もしない
	if ( dispMode!=DISPMODE_ICON){
		return;
	}
	ntime = MOS_getTime();
	/* 前回から1800ms未満なら終了 */
	if ( abs(ntime - btime) < 120 ){
		return;
	}
	btime = ntime;
	
	ptn = 512 + 4 + rand()%10;
	// パターンが前と同じなら更新しない
	if ( ptn != optn ){
		MMI_SendMessage( ID_ICON[3], MM_SETSHAPE, 1, ptn);
		MMI_SendMessage( ID_ICON[3], MM_SHOW, 0 );
	}
	optn = ptn;
}

/*===================================================================*/
/*  アイドルタスクに登録                                             */
/*===================================================================*/
int		setIdleTask()
{
	void	( *idleTask )() ;

	/*	アイドル処理関数の取得	*/
	idleTask = MMI_GetIdleTaskFunc() ;

	/*	二重登録禁止チェック	*/
	if( idleTask != userIdleTask ){
		GV_defIdleTask = idleTask ;
		MMI_SetIdleTaskFunc( (void ((*)(void)))userIdleTask );
	}
	return NOERR;
}

/*===================================================================*/
/*  アイドルタスクから削除                                           */
/*===================================================================*/
int		resetIdleTask()
{
	void	( *IdleTask )() ;

	/*	アイドル処理関数の取得	*/
	IdleTask = MMI_GetIdleTaskFunc() ;

	/*	USER関数登録のチェック	*/
	if( IdleTask == userIdleTask ){
		MMI_SetIdleTaskFunc( GV_defIdleTask ) ;
		GV_defIdleTask = 0 ;
	}
	return NOERR;
}


/*===================================================================*/
/*  アイコン化されたウィンドゥの関数                                 */
/*===================================================================*/
int		func_ICON( int kobj, int messId, int ac, EVENT *pev, int trigger )
{
	HYPER	hyp;
	FRAME	fr;

	if( messId == MM_SHOW ){
		return ERROR;
	}
	// ※ ここでダブルクリックなら関数起動 / それ以外ならMOVE
	if( messId == MM_MOUSEON ){
		// 枠座標を得る
		MMI_SendMessage( kobj, MM_GETHYPER, 1, &hyp );
		fr = hyp.fr;
		do {
			MMI_iosense();
		} while( (MMI_GetEvnt((EVMOSUP|EVMOSDRAG), &pev)) < NOERR);
		if ( pev->what == EVMOSUP ){
			// ダブルクリックチェック
			if ( MMI_DoubleClickCheck(&fr, pev) != FALSE ){
				// 「アイコン→ウィンドゥ表示」
				func_show();
			}
			return NOERR;
		}
		// ダブルクリックでは無いのでMOVE処理へ
	}
	// エラーで抜けるとWINDOW部品本来の動作をしまっする♪
	return ERROR;
}

/*===================================================================*/
/*  部品表示(汎用)                                                   */
/*===================================================================*/
int	func_SHOW( int id )
{
	char		clp[EINCLIPSIZE];
	register int	ret;

	// アイコンをATTACHする
	ret = MMI_SendMessage( id, MM_ATTACH, 1, MMI_GetBaseObj() ) ;
	// アイコンを表示する
	EIN_clipOpen( clp );
	MMI_SendMessage( id, MM_SHOW, 0 ) ;
	MMI_SendMessage( id, MM_WAKE, 0 ) ;
	EIN_clipClose( clp );

	return ret;
}

/*===================================================================*/
/*  部品消去(汎用)                                                   */
/*===================================================================*/
int	func_HIDE( int id )
{
	MMI_SendMessage( id, MM_SLEEP, 0 );
	MMI_SendMessage( id, MM_ERASE, 0 );
	MMI_SendMessage( id, MM_DETACH, 0 );
	return NOERR;
}

/*===================================================================*/
/*  入力ウィンドゥ表示 & アイコン消去                                */
/*===================================================================*/
int	func_show()
{
	// 既にウィンドゥが表示されているなら何もしない
	if ( dispMode==DISPMODE_PANEL){
		return NOERR;
	}
	dispMode=DISPMODE_PANEL;

	// アイコンを消去する
	func_HIDE( ID_ICON[0] );
	// 入力ウィンドゥを表示する
	func_SHOW( ID_IWIN[0] );

	return NOERR;
}

/*===================================================================*/
/*  入力ウィンドゥ一時消去                                           */
/*===================================================================*/
int	func_hide()
{
	// パネルが表示されていないなら何もしない
	if ( dispMode!=DISPMODE_PANEL){
		return ERROR;
	}
	dispMode=DISPMODE_ICON;

	// 入力ウィンドゥを消去する
	func_HIDE( ID_IWIN[0] );
	// アイコンを表示
	func_SHOW( ID_ICON[0] );

	return NOERR;
}

int	func_close()
{
	// リジューム
	SaveResumeFile();
	//	正常終了
	MMI_SetHaltFlag( TRUE ) ;	//	イベントループを終了させるフラグ
	return NOERR;
}

// ファイル名/ポケット をMSG部品に設定
int		func_setFname()
{
	static char	str_pocket[]="(ポケット入出力モード)";

	// 入出力先(0:ファイル,1:ポケット)
	if ( fileMode == 0 ){
		MMI_SendMessage( ID_IWIN[ID_fname], MM_SETMSG, 1, fname );
	} else {
		MMI_SendMessage( ID_IWIN[ID_fname], MM_SETMSG, 1, str_pocket );
	}
	return NOERR;
}

// ファイル名部品を設定して再表示
int		func_showFname()
{
	char	str_erase[] ="                              ";
	MMI_SendMessage( ID_IWIN[ID_fname], MM_SETMSG, 1, str_erase );
	MMI_SendMessage( ID_IWIN[ID_fname], MM_SHOW, 0 );
	func_setFname();
	MMI_SendMessage( ID_IWIN[ID_fname], MM_SHOW, 0 );
	return NOERR;
}

// ファイルダイアログを表示してファイル名を取得
int	func_fname()
{
	unsigned int	InfSw;
	char			*ExtStr[]={"*.*", NULL};
	unsigned int	MSlctCnt;
	int				Atr, i, ret;
	char			path[128], filename[12];
	FILE	*fp;

retry:
	ret = FDG_InitFileDlg();
	if ( ret < 0 ){
		return ERROR;
	}
	FDG_SaveCurDir();
//	// Qドライブはパスする
//	FDG_SetPassDrv("Q");
	FDG_SetTitle( "ファイル名指定", "実行", "取消" );
	InfSw=(FDG_TEXT|FDG_FILEONLY|FDG_REDRAW|FDG_ALERT);
	// 初期パスを設定
	// (指定ファイルの存在をチェック  '95.10.31)
	if ( (strlen(fname)>0) &&
		 (fp = EIN_fopen( fname, "r" )) != (FILE *)NULL ){
		fclose(fp);
		EIN_fnameNonDirectory( fname, filename );
		EIN_fnameDirectory( fname, path );
		// パス名末尾の"￥"を削除する(FDGの仕様)
		i=strlen(path)-1;
		if (i>0){
			path[i] = 0;
		}
		#ifdef DEBUG
		printf("%s\n%s\n", filename, path);
		#endif
		FDG_SetFileText( filename );
		ret=FDG_DspFileDlg( MMI_GetBaseObj(), InfSw, path, ExtStr, &MSlctCnt );
	} else {
		// ファイルが無い場合
		ret=FDG_DspFileDlg( MMI_GetBaseObj(), InfSw, NULL, ExtStr, &MSlctCnt );
	}
	FDG_RecovCurDir();
	// 取り消されたら終了
	if ( ret != 1 ){
		FDG_FreeFileDlg();
		return ERROR;
	}
	FDG_GetPathName( fname, &Atr, 0 );
	FDG_FreeFileDlg();
	// 小文字は大文字に
	for ( i=0; i<strlen(fname); i++ ){
		fname[i] = toupper( (int)fname[i] );
	}
	// ファイル名を表示
	func_showFname();

	return NOERR;
}

// トグルアイコンの値を設定 (flag!=0 なら再描画)
int	func_TGset( int flag )
{
	register int	i;

	// 通信モード(0:同報,1:同期)
	if ( termMode == 0 ){
		MTL_setFlagObj(   ID_T1[0], MS_TOGGLE );
		MTL_resetFlagObj( ID_T1[1], ~MS_TOGGLE );
	} else {
		MTL_resetFlagObj( ID_T1[0], ~MS_TOGGLE );
		MTL_setFlagObj(   ID_T1[1], MS_TOGGLE );
	}
	// 変換モード(0:無変換[CSV],1:変換[メモ])
	if ( convMode == 0 ){
		MTL_setFlagObj(   ID_T2[0], MS_TOGGLE );
		MTL_resetFlagObj( ID_T2[1], ~MS_TOGGLE );
	} else {
		MTL_resetFlagObj( ID_T2[0], ~MS_TOGGLE );
		MTL_setFlagObj(   ID_T2[1], MS_TOGGLE );
	}
	// 入出力先(0:ファイル,1:ポケット)
	if ( fileMode == 0 ){
		MTL_setFlagObj(   ID_T3[0], MS_TOGGLE );
		MTL_resetFlagObj( ID_T3[1], ~MS_TOGGLE );
	} else {
		MTL_resetFlagObj( ID_T3[0], ~MS_TOGGLE );
		MTL_setFlagObj(   ID_T3[1], MS_TOGGLE );
	}
	if ( flag != 0 ){
		for ( i=0; i<2; i++ ){
			MMI_SendMessage( ID_T1[i], MM_SHOW, 0 );
			MMI_SendMessage( ID_T2[i], MM_SHOW, 0 );
			MMI_SendMessage( ID_T3[i], MM_SHOW, 0 );
		}
	}

	return NOERR;
}

int	func_TGicon( int kobj, int messId, int ac, EVENT *pev, int trigger )
{
	// 通信モード(0:同報)
	if ( kobj == ID_T1[0] ){
		termMode = 0;
		func_TGset( 1 );
		DM_showMsg( "光通信モードに設定しました", "(『光通信』キーで実行される非同期通信モード)" );
		return NOERR;
	}
	// 通信モード(1:同期)
	if ( kobj == ID_T1[1] ){
		termMode = 1;
		func_TGset( 1 );
		DM_showMsg( "オプション通信モードに設定しました", "(『メニュー』から実行する同期通信モード)" );
		return NOERR;
	}
	// 変換モード(0:無変換[CSV])
	if ( kobj == ID_T2[0] ){
		convMode = 0;
		func_TGset( 1 );
		DM_showMsg( "ＣＳＶモードに設定しました", "(通信するデータに手を加えません)" );
		return NOERR;
	}
	// 変換モード(1:変換[メモ])
	if ( kobj == ID_T2[1] ){
		convMode = 1;
		func_TGset( 1 );
		DM_showMsg( "テキスト変換モードに設定しました", "(テキスト<->CSV形式に相互変換します)" );
		return NOERR;
	}
	// 入出力先(0:ファイル)
	if ( kobj == ID_T3[0] ){
		fileMode = 0;
		func_TGset( 1 );
		func_showFname();	// ファイル名を表示
		DM_showMsg( "ファイルモードに設定しました", "(指定ファイル名にセーブ/ロードします)" );
		return NOERR;
	}
	// 入出力先(1:ポケット)
	if ( kobj == ID_T3[1] ){
		fileMode = 1;
		func_TGset( 1 );
		func_showFname();	// ファイル名を表示(ポケットモード)
		DM_showMsg( "ポケットモードに設定しました", "(ポケットにセーブ/ロードします)" );
		return NOERR;
	}

	return NOERR;
}

static char	str_erase[48]= "                                              ";

int	DM_setMsg( char *str1, char *str2 )
{
	if ( str1!=NULL){
		MMI_SendMessage( ID_IWIN[ID_msg1], MM_SETMSG, 1, str1 );
	} else {
		MMI_SendMessage( ID_IWIN[ID_msg1], MM_SETMSG, 1, str_erase );
	}
	if ( str2!=NULL){
		MMI_SendMessage( ID_IWIN[ID_msg2], MM_SETMSG, 1, str2 );
	} else {
		MMI_SendMessage( ID_IWIN[ID_msg2], MM_SETMSG, 1, str_erase );
	}
	return NOERR;
}

int	DM_showMsg( char *str1, char *str2 )
{
	if ( str1!=NULL){
		MMI_SendMessage( ID_IWIN[ID_msg1], MM_SETMSG, 1, str_erase );
		MMI_SendMessage( ID_IWIN[ID_msg1], MM_SHOW, 0 );
		MMI_SendMessage( ID_IWIN[ID_msg1], MM_SETMSG, 1, str1 );
	} else {
		MMI_SendMessage( ID_IWIN[ID_msg1], MM_SETMSG, 1, str_erase );
	}
	MMI_SendMessage( ID_IWIN[ID_msg1], MM_SHOW, 0 );

	if ( str2!=NULL){
		MMI_SendMessage( ID_IWIN[ID_msg2], MM_SETMSG, 1, str_erase );
		MMI_SendMessage( ID_IWIN[ID_msg2], MM_SHOW, 0 );
		MMI_SendMessage( ID_IWIN[ID_msg2], MM_SETMSG, 1, str2 );
	} else {
		MMI_SendMessage( ID_IWIN[ID_msg2], MM_SETMSG, 1, str_erase );
	}
	MMI_SendMessage( ID_IWIN[ID_msg2], MM_SHOW, 0 );

	return NOERR;
}

int	DM_dispCount( int flag )
{
	static char	str_msg[31];
	static int	cnt = 1;

	// 
	if ( flag < 0 ){
		cnt = 1;
		return NOERR;
	}
	if ( flag == 0 ){
		sprintf( str_msg, "[ %d block. ]", cnt );
	} else {
		sprintf( str_msg, "[ %d/%d block. ]", cnt, flag );
	}
	cnt++;
	// まず古い文字列を消去
	MMI_SendMessage( ID_IWIN[ID_msg2], MM_SETMSG, 1, str_erase );
	MMI_SendMessage( ID_IWIN[ID_msg2], MM_SHOW, 0 );
	MMI_SendMessage( ID_IWIN[ID_msg2], MM_SETMSG, 1, str_msg );
	MMI_SendMessage( ID_IWIN[ID_msg2], MM_SHOW, 0 );
	return NOERR;
}

extern int	IR_checkWC();
extern int	IR_syncRead();
extern int	IR_onsideRead();
extern int	IR_syncSend();
extern int	IR_onsideSend();
extern int	WL_purgeBuf();
extern int	WL_mallocBuf();
extern int	WL_shrinkBuf();
extern int	WL_putEOF();
extern int	WL_saveFile();
extern int	WL_savePocket();
extern int	WL_getFileSize();
extern int	WL_getPocketSize();
extern int	WL_loadFile();
extern int	WL_loadPocket();
extern int	WL_convText2Csv();
extern int	WL_convCsv2Text();
extern int	IR_waitBreak();

extern char	*termBuf;			// 送受信元データバッファ
extern int	termSize;			// 元データバッファ内データサイズ(bytes)

// 送信
int	func_send()
{
	int		ret, size;

	// ワイヤレスコマンダー接続チェック
	if ( IR_checkWC()!=NOERR ){
		return ERROR;
	}
	// 入出力先(0:ファイル,1:ポケット)
	if ( fileMode == 0 ){
		if ( strlen(fname)< 1 ){
			DM_showMsg( "※送信ファイル名を指定してね", NULL );
			return ERROR;
		}
		if ( (size = WL_getFileSize()) < 1 ){
			DM_showMsg( "※ファイルが見当たらないっす (T-T)", NULL );
			return ERROR;
		}
	} else {
		if ( (size = WL_getPocketSize()) < 1 ){
			DM_showMsg( "※ポケットのデータが読めんす (T-T)", NULL );
			return ERROR;
		}
	}
	// 読み込みバッファ取得 ( size+1 にするのは、後で0x1aを付加する時の為)
	if ( WL_mallocBuf( size + 1 ) != NOERR ){
		DM_showMsg( "メモリ不足っす (T-T)", NULL );
		return ERROR;
	}
	// 読み込みサイズ設定
	termSize = size;
	#ifdef DEBUG
	printf(" size = %d\n", size);
	#endif

	// 入出力先(0:ファイル,1:ポケット)
	if ( fileMode == 0 ){
		ret = WL_loadFile( termBuf, termSize );
	} else {
		ret = WL_loadPocket( termBuf, termSize );
	}
	if ( (ret != NOERR) || (termSize == 0) ){
		DM_showMsg( "送信データ読み込みに失敗したっす (T-T)", NULL );
		return ERROR;
	}

	// 変換モード(0:無変換[CSV],1:変換[メモ])
	if ( convMode != 0 ){
		// 本文から無地メモ形式に変換
		WL_convText2Csv( 1024 );
	}

	// マウス消去
	MG_mosDisp( 2 );
	// バッファ末尾に0x1aが無ければ追加する
	WL_putEOF();
	// 通信モード(0:光通信[同報],1:オプション[同期])
	if ( termMode == 0 ){
		ret = IR_onsideSend();
	} else {
		ret = IR_syncSend();
	}
	// マウス復帰
	MG_mosDisp( 3 );
	if ( ret != NOERR ){
		WL_purgeBuf();
		// この場合は各関数内でエラー表示しているので何も表示せず終了
		return ERROR;
	}
	DM_showMsg( "送信完了", NULL );
	// バッファを開放
	WL_purgeBuf();

	return NOERR;
}

// 受信
int	func_receive()
{
	int		ret;

	// ワイヤレスコマンダー接続チェック
	if ( IR_checkWC()!=NOERR ){
		return ERROR;
	}
	// 入出力先(0:ファイル,1:ポケット)
	if ( fileMode == 0 ){
		if ( strlen(fname)< 1 ){
			DM_showMsg( "※受信ファイル名を指定してね", NULL );
			return ERROR;
		}
	}
	// ファイルの上書きチェック
	if ( fileMode == 0 ){
		if ( WL_getFileSize() > 0 ){
			DM_showMsg( "※ファイルに上書きしてい〜のかなぁ?", "(右クリックで中止)" );
			if ( IR_waitBreak(3) != NOERR ){
				DM_showMsg( "中断したっす", NULL );
				return ERROR;
			}
		}
	}
	// 通信モード(0:光通信[同報],1:オプション[同期])
	if ( termMode == 0 ){
		ret = WL_mallocBuf( 1024*64 );
	} else {
		ret = WL_mallocBuf( 1024*256 );
	}
	if ( ret != NOERR ){
		DM_showMsg( "メモリ不足っす (T-T)", NULL );
		return ERROR;
	}
	// マウス消去
	MG_mosDisp( 2 );
	// 通信モード(0:光通信[同報],1:オプション[同期])
	if ( termMode == 0 ){
		ret = IR_onsideRead();
	} else {
		ret = IR_syncRead();
	}
	// マウス復帰
	MG_mosDisp( 3 );
	if ( (ret != NOERR) || (termSize == 0)  ){
		// この場合は各関数内でエラー表示しているので何もせず終了
		WL_purgeBuf();
		return ERROR;
	}
	DM_showMsg( "受信完了", NULL );

	#ifdef DEBUG
	printf("get %x, %d bytes\n", termBuf,termSize);
	#endif

	// バッファ末尾に0x1aが無ければ追加する
	WL_putEOF();
	// 元バッファをshrink
	WL_shrinkBuf();
	// 変換モード(0:無変換[CSV],1:変換[メモ])
	if ( convMode != 0 ){
		// 本文のみを摘出
		WL_convCsv2Text();

		// 元バッファをshrink
		WL_shrinkBuf();
	}
	// 入出力先(0:ファイル,1:ポケット)
	if ( fileMode == 0 ){
		ret = WL_saveFile( termBuf, termSize );
	} else {
		ret = WL_savePocket( termBuf, termSize );
	}
	if ( ret != NOERR ){
		DM_showMsg( "保存失敗 (T-T)", NULL );
		return ERROR;
	}
	// バッファを開放
	WL_purgeBuf();

	return NOERR;
}
