#include	<stdio.h>
#include    <ctype.h>
#include	<string.h>
#include	<egb.h>
#include	<fmc.h>
#include	"KEYBOARD.H"
#include	"CONSOL.H"
#include    "OAKLIB.H"
#include	"LEDIT.H"
#include	"GRAPHIC.H"


#define	MAX	81

void INKEY_start(void);			/* FEP on   */
void INKEY_end(void);			/* FEP off  */

/*---------------------------------------------------------------------------*/
unsigned int ec;			/* ｷｰﾎﾞｰﾄﾞｽｷｬﾝｺｰﾄﾞ */

static  char spc[MAX]="                                                                                ";
static  char swork[MAX];	/* 文字列編集 */
static  char ework[MAX];	/* 漢字判断用 */
static  char lwork[MAX];	/* 左側作業用 */
static  char rwork[MAX];	/* 右側作業用 */
static  char ch[2];			/* 入力文字格納用 */
static	int	insmode;		/* 挿入モードフラグ 0=上書き/1=挿入 */
static	int	curptr;			/* 文字ﾀｲﾌﾟ */
static  int maxlen;			/* 編集長さ */
static	int fcolor;			/* ﾌｫｱｸﾞﾗﾝﾄﾞ･ｶﾗｰ  */
static	int bcolor;			/* ﾊﾞｯｸｸﾞﾗﾝﾄﾞ･ｶﾗｰ  (OAK2で使用) */
int	xposit, yposit;			/* ｶｰｿﾙ座標(OAK2で使用) */
int	cur_x, cur_y;			/* OAK2用ｶｰｿﾙ座標 */

/*---------------------------------------------------------------------------*/

int inkey(int mode)
{
	int ch;

	ch = KAN_read(mode, &ec);
	return ((ch & 0xFF00) == 0xFF00 ? EOF:ch);
}

int getch(int mode)
{
	int ch;

	ch = KYB_read(mode, &ec);
	return ((ch & 0xFF00) == 0xFF00 ? EOF:ch);
}

void Beep(void)
{
	BPB_fixon();
}

void mid(char *str, int start, int len, char *midstr)
{
	int i, j;

	for ( i=0,j=start; i<len && str[i]!='\0' ; i++,j++ )
		midstr[i] = str[j];
	midstr[i]='\0';
}

void setctype(char *in, char *ex)
{
	while ( *in ) {
		if (iskanji(*in)) {
			in++;
			*ex++ = 2;
		}
			in++;
			*ex++ = 1;
	}
}

int LineEdit(int xp, int yp, char *str, int max, int f, int b)
{
	int i, j, exfg, key;

	strcpy(swork,str);
	maxlen=max;
	insmode=1;
	xposit=xp, cur_x=xposit*8;
	yposit=yp, cur_y=yposit*19;
	curptr=0;
	fcolor=f, bcolor=b;

	for (j=0; j<max; j++) ework[j]=lwork[j]=rwork[j]=' ';
	ework[max]='\0';
	lwork[max]='\0';
	rwork[max]='\0';

	strncat(swork, lwork, max-strlen(swork));
	cursor_off;
	color(fcolor, bcolor);
	put_str(xposit, yposit, swork);
	setctype(swork, ework);
	INKEY_start();

	exfg=1;
	do {

		*ch=0;
		*(ch+1)=0;

		cursor_off;
		cur_type(insmode);
		cursor_on;
		csr_posit(xposit, yposit);

		do {
			*ch = inkey(1);
		} while ( *ch == 0xFF );

		key  = ec >> 8;

		if ( *ch == 0x001B && key != 0x01 ) *(ch+1) = inkey(1);	/* no ESC */

		switch (key) {
		case KB_LEFT  :
				if ( ec & 0x04 ) {
					xposit=xp, cur_x=xposit*8;
					curptr=0;
				}
				else backward();
				break;
		case KB_RIGHT :
				if ( ec & 0x04 ) {
					xposit=xp+(max-1), cur_x=xposit*8;
					curptr=max-1;
					if ( ework[curptr - 1] == 2 ) {
						curptr--;
						xposit--;
						cur_x=xposit*8;
						csr_back();
					}
				}
				else forward();
				break;
		case KB_INS   : insmode = (insmode == 0); break;
		case KB_DEL   :
				if ( ec & 0x04 ) {
					mid(spc,0,max-curptr,rwork);
					color(fcolor, bcolor);
					put_str(xposit, yposit, rwork);
					for (i=curptr; i<max; i++) swork[i]=' ';
					setctype(swork, ework);
				}
				else delete();
				break;
		case KB_BS    :
				if (xposit != xp) {
					backward();
					delete();
				}
				break;
		case KB_PF01 :
		case KB_PF02 :
		case KB_PF03 :
		case KB_PF04 :
		case KB_PF05 :
		case KB_PF06 :
		case KB_PF07 :
		case KB_PF08 :
		case KB_PF09 :
		case KB_PF10 :
		case KB_PF11 :
		case KB_PF12 :
		case KB_PF13 :
		case KB_PF14 :
		case KB_PF15 :
		case KB_PF16 :
		case KB_PF17 :
		case KB_PF18 :
		case KB_PF19 :
		case KB_PF20 :
		case KB_BPAGE :
		case KB_NPAGE :
		case KB_UP    :
		case KB_DOWN  :
		case KB_HOME  :
		case KB_CR    :
		case KB_CR2   :
		case KB_CR3   :
				j=max;
				do {
					j--;
				} while ( swork[j] == ' ' );
				i=j;
				for (j=0; j<=i; j++) lwork[j]=swork[j];
				lwork[i+1]='\0';
				strcpy(str,lwork);
				exfg=0;
				break;
		case KB_ESC   :
		case KB_CAN   :
				str[0]='\0';
				exfg=0;
				break;
		default :
				if ( iskanji(*ch) ) {	/* 全角文字 */
					*(ch+1)=inkey(1);	/* 漢字第２バイト入力 */
					if ((insmode == 1 ) && ( swork[max - 2] != ' ' )) break;
										/* 挿入余地なし */
					if ( curptr == max-1 ) break;	/* 入力不可能 */
					else {
						char_set(1);
						break;
					}
				} else if (iscntrl(*ch)) break;	/* 制御文字ならば     */
				else char_set(0);
		}
	} while ( exfg );
	INKEY_end();
	cursor_off;
	return(key);
}

void char_set(int mode)
{
	int i;
	/* mode=0 ANK  mode=1 漢字 */

	cursor_off;
	if ( insmode == 1 ) {				/* 挿入 */
		if( swork[maxlen-1]!=' ') {
			cursor_on;
			return;
		}
		else {
		mid(swork, 0, curptr, lwork);
		mid(swork, curptr, maxlen-curptr-(1+mode), rwork);

		strcat(lwork, ch);
		strcat(lwork, rwork);
		color(fcolor, bcolor);
		put_str(xposit, yposit, ch);
		curptr++;
		xposit++;
		cur_x=xposit*8;
		csr_fwd();
			if ( mode ) {
				curptr++;
				xposit++;
				cur_x=xposit*8;
				csr_fwd();
			}
		color(fcolor, bcolor);
		put_str(xposit, yposit, rwork);
		}
	}										/* insmode==1 */
	else {
		strcpy(lwork, swork);
		if ( ework[curptr+mode] == 2 ) {		/* 次が漢字の時 */
			lwork[curptr+1+mode]=' ';
			put_chr(xposit+1+mode, yposit, ' ');
		}
		color(fcolor, bcolor);
		put_str(xposit, yposit, ch);
			for ( i=0; i<=mode; i++) {
				lwork[curptr]=ch[i];
				curptr++;
				xposit++;
				cur_x=xposit*8;
				csr_fwd();
			}
	}

	strcpy(swork, lwork);
	setctype(swork, ework);

	if ( curptr == maxlen ) {
		curptr--;
		xposit--;
		cur_x=xposit*8;
		csr_back();
	}
	csr_posit(xposit, yposit);
	cursor_on;
}

void backward()
{
	if ( curptr > 0 ) {
		if ( ework[curptr - 2] == 2 ) {
			curptr--;
			xposit--;
			cur_x=xposit*8;
			csr_back();
		}
		curptr--;
		xposit--;
		cur_x=xposit*8;
		csr_back();
	}
}

void forward()
{
	if ( curptr < maxlen-1 ) {
		if( ework[curptr] == 2 ) {
			if ( curptr == maxlen - 2 ) return;
			curptr++;
			xposit++;
			cur_x=xposit*8;
			csr_fwd();
		}
		curptr++;
		xposit++;
		cur_x=xposit*8;
		csr_fwd();
	}
}

void delete()
{
	int pos = ework[curptr];

	cursor_off;
	mid(swork, 0, curptr, lwork);
	mid(swork, curptr+pos, maxlen-(curptr+pos), rwork);
	strncat(rwork, spc, pos);
	strcat(lwork, rwork);
	strcpy(swork, lwork);
	color(fcolor, bcolor);
	put_str(xposit, yposit, rwork);
	cursor_on;
	csr_posit(xposit, yposit);
	setctype(swork, ework);
}

void csr_posit(int x, int y)
{
	char param[]={0x1B,'=',0,0,'\0'};

	param[2]=(char)y+0x20;
	param[3]=(char)x+0x20;
	cputs(param);
}

void put_str(int x,int y,char *buf)
{
	csr_posit(x,y);
	cputs(buf);
}

void put_chr(int x,int y,char chr)
{
	csr_posit(x,y);
	putch(chr);
}

