/****************************************************************************/
/* TEXT WINDOW SYSTEM V1.50 Copyright (C) 1991,94 by AIG-SOFT */
/****************************************************************************/
/* noのウインドウをアクティブにしてから呼び出すこと */

#include <stdio.h>
#include <stdlib.h>
#include "defines.h"
#include "menu.h"
#include "win.h"
#include "amacro.h"

/* ウインドウ内部データ */
extern	_WIN_DATA *_awinp[WINMAX]; /* ウインドウ構造体アドレスバッファー */

/****************************************************************************/

static int col_set(int col,int num)
/* 色・属性設定 from エスケープシーケンス */
/* col=今の属性 , num=追加・変更する属性 */
{
	switch (num) {
		case 0:	return(TWHITE);
		case 1:	if (col&HLIGHT) return(col&(~HLIGHT));
			return(col|HLIGHT);
		case 7:	if (col&REVERSE) return(col&(~REVERSE));
			return(col|REVERSE);
		
		case 30:return(TBLACK);
		case 31:return(TCYAN);
		case 32:return(TYELLOW);
		case 33:return(TWHITE);
		
		case 34:return(HLIGHT|TBLACK);
		case 35:return(HLIGHT|TCYAN);
		case 36:return(HLIGHT|TYELLOW);
		case 37:return(HLIGHT|TWHITE);
		
		case 40:return(REVERSE|TBLACK);
		case 41:return(REVERSE|TCYAN);
		case 42:return(REVERSE|TYELLOW);
		case 43:return(REVERSE|TWHITE);
		
		case 44:return(HLIGHT|REVERSE|TBLACK);
		case 45:return(HLIGHT|REVERSE|TCYAN);
		case 46:return(HLIGHT|REVERSE|TYELLOW);
		case 47:return(HLIGHT|REVERSE|TWHITE);
	}
	return(col);
}

/*****************************************************************************/

static int esc_com(int no,unint c)
/* エスケープシーケンス処理 */
{
int i,num;
_WIN_DATA *win;
	win=_awinp[no];
	if (win->fesc==0) return(0);
	
	/* ESCシーケンス処理 */
	if (win->fesc==1) {
		if (c=='[') {
			win->num=0;
			win->num2=-1;
			win->fesc++;
			return(1);
		}
		win->fesc=0;
		return(0);
	}
	
	if (win->fesc==2) {
		if (c=='*') { /* ウインドウ内クリア */
			win_cls(no);
			win->fesc=0;
			return(1);
		}
		if (c=='s') { /* カーソル位置保存 */
			win->ccx=win->cx;
			win->ccy=win->cy;
			win->fesc=0;
			return(1);
		}
		if (c=='u') { /* カーソル位置復帰 */
			win->cx=win->ccx;
			win->cy=win->ccy;
			win->fesc=0;
			return(1);
		}
		if (c=='m') { /* カラー省略系 */
			win_color(no,col_set(col_set(win->col,0),win->num2));
			win->fesc=0;
			return(1);
		}
		if (c>='0' && c<='9') {
			win->fesc++;
			win->num=c-'0';
			return(1);
		}
		/* そのほかはそのまま表示 */
		win->fesc=0;
		return(0);
	}
	
	if (win->fesc>=3) {
		if (c>='0' && c<='9') {
			win->fesc++;
			win->num*=10;
			win->num+=(c-'0');
			return(1);
		}
		
		num=win->num;
		switch (c) {
			default:
				win->fesc=0;
				return(0);
			
			case ';': /* 継続 */
				win->fesc++;
				win->num2=num;
				win->num=0;
				return(1);
			
			case 'A': /* up */
				if (num==0) num=1;
				for (i=0;i<num;i++) {
					if (win->cy==0) break;
					win->cy--;
				}
				win_cursor(no,-1);
				break;
			
			case 'B': /* down */
				if (num==0) num=1;
				for (i=0;i<num;i++) {
					if (win->cy>=win->wy-2) break;
					win->cy++;
				}
				win_cursor(no,-1);
				break;
			
			case 'C': /* right */
				if (num==0) num=1;
				for (i=0;i<num;i++) {
					if (win->cx>=win->wx-2) break;
					win->cx++;
				}
				win_cursor(no,-1);
				break;
			
			case 'D': /* left */
				if (num==0) num=1;
				for (i=0;i<num;i++) {
					if (win->cx==0) break;
					win->cx--;
				}
				win_cursor(no,-1);
				break;
			
			case 'J': /* cls */
				if (num==0) win_ctrlz(no); /* カーソル以降クリア */
				if (num==2) win_cls(no);   /* 全画面クリア */
				break;
			
			case 'K':
				if (num==2) { /* この行先頭から消す */
					win_locate(no,0,win->cy);
					num=0;
				}
				if (num==0) { /* この行カーソル以下クリア */
					win_line_clear(no);
				}
				break;
			
			case 'm': /* color */
				win_color(no,col_set(col_set(win->col,num),win->num2));
				break;
			
			case 'H':
			case 'f': /* locate */
				win_locate(no,win->num2-1,num-1);
				break;
		}
		win->fesc=0;
		return(1);
	}
}

/*****************************************************************************/

void win_printc(int no,unint c)
/* １文字表示 */
{
int cx,cy,x,y,wx,wy;
_WIN_DATA *win;
	win=_awinp[no];
	EX_COLOR(win->col);
	
	x=win->x+1;
	y=win->y+1;
	wx=win->wx-2;
	wy=win->wy-2;
	cx=win->cx;
	cy=win->cy;
	
	switch (c) {
		/* 通常文字 */
		default:
			if (esc_com(no,c)) return; /* ｴｽｹｰﾌﾟｼｰｹﾝｽ */
			
			B_LOCATE(x+cx,y+cy);
			if (win->kanji1==0) { /* 漢字１バイト目処理 */
				if (check_kanji1(c)) {
					win->kanji1=c;
					return;
				}
			} else { /* 漢字１文字処理 */
				if (cx+2>wx) { /* 漢字行末自動改行処理 */
					win_inc_line(no);
					cy=win->cy;
					cx=0;
					B_LOCATE(x,y+cy);
				}
				EX_PUTC2(8,win->kanji1);
				win->kanji1=0;
				cx++;
			}
			EX_PUTC2(8,c);
			cx++;
			break;
		
		/* コントロールコード処理 */
		/* いくつかの処理が多重処理になっているから注意 */
		case ESC: /* エスケープシーケンスコード */
			win->fesc=1;
			win->kanji1=0;
			break;
		
		case 0x07: /* BELL */
			beep();
		case 0x7f: /* DEL */
		case 0x00: /* NULL */
			win->kanji1=0;
			return;
		
		case 0x08: /* BS */
		case 0x1d: /* LEFT */
			cx--;
			if (cx<0) {
				cx=wx-1;
				if (cy>0) cy--;
			}
			win->kanji1=0;
			break;
		
		case TAB: /* TAB */
			B_LOCATE(x+cx,y+cy);
			do {
				EX_PUTC2(8,' ');
				cx++; /* 出力文字桁数 */
				if (cx>=wx) break;
			} while ((cx%win->mdata->wx)!=0);
			win->kanji1=0;
			break;
		
		case '\n': /* LF */
			/*if (!win->fcrlf) {*//* 自然改行直後の改行を消す */
				win_inc_line(no);
				cy=win->cy;
				cx=0;
			/*}*/
			win->kanji1=0;
			break;
		
		case 0x0c: /* CLS */
			win_cls(no);
		case 0x0b: /* HOME */
			cy=0;
		case CR: /* CR */
			cx=0;
			win->kanji1=0;
			break;
		
		case 0x1c: /* RIGHT */
			cx++;
			win->kanji1=0;
			break; /* 後は通常文字と同じ */
		
		case 0x1e: /* UP */
			if (cy>0) cy--;
			win->kanji1=0;
			break;
		
		case 0x1f: /* DOWN */
			win_inc_line(no);
			cy=win->cy;
			win->kanji1=0;
			break;
	}
	
	if (cx>=wx) {
		win_inc_line(no);
		cy=win->cy;
		cx=0;
		win->fcrlf=1;
	} else win->fcrlf=0;
	
	B_LOCATE(x+cx,y+cy);
	win->cx=cx;
	win->cy=cy;
}

/*****************************************************************************/
