/* DIVIDE_START=window.c */
#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	<file_dlg.h>

#include	"var.h"

static int windowflg = 0 ;	/*	ウィンドウが何枚開いているかをしめす変数	*/

	int	WindowId = -1 ;
	int	ScrollBarId = -1 ;
	int	WindowTextId = -1 ;

int		textFunc();

/*	テキストのカット機能を使う			*/
int	TextCutFunc( )
{
	if( window[ActWindowId].windowId > 0 )
	{
		MMI_SendMessage( window[ActWindowId].textId , MM_CUT , 0 ) ;
		/*	テキストとスクロールバーの再設定		*/
		textFunc( ) ;
	}
	return NOERR ;
}

/*	テキストのコピー機能を使う			*/
int	TextCopyFunc( )
{
	if( window[ActWindowId].windowId > 0 )
	{
		MMI_SendMessage( window[ActWindowId].textId , MM_COPY , 0 ) ;
		/*	テキストとスクロールバーの再設定		*/
		textFunc( ) ;
	}
	return NOERR ;
}

/*	テキストのペースト機能を使う			*/
int	TextPasteFunc( )
{
	if( window[ActWindowId].windowId > 0 )
	{
		MMI_SendMessage( window[ActWindowId].textId , MM_PASTE , 0 ) ;
		/*	テキストとスクロールバーの再設定		*/
		textFunc( ) ;
	}
	return NOERR ;
}

/*	テキストのクリア機能を使う			*/
int	TextClearFunc( )
{
	if( window[ActWindowId].windowId > 0 )
	{
		MMI_SendMessage( window[ActWindowId].textId , MM_WAKE , 0 ) ;
		MMI_SendMessage( window[ActWindowId].textId , MM_CLEAR , 0 ) ;
		/*	テキストとスクロールバーの再設定		*/
		textFunc( ) ;
	}
	return NOERR ;
}

/*	ファイルダイアログ処理関数		*/
int fdlgFunc( char *PathName )
{
	unsigned int MSlctCnt ;	/*	選択されたファイル数(ここでは使っていない) */
	int	Atr ;
	int	ret , i ;
	char	f_name[ MAX_FILENAME_LEN ], *p;

	/*	ファイルダイアログを表示している間は		
			メニューを選択できないようにする 		*/
//	MTL_setAtrObj( menuBarId , MS_INACTIVEL40) ;

	/*	ウィンドウも選択不可とする		*/
	for( i = 0 ; i < TXTWIN ; i++ ) {
		if( window[i].windowId > 0 )
			MTL_setAtrObj( window[i].windowId , MS_INACTIVEL40) ;
	}

	strcpy( f_name, PathName );
	if ( *f_name == '\0' ) {			p= NULL;
	} else {
		p= last_yen( f_name );
		FDG_SetFileText( p + 1 );
		if ( p != f_name ) {
			if ( *(p-1) == ':' ) {		*++p = '\0';
			} else {					*p++ = '\0';
			};
		} else {
			// \\ がない場合
			if ( *(p+1) == ':' )		FDG_SetFileText( p + 2 );
		};
		p= f_name;
	};

	/*	ファイルダイアログの表示			*/
	ret=FDG_DspFileDlg(TopMenuHyperDialog,FDG_TEXT,p,ExtStrAll,&MSlctCnt);

	/*	"実行"が押されたならファイル名を取得する	*/
	if( ret )
	{
		FDG_GetPathName( PathName , &Atr , 0 ) ;
	}

	/*	選択不可だったものを元に戻す		*/
//	MTL_resetAtrObj( menuBarId , (~MS_INACTIVEL40)) ;

	for( i = 0 ; i < TXTWIN ; i++ )
	{
		if( window[i].windowId > 0 )
			MTL_resetAtrObj( window[i].windowId , (~MS_INACTIVEL40)) ;
	}

	return ret ;
}

/*	initDataTOPMENU:NULL:MJ_MITEML40の呼び出し関数	*/
/*	メニューの"読 込"が押された時に呼ばれる関数		*/
int	ReadFileFunc( )
{
	TEHandle	*th ;
	FILE	*fp ;
	int		tid , ptr ;
	char	*p;

	/*	ウィンドウをこれ以上開けないならアラートを表示してリターン		*/
	if( windowflg == TXTWIN )
	{
		SetLineHelpAlert( "ウィンドウをこれ以上開けません。" ) ;
		return NOERR ;
	}

	/*	ファイルダイアログで"取消"が押されたらこれ以下を実行しない	*/
	*FileName= '\0';
	if( fdlgFunc( FileName ) != 0 )
	{
		/*	ファイルをオープンできなかったらアラートを表示してリターン	*/
		if( (fp = fopen( FileName , "rb" )) == NULL ) 
		{
			SetLineHelpAlert( "ファイルをオープンできません。" ) ;
			return -1 ;
		}

		/*	新しいウィンドウを生成する		*/
		p= last_yen( FileName ) + 1;
		geneWindow( p, FileName );
		tid = window[ActWindowId].textId ;
		MMI_SendMessage( tid , MM_SETTEXT , 3 , NULL , 0 , FALSE );
		MMI_SendMessage( tid , MM_GETTEHANDLE , 1 , &th ) ;
		/*	マウスを時計の形にする		*/
		MG_PushPtr( 81 , &ptr ) ;

		/*	ファイルからstrに読み込んだものをテキストにセットする	*/
		while( fgets( str , LINE , fp ) != 0 )
		{
			MMI_SendMessage( tid , MM_SETTEXT , 3 , str , LINE , TRUE ) ;
		}

		/*	ファイルの先頭から表示させる	*/
		TE_Activate( th , 0 , 0 ) ;
		TE_dsplineJump( 0 ) ;
		MMI_SendMessage( window[ActWindowId].textId , MM_SHOW , 0 ) ;
		/*	マウスの形をもとに戻す		*/
		MG_PopPtr( ptr ) ;
		/*	テキストとスクロールバーの再設定		*/
		textFunc( ) ;
		/*	ファイルのクローズ		*/
		fclose( fp ) ;
	}

	/*	 ファイルを読み込まなかった時はアクティブだったテキストを
		アクティブに戻す										*/
	else
		MMI_SendMessage( window[ActWindowId].textId , MM_WAKE , 0 ) ;

	return NOERR ;
}

/*	メニューの"保 存"が押された時に呼ばれる関数		*/
/*	initDataTOPMENU:NULL:MJ_MITEML40の呼び出し関数	*/
int	WriteFileFunc( )
{
	FILE	*fp ;
	int		tid , ptr ;
	int		writeCnt, writeCntOld;

	/*	 ウィンドウが1枚も表示されていない時は何もしないでリターン	*/
	if( windowflg == 0 )			return NOERR ;

	strcpy( FileName, window[ActWindowId].FileName );

	PrintMessage( "\nファイル名：<" );
	PrintMessage( FileName );
	PrintMessage( ">の窓のデータを書き出します。" );

	/*	ファイルダイアログで"取消"が押されたらこれ以下を実行しない	*/
	if ( fdlgFunc( FileName ) != 0 ) {
		/*	ファイルをオープンできなかったらアラートを表示してリターン	*/
		if( (fp = fopen( FileName , "wb" )) == NULL ) 
		{
			SetLineHelpAlert( "ファイルをオープンできません。" ) ;
			return -1 ;
		}

		tid = window[ActWindowId].textId ;
		writeCntOld = MMI_SendMessage( tid, MM_GETTEXT, 3, NULL, 0, FALSE );
		writeCnt= MMI_SendMessage( tid , MM_GETTEXT , 3 , str , LINE , FALSE );
		/*	マウスを時計の形にする		*/
		MG_PushPtr( 81 , &ptr ) ;

		/*	ファイルへの書き込み		*/
		while( writeCntOld ) {
			fwrite( str , 1 , writeCntOld - writeCnt , fp );
			writeCntOld = writeCnt;
			writeCnt = MMI_SendMessage( tid, MM_GETTEXT, 3, str, LINE , TRUE );
		}
		/*	マウスの形をもとに戻す		*/
		MG_PopPtr( ptr ) ;
		/*	ファイルのクローズ		*/
		fclose( fp );
	}

	/*	アクティブだったテキストをアクティブに戻す		*/
	MMI_SendMessage( window[ActWindowId].textId , MM_WAKE , 0 ) ;

	return NOERR ;
}

/*	initDataMIWINDOW:textId:MJ_TEXTL40の呼び出し関数		*/
/*	この関数ではprt,maxを値が変わった時だけ書き換えている	*/
int		textFunc( )
{
	int			line ;		/*	テキストの全行数		*/
	int			prt , max , min , len , page ;
	int			nprt, nmax ;
	TEHandle	*textPtr ;

	MMI_SendMessage(window[ActWindowId].textId,MM_GETTEHANDLE,1,&textPtr);
	MMI_SendMessage( window[ActWindowId].vscrollId, MM_WAKE, 0 );
	MMI_SendMessage( window[ActWindowId].vscrollId, MM_GETSCROLL,
								 5, &prt, &min, &max, &len, &page) ;

	/*	スクロールバーの値を設定しなおす				*/
	TE_GetTextLine2( textPtr , &line ) ;
	nprt = textPtr->dspline + min ;
	nmax = (line < len) ? len - 1 : ( line - 1 ) ;

	/*	スクロールバーの値が変わった時だけスクロールバーを書き換える	*/
	/* つまり画面がスクロールした時又は､テキストの最大行数が変わった時	*/
	if ((nprt != prt)||(nmax != max))
	{
		nprt = ( nprt > nmax ) ? nmax : nprt ;
		MMI_SendMessage( window[ActWindowId].vscrollId , MM_SETSCROLL, 5 ,
				 nprt, min , nmax , len , page );
		/*	スクロールバーのインジケータを書き換える		*/
		MMI_SendMessage( window[ActWindowId].vscrollId , MM_SHOW , 0 ) ;
	};

	return NOERR ;
}

/*	initDataWINDOW:WindowId:MJ_WINDOWL40の呼び出し関数	*/
/*	initDataWINDOW:ScrollBarId:MJ_SCRLL40の呼び出し関数	*/
/*	initDataWINDOW:WindowTextId:MJ_TEXTL40の呼び出し関数	*/
int	WindowFunc( int kobj, int messId )
{
	int			act ;
	FRAME		org ;
	FRAME		size ;
	HYPER		winhyp , texthyp , vschyp  ;

	TEHandle	*th ;
	int			textLen ;
	int			line ;
	int			prt , max , min , len , page ;
	FRAME		fr ;

	/*	どのウィンドウから呼ばれたか調べる		*/
	for( act = 0 ; act < TXTWIN ; act ++ ) {
		if( window[act].windowId == kobj )			 break ;
	};

	if ( act == TXTWIN )	return NOERR ;

	/*	リサイズの時の処理		*/
	if( messId == MM_UPDATE )
	{
		MMI_SendMessage( kobj , MM_GETUSER , 2 , &org , &size ) ;
		MMI_SendMessage( kobj , MM_GETHYPER , 1 , &winhyp ) ;

	/*		ユーザー領域のリサイズ処理								*/
	/*	このアプリケーションではユーザー領域を使用していません		*/
		/* 	影とスクロールバーの分 内側によせる(SHADE_SIZE + BAR_SIZE)	*/
		/*	SHADE_SIZE : GUI.H参照		BAR_SIZE : SMP.H参照			*/
		org.rdwx = winhyp.fr.rdwx - 
				 ( SHADE_SIZE + BAR_SIZE ) - winhyp.fr.lupx - org.lupx ;
		org.rdwy =winhyp.fr.rdwy -
				   SHADE_SIZE - winhyp.fr.lupy - org.lupy ;
		MMI_SendMessage( kobj , MM_SETUSER, 2, &org, &size );

	/*		テキストのリサイズ処理									*/
		MMI_SendMessage( window[act].textId , MM_GETHYPER , 1 , &texthyp ) ;
		texthyp.fr.rdwx = texthyp.fr.lupx + org.rdwx ;
		texthyp.fr.rdwy = texthyp.fr.lupy + org.rdwy ;
		MMI_SendMessage( window[act].textId, MM_SETHYPER, 1, &texthyp ) ;

	/*		スクロールバーのリサイズ処理							*/
		MMI_SendMessage( window[act].vscrollId , MM_GETHYPER , 1, &vschyp ) ;
		vschyp.fr.lupx = texthyp.fr.rdwx + 1 ;
		vschyp.fr.rdwx = vschyp.fr.lupx + BAR_SIZE ;
		vschyp.fr.rdwy = texthyp.fr.rdwy - BAR_SIZE ;
		MMI_SendMessage( window[act].vscrollId , MM_SETHYPER , 1, &vschyp ) ;

	/*		スクロールバーとテキストを設定しなおす				*/
		/*	テキストの大きさが変わったのでハンドラを変更する	*/
		/* テキストをSHOWする前にハンドラを変えたいので行う処理	*/
		MMI_SendMessage(window[ActWindowId].textId,MM_GETTEHANDLE,1,&th);
		fr = texthyp.fr ;
		/*	ハンドラを変更するときは必ずDeactiveにする			*/
		TE_Deactivate() ;
		th->textRec = *(TE_RECT *)&fr ;

		MMI_SendMessage( window[ActWindowId].vscrollId, MM_GETSCROLL,
								 5, &prt, &min, &max, &len, &page) ;
		/*	ハンドラを変更したので引数を 0 , 1 でActiveにする	*/
		TE_Activate( th , 0 , 1 ) ;
		/*	テキストの全行数を求める	*/
		TE_GetTextLine( &line ) ;
		/*	テキストの表示行数を求める	*/
		textLen = setTextLenFunc() ;

		/*	テキストの表示行数が増えたときの処理		*/
		/*	表示行数が増えたとき下に空きがあるのにテキストが全部表示
		* されないことがあるので下の処理で表示開始行を変更して適正に
		* 表示されるようにする	*/
		/*	prt-min+textLen は表示最終行, lineはテキスト最終行	*/
		if( ( prt - min + textLen) > line )
			TE_dsplineJump( ((line - textLen)>0 ) ? (line - textLen) : 0 ) ;
/*
		if ( act == PrintMessageWindowId ) {
			int		line0;
			
			// カーソルを文章末に移動する
			TE_GetCrtOffset( &line0 );
			TE_GetTextLen( &line );
			if ( line0 < line )	TE_offsetJump( line );
		};
*/
		/*	スクロールバーの設定		*/
		/*	textFuncではprtとmaxしか変えないので他はここで設定する	*/
		/*	min,len,pageの書き換え		*/
		MMI_SendMessage( window[ActWindowId].vscrollId , MM_SETSCROLL, 5,
							prt, textLen - 1 , max , textLen , textLen/2 ) ;
		/*	prt,maxの書き換え			*/
		textFunc( ) ;
	}

	/*	消去の時の処理			*/
	else if( messId == MM_ERASE )
	{
		/*	ウィンドウの表示枚数を1枚減らす		*/
		windowflg-- ;
		/*	表示してないことをしめすためwindowIdを負にする	*/
		window[act].windowId = -(window[act].windowId) ;
		/*	テキストのワークを解放			*/
		MMI_SendMessage( window[act].textId, MM_SETTEXT, 3 , NULL, 0, FALSE ) ;

		if ( act == PrintMessageWindowId ) {
			PrintMessageWindowSw = FALSE;
		};
//			PrintMessageWindowSw = FALSE;
	}

	/*	アクティブになった時の処理		*/
	else if( messId == MM_WAKE )
	{
		ActWindowId = act ;

		/*	テキストをアクティブにする		*/
		MMI_SendMessage( window[act].textId , MM_WAKE , 0 ) ;
	}

	return NOERR ;
}

/*	スクロールバーが押されたときに呼ばれる関数			*/
/*	initDataWINDOW:ScrollBarId:MJ_SCRLL40の呼び出し関数	*/
int	vscrollFunc( )
{
	TEHandle	*textPtr;
	int		prt , max , min , len , page ;
	int		oprt ;

	/*	マウス消去	*/
	MG_mosDisp( 2 );

	MMI_SendMessage( window[ActWindowId].vscrollId, MM_GETSCROLL,
								 5, &prt, &min, &max, &len, &page) ;
	MMI_SendMessage( window[ActWindowId].textId, MM_GETTEHANDLE, 1, &textPtr);

	/*	スクロールバーの現在値は prt-min であり,スクロールバーが押される
	前と後の prt-min を比べることによりスクロールバーの動いた量を知る	*/

	/*	textPrt->dspline : 
		表示開始行(スクロールバーを動かす前の prt-min の値と同じ)	*/
	oprt = textPtr->dspline ;
	/*	スクロールバーの動いた値だけテキストをスクロール	*/
	TE_Activate( textPtr, 0 ,0 );
	TE_Scroll( ( (prt - min) >= oprt )? 1: 0, abs( prt - min - oprt ) );

	/*	マウス表示	*/
	MG_mosDisp( 3 );

	return NOERR ;
}


/*	画面に表示できるテキストの行数を計算する関数		*/
int setTextLenFunc()
{
	TEHandle	*textPtr ;
	HYPER		hyp ;

	MMI_SendMessage(window[ActWindowId].textId,MM_GETTEHANDLE,1,&textPtr);
	MMI_SendMessage( window[ActWindowId].textId , MM_GETHYPER , 1 , &hyp ) ;
	return	 (hyp.fr.rdwy - hyp.fr.lupy + 1)/
					(textPtr->txFont.sizeY + textPtr->lineHeight);
}

/*	メニューの"新規作成"が押された時に呼ばれる関数		*/
/*	initDataMIDESK:mitem1Id[0]:MJ_MITEML40の呼び出し関数	*/
int		geneWindow( char *winName, char *fileName )
{
	int			no ;
	int			wid;	/*	ウィンドウ			*/
	int			vsid;	/*	スクロールバー		*/
	int			tid;	/*	テキスト			*/
	int			textLen ;
	HYPER		winhyp, texthyp, vschyp ;
	FRAME		org ;
	FRAME		size ;

	/*	ウィンドウをこれ以上表示できないときはアラートを表示してリターン	*/
	if( windowflg == TXTWIN ) {
		PrintMessage( "これ以上ウィンドウを表示できません" );
		showKakunin( );
		return NOERR ;
	};

	/*	何番目のウィンドウが表示できるか調べる		*/
	for( no = 0 ; no < TXTWIN ; no++ )
		if( window[no].windowId < 0 )		break ;

	ActWindowId = no;
	window[no].windowId = -(window[no].windowId) ;
	wid = window[no].windowId ;
	tid = window[no].textId ;
	vsid = window[no].vscrollId ;
	strcpy( window[no].FileName, fileName );

	/*	2回目以降の表示の時,大きさをもとどおりにする	*/
	MMI_SendMessage( WindowId , MM_GETHYPER , 1 , &winhyp );
	MMI_SendMessage( wid , MM_SETHYPER , 1 , &winhyp ) ;
	MMI_SendMessage( WindowTextId , MM_GETHYPER , 1 , &texthyp );
	MMI_SendMessage( tid , MM_SETHYPER , 1 , &texthyp ) ;
	MMI_SendMessage( ScrollBarId , MM_GETHYPER , 1 , &vschyp );
	MMI_SendMessage( vsid , MM_SETHYPER , 1 , &vschyp ) ;
	MMI_SendMessage( WindowId , MM_GETUSER , 2 , &org , &size );
	MMI_SendMessage( wid , MM_SETUSER , 2 , &org , &size ) ;

	if ( no == 0 ) {
		// ウィンドウのサイズを変更する
		//	MMI_SendMessage( wid , MM_GETHYPER , 1 , &winhyp );
		winhyp.fr.lupx=   0;	winhyp.fr.lupy=  22;
		winhyp.fr.rdwx= 639;	winhyp.fr.rdwy= 479;
		MMI_SendMessage( wid , MM_SETHYPER , 1 , &winhyp ) ;

	/*		ユーザー領域のリサイズ処理								*/
	/*	このアプリケーションではユーザー領域を使用していません		*/
		/* 	影とスクロールバーの分 内側によせる(SHADE_SIZE + BAR_SIZE)	*/
		/*	SHADE_SIZE : GUI.H参照		BAR_SIZE : SMP.H参照			*/
		//	MMI_SendMessage( wid , MM_GETUSER , 2 , &org , &size );
		org.rdwx = winhyp.fr.rdwx - 
				 ( SHADE_SIZE + BAR_SIZE ) - winhyp.fr.lupx - org.lupx ;
		org.rdwy =winhyp.fr.rdwy -
				   SHADE_SIZE - winhyp.fr.lupy - org.lupy ;
		MMI_SendMessage( wid , MM_SETUSER, 2, &org, &size );

	/*		テキストのリサイズ処理									*/
		//	MMI_SendMessage( tid , MM_GETHYPER , 1 , &texthyp );
		texthyp.fr.lupx=   0 + SHADE_SIZE;
		texthyp.fr.lupy=  22 + BAR_SIZE;
		texthyp.fr.rdwx = texthyp.fr.lupx + org.rdwx ;
		texthyp.fr.rdwy = texthyp.fr.lupy + org.rdwy ;
		MMI_SendMessage( tid, MM_SETHYPER, 1, &texthyp ) ;

	/*		スクロールバーのリサイズ処理							*/
		//	MMI_SendMessage( vsid, MM_GETHYPER , 1, &vschyp ) ;
		vschyp.fr.lupx = texthyp.fr.rdwx + 1 ;
		vschyp.fr.lupy=  22 + BAR_SIZE;
		vschyp.fr.rdwx = vschyp.fr.lupx + BAR_SIZE ;
		vschyp.fr.rdwy = texthyp.fr.rdwy - BAR_SIZE ;
		MMI_SendMessage( vsid, MM_SETHYPER , 1, &vschyp ) ;
	};

	/*	それぞれの部品をくっつける		*/
	MMI_SendMessage( tid , MM_ATTACH , 1 , wid ) ;
	MMI_SendMessage( vsid , MM_ATTACH , 1 , wid );
	MMI_SendMessage( wid , MM_ATTACH , 1 , TopMenuHyperWin ) ;

	/*	ウィンドウの表示位置を重ならないようにずらす	*/
	MMI_SendMessage( wid , MM_MOVE, 2, no*12, no*12 );
	/*	ウィンドウのタイトルを設定する			*/
	StrCut( winName, 19 );		// ..\common_a.c
	strcpy( window[no].name , winName ) ;
	MMI_SendMessage( wid , MM_SETMSG , 1 , window[no].name ) ;

	/*	スクロールバーの値を設定する			*/
	/*	テキストの表示行数を求める	*/
	textLen = setTextLenFunc() ;
	MMI_SendMessage( vsid , MM_SETSCROLL , 5 , 
						textLen - 1, textLen - 1, textLen - 1,
							textLen , textLen/2 ) ; 

	/*	ウィンドウをアクティブにして表示する		*/
	MMI_SendMessage( wid , MM_WAKE , 0 ) ;
	MMI_SendMessage( wid , MM_SHOW , 0 ) ;

	/*	ウィンドウの表示枚数を1枚増やす		*/
	windowflg++ ;

	return NOERR ;
}

void	WindowInitial()
{
	int		i;

	/*	ウィンドウを生成する				*/
	for( i = 0 ; i < TXTWIN ; i++ ) {
		/*	ウィンドウ,テキスト,スクロールバーを生成する	*/
		window[i].windowId = -(MMI_SendMessage( WindowId , MM_NEW , 0)) ;
		window[i].vscrollId = MMI_SendMessage( ScrollBarId , MM_NEW , 0);
		window[i].textId = MMI_SendMessage( WindowTextId , MM_NEW , 0 );
	};
}

/* DIVIDE_END */
