/* DIVIDE_START=display.c */
/*
	ＮＩＦＴＹのＬＯＧ整理				display.c
*/

#ifndef		TYPE_LINUX

#include	"catlog.h"

#include	<egb.h>
#include	<mos.h>

#define		TEST	1
#undef		TEST

static	void	display_ini();

static	char	para[ 64 ];
static	char	work[ EgbWorkSize ];

#ifdef	TEST
static	char	mwork[ MosWorkSize ];
static	int	mouse_ch,mouse_x,mouse_y;
#endif	/* TEST */

extern	short	cons_cur_lin;
extern	short	cons_cur_x;	/* 画面上のカーソルの x 座標 */
extern	short	cons_cur_y;	/* 画面上のカーソルの y 座標 */

struct WINDOW	{
			int	pag;
			int	x1,x2,y1,y2;	/* (x1,y1) - (x2,y2) の範囲 */
			int	fc,bc;		/* 文字の色 */
			short	cur_x,cur_y;	/* カーソルの位置 */
			char	win_mes[ 84 ];	/* 窓の表題 */
			char	file_name[ 128 ];
			char	*start , *end;	/* 表示文字列へのポインタ */
			char	*buf;
			char	*ptr;
			int	w_putch_sw;
};

#define	MAX_WINDOW	4

static	struct	WINDOW	window[ MAX_WINDOW ];

static	int	win_p[ MAX_WINDOW ];
static	int	win_used[ MAX_WINDOW ];
static	int	max_win = 0;
static	int	cur_win = 0;

#define	MAX_BUF	1024*64		/* 64 Kbytes */

static	int		CatlogMesFileSet = NO;
static	FILE	*CMFF = NULL;

static	void	w_putch_err( int num , int ch )
{
	catlog_mes_file_name_sw = NO;
	CatlogMesFileSet = NO;
	switch( num ) {
		case 1:	printf("\n<%s>がオープンできません。",CatlogMesFileName);
				break;
		case 2:	printf("\n<%2x>が書き出せません。",ch);
				break;
		default:	break;
	};
	exit( 1 );
}

void	catlog_mes_file_open()
{
	if ( catlog_mes_file_name_sw == NO ) return;	/* ﾌｧｲﾙに記録しない */

	if ( ( CMFF = fopen( CatlogMesFileName , "wb" ) ) == NULL ) {
		check_and_make_output_path( CatlogMesFileName );
		if ( ( CMFF = fopen( CatlogMesFileName , "wb" ) ) == NULL ) {
			w_putch_err( 1 , EOF );
		};
	};
	CatlogMesFileSet = YES;
	fprintf( CMFF, "ＣＡＴＬＯＧ %sです。\n<%s>で処理を行っています。",
		Version , file_name
	);
}

void	catlog_mes_file_close()
{
	if ( catlog_mes_file_name_sw == NO ) return;	/* ﾌｧｲﾙに記録しない */

	if ( CatlogMesFileSet == NO )	return;			/* 既にｸﾛｰｽﾞしている */

	fclose( CMFF );
	CatlogMesFileSet = NO;
}

void	catlog_mes_file_reopen()
{
	if ( catlog_mes_file_name_sw == NO ) return;	/* ﾌｧｲﾙに記録しない */

	if ( CatlogMesFileSet == YES )	return;			/* 二重にｵｰﾌﾟﾝ */

	if ( ( CMFF = fopen( CatlogMesFileName , "ab" ) ) == NULL ) {
		w_putch_err( 1 , 0 );
	};
	CatlogMesFileSet = YES;
}

static	int	CatlogMesFile0d = NO;

static	void	w_putch_sub( int ch )
{
	if ( catlog_mes_file_name_sw == NO ) return;	/* ﾌｧｲﾙに記録しない */

	if ( CatlogMesFileSet == NO )		return;		/* ﾌｧｲﾙはｸﾛｰｽﾞ中 */

	ch = ch & 0xff;
	if ( ch == 0x0d ) {
		if ( CatlogMesFile0d == YES )	return;
		CatlogMesFile0d = YES;
	} else {
		CatlogMesFile0d = NO;
		if ( ch == EOF )		return;
	};
	if ( fputc( ch , CMFF ) == EOF ) w_putch_err( 2 , ch );
}

void    w_putch( const int ch )
{
	char	*p1,*p2,*p3;

	w_putch_sub( ch );

	if ( window[ cur_win ].w_putch_sw == 0 ) return;

	p1 = p2 = window[ cur_win ].buf;
	p3 = window[ cur_win ].ptr;

	/* 行頭の処理 */
	if ( cons_cur_x == 0 ) {
		/* その文字が行頭になる */
	} else if ( cons_cur_x == 2 ) {
		if ( p3 - p1 > 1 ) {
			if ( iskanji( *(p3-2) ) ) {
				/* - 2 が行頭 */
			};
		};
	};

	if ( window[ cur_win ].w_putch_sw == 1 ) return;

	/* 以下、 buffer に保存する */
	*p3++ = ch;
	window[ cur_win ].ptr++;
	if ( window[ cur_win ].ptr - window[ cur_win ].buf >= MAX_BUF ) {
		while ( p1 < p3 ) {
			if ( *p1 == '\n' ) {	p1++;	break;	};
			p1++;
		};
		while ( p1 < p3 ) *p2++ = *p1++;
		window[ cur_win ].ptr = p2;
	};
}

static	void	w_open_sub( int win0 )
{
		int	fc,bc,pag;
		int	x1,x2,y1,y2;
		int	win;

	if ( win0 < 0 || MAX_WINDOW <= win0 ) return;

	window[ cur_win ].w_putch_sw = 0;

	win = win_p[ win0 ];

	pag = window[ win ].pag;
	x1 = window[ win ].x1;	y1 = window[ win ].y1;
	x2 = window[ win ].x2;	y2 = window[ win ].y2;
	fc = window[ win ].fc;	bc = window[ win ].bc;

	CON_close();				/* 現在の画面をクローズ */
	CON_open(pag,x1,y1,x2,y2,fc,bc);
	/* MES の表示 */
	cprintf("%s",window[ win ].win_mes);
	CON_close();
	CON_open(pag,x1,y1+16,x2,y2,fc,bc);

	EGB_color( work , 0 , 0x1f );
	EGB_writeMode( work , 0 );		/* write PSET mode */
	WORD( para + 0 ) = x1-1;
	WORD( para + 2 ) = y1-1;
	WORD( para + 4 ) = x1 + ( (x2-x1+1) & 0xfff8 );
	WORD( para + 6 ) = y1 + ( (y2-y1+1) & 0xfff0 );
	EGB_rectangle( work , para );
	WORD( para + 2 ) = y1 - 1 + 16;
	EGB_rectangle( work , para );

	if ( window[ win ].buf != NULL ) {
		x1 = *window[ win ].ptr;
		*window[ win ].ptr = '\0';
		puts( window[ win ].buf );
		*window[ win ].ptr = x1;
	};

	window[ cur_win ].w_putch_sw = 0;
}

static	int	w_open( int x1 , int y1 , int x2 ,int y2 , char *mes )
{
		int	fc,bc,pag;
		int	xs1,xs2,ys1;
		char	sub[ 84 ];

	pag = 1;	fc = 15;	bc = 9;

	/************************/
	/* 今の窓の値を保存する */
	/************************/
	if ( win_p[ cur_win ] >= 0 ) {
		window[win_p[cur_win]].cur_x = cons_cur_x;
		window[win_p[cur_win]].cur_y = cons_cur_y;
	};

	/********************************/
	/* 以下、新しい窓のデータの設定 */
	/********************************/
	for ( xs1 = 0 ; xs1 < MAX_WINDOW ; xs1++ ) {
		if ( win_used[ xs1 ] < 0 ) break;
	};
	if ( xs1 >= MAX_WINDOW ) {
		puts( "\nウィンドウを開けません" );	get_yesno();
		return( FALSE );
	};
	win_used[ xs1 ] = 1;		/* 使用中である */
	win_p[ max_win ] = xs1;
	cur_win = xs1;
	max_win++;

	window[ cur_win ].start = window[ cur_win ].end = NULL;
	window[ cur_win ].buf = window[ cur_win ].ptr = NULL;
	window[ cur_win ].pag = pag;
	window[ cur_win ].x1 = x1;	window[ cur_win ].y1 = y1;
	window[ cur_win ].x2 = x2;	window[ cur_win ].y2 = y2;
	window[ cur_win ].fc = fc;	window[ cur_win ].bc = bc;

	/**************/
	/* 表題の設定 */
	/**************/
	xs1 = ( x2 - x1 + 1 ) / 8 - 2;	/* 表示できる桁数 */
	if ( strlen( mes ) == 0 ) {	strcpy( str , "指定して下さい" );
	} else {
		if ( str != mes ) {	strcpy( str , mes );
		};
	};
	if ( xs1 < 1 ) strcpy( str , "" );	/* 表題は'Ｅ'だけ */

	str[ xs1 ] = '\0';		/* 表示できる桁数だけしか表示しない */

	xs2 = strlen( str );		/* 表題の文字数 */

	strcpy( sub , "Ｅ------------------------------------------------------------------------------" /* 80文字 */ );
	ys1 = ( xs1 - xs2 ) / 2 - ( xs1 - xs2 ) % 2;	/* 書き始めの位置 */
	if ( ys1 < 2 ) ys1 = 2;
	strncpy( sub + ys1 , str , xs2 );
	sub[ xs1 ] = '\0';
	strcpy( window[ cur_win ].win_mes , sub );

	w_open_sub( cur_win );

	return( TRUE );
}

void	replace_window( int x1 , int y1 )	/* 左上の座標を指定 */
{
	int	i,dx,dy;
	int	win;

	win = win_p[ cur_win ];

	dx = x1 - window[ win ].x1;
	dy = y1 - window[ win ].y1;

	window[ win ].x1 += dx;		window[ win ].y1 += dy;
	window[ win ].x2 += dx;		window[ win ].y2 += dy;

	if ( window[ win ].x1 < 0 )	window[ win ].x1 = 0;
	if ( window[ win ].y1 < 0 )	window[ win ].y1 = 0;
	if ( 639 < window[ win ].x2 )	window[ win ].x2 = 639;
	if ( 479 < window[ win ].y2 )	window[ win ].y2 = 479;

	/* 全部の窓を再度開ける */
	CON_close();
	CON_open(1,0,16,639,479,15,9);
	for ( i=0 ; i<max_win ; i++ ) {
		w_open_sub( i );
/*
		cons_cur_x = window[win_p[ i ]].cur_x;
		cons_cur_y = window[win_p[ i ]].cur_y;
*/
	};
}

#ifdef	TEST
static	void	w_close()
{
	int	i,j;

	win_used[ cur_win ] = win_p[ cur_win ] = -1;

	for ( i = 0 ; i < max_win ; i++ ) {
		if ( win_p[ i ] < 0 ) {
			for ( j=i+1 ; j<max_win ; j++ ) {
				win_p[j-1] = win_p[j];
			};
		};
	};

	if ( --max_win < 0 ) {
		puts("\nウィンドゥを閉じられません");	get_yesno();
		max_win = 0;	return;
	};

	/* 全部の窓を再度開ける */
	CON_close();
	CON_open(1,0,16,639,479,15,9);
	for ( i=0 ; i<max_win ; i++ ) {
		w_open_sub( i );
/*
		cons_cur_x = window[win_p[ i ]].cur_x;
		cons_cur_y = window[win_p[ i ]].cur_y;
*/
	};
}

static	void	get_com_xor( int y )
{
	MOS_disp( 0 );
	y = y * 16;
	y += window[win_p[ cur_win ]].y1;
	EGB_writeMode( work , 4 );	/* XOR */
	EGB_paintMode( work , 0x22 );
	EGB_color( work , 0 , 0x09 );
	WORD( para + 0 ) = window[win_p[ cur_win ]].x1;
	WORD( para + 2 ) = y;
	WORD( para + 4 ) = window[win_p[ cur_win ]].x2;
	WORD( para + 6 ) = y + 16;
	EGB_rectangle( work , para );
	EGB_writeMode( work , 0 );	/* PSET */
	EGB_paintMode( work , 0x02 );
	EGB_color( work , 0 , 0x1f );
	MOS_disp( 1 );
}

int	get_command( int x1 , int y1 , char *command[] )
{
	int	n,l,max,re,re0;
	int	x2,y2;

	/* コマンドの数を数える */
	n = max = 0;
	while ( ( l = strlen( command[n] ) ) != 0 ) {
		if ( max < l ) max = l;
		n++;
	};
	max++;
	if ( max < 18 ) max = 18;

	/* ウィンドウのオープン */
	x2 = x1 + max * 8;	y2 = y1 + (n+1) * 16;
	w_open( x1 , y1 , x2 , y2 , "選択して下さい" );

	y1 += 16;

	/* コマンドの表示 */
	for ( l=0 ; l<n ; l++ ) printf( "\n%s" , command[ l ] );

	/* マウスの指定 */
	MOS_disp( 1 );		/* マウスの表示 */
	mouse_ch = 1;	l = FALSE;	re = re0 = 0;
	while ( mouse_ch != 0 ) MOS_rdpos( &mouse_ch , &mouse_x , &mouse_y );
	forever {
		if ( l == TRUE && mouse_ch == 0 ) break;
		MOS_rdpos( &mouse_ch , &mouse_x , &mouse_y );
		if ( mouse_ch == 2 /* 右ボタン */ ) {
			re = 0;	break;
		};
		if ( mouse_ch == 1 /* 左ボタン */ ) {
			l = TRUE;
			if ( x1<=mouse_x && mouse_x<x2
			&&   y1<=mouse_y && mouse_y<y2
			) {	/* 窓の内側に入っている */
				re = ( mouse_y - y1 ) / 16 + 1;
				if ( re != re0 ) {
					if ( re0 != 0 ) get_com_xor( re0 );
					re0 = re;
					get_com_xor( re0 );
				};
			} else {
				re = 0;
			};
		};
	};
	MOS_disp( 0 );		/* マウスの消去 */
	if ( re0 != 0 ) get_com_xor( re0 );
	w_close();
	return ( re );
}

int	get_yesno_mouse( char *mes )
{
	int	re;
	int	x,y;

	x = 20 * 8;
	y = 5 * 16;

	/* ウィンドウのオープン */
	w_open( x , y , x + 26*2*8 , y+48 , mes );
	/* メッセージの表示 */
	puts("ＹＥＳなら左ボタン、ＮＯなら右ボタンを押して下さい。");
	/* get YES or NO */
	MOS_disp( 1 );
	mouse_ch = 1;
	while ( mouse_ch != 0 ) MOS_rdpos( &mouse_ch , &mouse_x , &mouse_y );
	forever {
		MOS_rdpos( &mouse_ch , &mouse_x , &mouse_y );
		if ( mouse_ch == 2 /* 右ボタン */ ) {
			re = NO;	break;
		};
		if ( mouse_ch == 1 /* 左ボタン */ ) {
			re = YES;	break;
		};
	};
	while ( mouse_ch != 0 ) MOS_rdpos( &mouse_ch , &mouse_x , &mouse_y );
	MOS_disp( 0 );
	/* ウィンドウのクローズ */
	w_close();
	return( re );
}

#endif	/* TEST */

#ifdef	TEST
static	char	*test[] = {
			"test1",
			"test2",
			"test3です",
			"test4だよ〜〜",
			"test5(おしまい)",
			""
};

static	int	CATLOG_edit()
{
	int	i , sw;

	CON_close();
	EGB_clearScreen( work );

	strcpy( str , "oricon g:\\downdata\\vz\\vzfmt.com display.c" );
	strcpy( str , "oricon" );
	strcpy( str , "console d:\\exe\\wink.exe display.c /TF:" );
	strcpy( str , "oricon d:\\exe\\wink.exe display.c /TF:" );

	if ( system( str ) < 0 ) {
		copen();
		printf("<%s>\nを実行できませんでした。\n",str);
		printf("処理を続けますか？");
		if ( get_yesno() == NO ) exit( 1 );
		sw = FALSE;
	} else {
		sw = TRUE;
	};

	/* 画面を消去するために以下を入れる */
	display_ini();

	/* 窓を全部開ける */
	for ( i=0 ; i<max_win ; i++ ) w_open_sub( i );

	return( sw );
}

#endif

static	int	display_mouse_sw = FALSE;

static	void	display_ini()
{
	EGB_init( work , EgbWorkSize );
	EGB_resolution( work , 0 , 3 );
	EGB_resolution( work , 1 , 3 );

	EGB_writePage( work , 1 );

	EGB_displayPage( work , 0 , 1 );
	EGB_displayStart( work , 0 , 0 , 0 );

	/******************/
	/* マウスの初期化 */
	/******************/
	/**************************************/
	/* exit() で MOS_end() を実行している */
	/**************************************/
/*
	if ( display_mouse_sw == FALSE ) {
		MOS_start( mwork , MosWorkSize );
		MOS_resolution( 0 , 3 );
		MOS_writePage( 0 );
		MOS_horizon( 0 , 639 );
		MOS_vertical( 0 , 479 );
		MOS_sysIcon(81,0,0,1);
		display_mouse_sw = TRUE;
	};
*/
	/*****************************************************************/
	/* 必要な時に MOS_disp( 1 ) を実行すること。常時は MOS_disp( 0 ) */
	/*****************************************************************/

/*
	CON_close();
	CON_open(1,0,0,639,480,0x1f,0);	CON_close();
	CON_open(0,0,0,639,480,0x1f,0);	CON_close();
*/

	sprintf( str , " CATLOG %s  by 山本(Yama-BBS SysOp) " , Version );

	w_open( 0 , 0 , 640 , 480 , str );
}

void	display_main()
{
	int	i;

	/* win_p[] win_used[] の値を初期化しておく */
	for( i=0 ; i<MAX_WINDOW ; i++ ) win_p[ i ] = win_used[ i ] = -1;

	display_ini();

}

#ifdef	TEST
void	display_dos_command(
		int	x1,	int	y1,
		int	x2,	int	y2,
		char	*command
) {
	w_open( x1 , y1 , x2 , y2 , command );
	window[ cur_win ].ptr = 
		window[ cur_win ].buf = (char *)malloc( MAX_BUF );
	if ( window[ cur_win ].buf == NULL ) {
		window[ cur_win ].w_putch_sw = 0;
	} else {
		window[ cur_win ].w_putch_sw = 2;
	};
	system( command );
	if ( window[ cur_win ].buf != NULL ) free( window[ cur_win ].buf );
	w_close();
}

void	display_file(
		int	x1,	int	y1,
		int	x2,	int	y2,
		char	*file_name
) {
	FILE	*fp;

	w_open( x1 , y1 , x2 , y2 , file_name );
	window[ cur_win ].ptr = 
		window[ cur_win ].buf = (char *)malloc( MAX_BUF );
	if ( window[ cur_win ].buf == NULL ) {
			window[ cur_win ].w_putch_sw = 0;
	} else {	window[ cur_win ].w_putch_sw = 1;
	};
	if ( (fp = fopen( file_name , "r" )) != NULL ) {
	};
	fclose( fp );
	if ( window[ cur_win ].buf != NULL ) free( window[ cur_win ].buf );
	w_close();
}

#endif	/* TEST */

void	CATLOG_color( int col )
{
	if ( col < 8 ) col += 8;
	ctblset( col , window[ win_p[ cur_win ] ].bc );
}

void	CATLOG_exit( int re )
{
	printf(" \nCATLOGを終了します" );
	if ( re != 0 ) {
		printf( " リターン・キーを押して下さい。" );
		get_yesno();
		putchar( '\n' );
	};

	if ( CatlogMesFileSet == YES ) fclose( CMFF );

	CON_close();
	EGB_init( work , EgbWorkSize );
/*
	EGB_displayPage( work , 0 , 1 );
	EGB_color( work , 1 , 0 );
	EGB_clearScreen( work );
	EGB_writePage( work , 0 );
	EGB_clearScreen( work );
	EGB_resolution( work , 0 , 1 );
	EGB_resolution( work , 1 , 1 );
*/
	if ( display_mouse_sw != FALSE ) MOS_end();
	_dos_exit( re );
}

#else		/* TYPE_LINUX */

void	catlog_mes_file_open(){};
void	catlog_mes_file_close(){};
void	catlog_mes_file_reopen(){};
void	display_main(){};
void	CATLOG_color( int col ){};
void    w_putch( const int ch ){};
void	CATLOG_exit( int re ){};

#endif		/* TYPE_LINUX */
/* DIVIDE_END */
