#include <sys/bios.h>
#include "fontcode.h"
#include "fontkey.h"


#define CURSOL 510  /*カーソル*/
#define CLEAR1 511 /*空白（SCREEN1用）*/
#define CLEAR2 512 /*空白（SCREEN2用*/


/*farポインタのoffset値からsegmentと重なる部分をsegmentに移動する*/
/*インクリメントで不都合が出た為使用（多分offsetがループしていた*/
#define SEGSFT(FPTR) MK_FP(FP_SEG(FPTR)+(FP_OFF(FPTR)>>4),FP_OFF(FPTR)&0x0f)


/*keyPressからkeyHitされたもののみ返す*/
int keyhitchk(int keyPress)
{
	int keyHit;
	static int prekey = 0;	/*一回前のkeyPress(保存するのでstatic)*/

	keyHit = (keyPress^prekey)&keyPress;	/*一回前とxorをとると変化したボタン   */
	prekey = keyPress;						/*のみ１になり　更にkeyPressとandを   */
											/*とると　押されたボタンのみ１となる  */
	return keyHit;							/*押されたボタンを返してkeyPressは保存*/
}


/*フォントコードからフォントデータ（８×８）を取得し配列に格納する*/
unsigned char *fontcode_to_fontdata(unsigned fontcode, unsigned char *font)
{
	unsigned char far *buf=NULL;
	unsigned char far *buf2;
	int i;

	text_get_fontdata(fontcode, buf);
	buf2 = SEGSFT(buf);	/*farポインタのインクリメントがうまくいかなかったので*/
	for(i=0;i<8;i++)	/*segmentとoffsetの重なり部分をsegmentによせた*/
	{
	font[i] = *buf2;
	buf2 += 1L;
	}

	return font;	/*fontの先頭アドレスを返す*/
}


/*フォントデータ（８×８）を回転*/
/* font:フォントデータの配列  dir:回転方向 0で右90度 1で左90度 2で180度*/
unsigned char *fontrotate(unsigned char *font, int dir)
{
	unsigned char tmp[8];
	int i;

	if(dir==0)	/*右回転*/
		for(i=0;i<8;i++)
		{
			tmp[i] = (font[7]<<i)&0x80;
			tmp[i] |= ((font[6]<<i)>>1)&0x40;
			tmp[i] |= ((font[5]<<i)>>2)&0x20;
			tmp[i] |= ((font[4]<<i)>>3)&0x10;
			tmp[i] |= ((font[3]<<i)>>4)&0x08;
			tmp[i] |= ((font[2]<<i)>>5)&0x04;
			tmp[i] |= ((font[1]<<i)>>6)&0x02;
			tmp[i] |= ((font[0]<<i)>>7)&0x01;
		}
	else if(dir==1)	/*左回転*/
		for(i=0;i<8;i++)
		{
			tmp[i] = (font[0]<<7-i)&0x80;
			tmp[i] |= ((font[1]<<7-i)>>1)&0x40;
			tmp[i] |= ((font[2]<<7-i)>>2)&0x20;
			tmp[i] |= ((font[3]<<7-i)>>3)&0x10;
			tmp[i] |= ((font[4]<<7-i)>>4)&0x08;
			tmp[i] |= ((font[5]<<7-i)>>5)&0x04;
			tmp[i] |= ((font[6]<<7-i)>>6)&0x02;
			tmp[i] |= ((font[7]<<7-i)>>7)&0x01;
		}
	else if(dir==2)	/*１８０度回転*/
		for(i=0;i<8;i++)
		{
			tmp[i] = (font[7-i]<<7)&0x80;
			tmp[i] |= (font[7-i]<<5)&0x40;
			tmp[i] |= (font[7-i]<<3)&0x20;
			tmp[i] |= (font[7-i]<<1)&0x10;
			tmp[i] |= (font[7-i]>>1)&0x08;
			tmp[i] |= (font[7-i]>>3)&0x04;
			tmp[i] |= (font[7-i]>>5)&0x02;
			tmp[i] |= (font[7-i]>>7)&0x01;
		}

	if(dir==0 || dir==1 || dir==2)
		for(i=0;i<8;i++)
			font[i] = tmp[i];	/*変換後 データを書き戻す*/

	return font;	/*fontの先頭アドレスを返す*/
}


/*キーの状態により　キャラクタ番号を返す（仮名モード用）*/
unsigned keySelect(int keyPress,int keyHit,int mode)
{
	unsigned code=CLEAR1;	/*デフォルトは空白*/


	keyPress &= 0x0f00;	/*keyPressはＹのみチェック*/
	keyHit &= 0x00f0;	/*keyHitはＸのみチェック*/

	switch (keyPress)
	{
		case KEY_Y2			: {
								if(keyHit == KEY_X2)
									code = JH_KA;
								else if(keyHit == KEY_X1)
									code = JH_KI;
								else if(keyHit == KEY_X4)
									code = JH_KU;
								else if(keyHit == KEY_X3)
									code = JH_KE;
								else if(keyHit == (KEY_X3|KEY_X4))
									code = JH_KO;
								else if(keyHit == 0)
									code = JH_KA;
							  } break;

		case KEY_Y2|KEY_Y3	: {
								if(keyHit == KEY_X2)
									code = JH_RA;
								else if(keyHit == KEY_X1)
									code = JH_RI;
								else if(keyHit == KEY_X4)
									code = JH_RU;
								else if(keyHit == KEY_X3)
									code = JH_RE;
								else if(keyHit == (KEY_X3|KEY_X4))
									code = JH_RO;
								else if(keyHit == 0)
									code = JH_RA;
							  } break;

		case KEY_Y3			: {
								if(keyHit == KEY_X2)
									code = JH_YA;
								else if(keyHit == KEY_X4)
									code = JH_YU;
								else if(keyHit == (KEY_X3|KEY_X4))
									code = JH_YO;
								else if(keyHit == 0)
									code = JH_YA;
							  } break;

		case KEY_Y3|KEY_Y4	: {
								if(keyHit == KEY_X2)
									code = JH_MA;
								else if(keyHit == KEY_X1)
									code = JH_MI;
								else if(keyHit == KEY_X4)
									code = JH_MU;
								else if(keyHit == KEY_X3)
									code = JH_ME;
								else if(keyHit == (KEY_X3|KEY_X4))
									code = JH_MO;
								else if(keyHit == 0)
									code = JH_MA;
							  } break;

		case KEY_Y4			: {
								if(keyHit == KEY_X2)
									code = JH_HA;
								else if(keyHit == KEY_X1)
									code = JH_HI;
								else if(keyHit == KEY_X4)
									code = JH_FU;
								else if(keyHit == KEY_X3)
									code = JH_HE;
								else if(keyHit == (KEY_X3|KEY_X4))
									code = JH_HO;
								else if(keyHit == 0)
									code = JH_HA;
							  } break;

		case KEY_Y4|KEY_Y1	: {
								if(keyHit == KEY_X2)
									code = JH_NA;
								else if(keyHit == KEY_X1)
									code = JH_NI;
								else if(keyHit == KEY_X4)
									code = JH_NU;
								else if(keyHit == KEY_X3)
									code = JH_NE;
								else if(keyHit == (KEY_X3|KEY_X4))
									code = JH_NO;
								else if(keyHit == 0)
									code = JH_NA;
							  } break;

		case KEY_Y1			: {
								if(keyHit == KEY_X2)
									code = JH_TA;
								else if(keyHit == KEY_X1)
									code = JH_TI;
								else if(keyHit == KEY_X4)
									code = JH_TU;
								else if(keyHit == KEY_X3)
									code = JH_TE;
								else if(keyHit == (KEY_X3|KEY_X4))
									code = JH_TO;
								else if(keyHit == 0)
									code = JH_TA;
							  } break;

		case KEY_Y1|KEY_Y2	: {
								if(keyHit == KEY_X2)
									code = JH_SA;
								else if(keyHit == KEY_X1)
									code = JH_SI;
								else if(keyHit == KEY_X4)
									code = JH_SU;
								else if(keyHit == KEY_X3)
									code = JH_SE;
								else if(keyHit == (KEY_X3|KEY_X4))
									code = JH_SO;
								else if(keyHit == 0)
									code = JH_SA;
							  } break;

		/*Ｙが押されてない*/
		case 0				: {
								if(keyHit == KEY_X2)
									code = JH_A;
								else if(keyHit == KEY_X1)
									code = JH_I;
								else if(keyHit == KEY_X4)
									code = JH_U;
								else if(keyHit == KEY_X3)
									code = JH_E;
								else if(keyHit == (KEY_X3|KEY_X4))
									code = JH_O;
								else if(keyHit == 0)
									code = CLEAR1;/*空白*/
							  } break;

		/*３つ以上押されている*/
		case KEY_Y1|KEY_Y2|KEY_Y3|KEY_Y4 :
		case KEY_Y1|KEY_Y2|KEY_Y3 :
		case KEY_Y2|KEY_Y3|KEY_Y4 :
		case KEY_Y1|KEY_Y2|KEY_Y4 :
		case KEY_Y1|KEY_Y3|KEY_Y4 :
							  {
								if(keyHit == KEY_X2)
									code = JH_WA;
								else if(keyHit == (KEY_X2|KEY_X3))
									code = JH_N;
								else if(keyHit == (KEY_X3|KEY_X4))
									code = JH_WO;
								else if(keyHit == 0)
									code = JH_WA;
							  } break;

		default : code = CURSOL;   /*カーソル*/
	}

	if(code==CURSOL)
		return CURSOL;
	else if(code==CLEAR1)
		return CLEAR1;
	else if(mode==1)
		return code+83;
	else
		return code;
}

/*数字モード用キーセレクト*/
unsigned numkeySelect(int keyPress,int keyHit)
{
	unsigned code=CLEAR1;  /*デフォルトは空白*/

	keyPress &= 0x0f00; /*keyPressはＹのみチェック*/
	keyHit &= 0x00f0;   /*keyHitはＸのみチェック*/

	switch (keyPress)
	{
		case KEY_Y2			:	code = JN_ONE;	break;

		case KEY_Y2|KEY_Y1	:	code = JN_TWO;	break;

		case KEY_Y1			:	code = JN_THREE;	break;

		case KEY_Y1|KEY_Y4	:	code = JN_FOUR;	break;

		case KEY_Y4			:	code = JN_FIVE;	break;

		case KEY_Y4|KEY_Y3	:	code = JN_SIX;	break;

		case KEY_Y3			:	code = JN_SEVEN;	break;

		case KEY_Y3|KEY_Y2	:	code = JN_EIGHT;	break;

		/*Ｙが押されてない*/
		case 0				: {
								if(keyHit&0x0f0)
									code = JN_ZERO;
								else
									code = CLEAR1;	/*空白*/
							  } break;
		/*３つ以上押されていたら９*/
		case KEY_Y1|KEY_Y2|KEY_Y3|KEY_Y4 :
		case KEY_Y1|KEY_Y2|KEY_Y3 :
		case KEY_Y2|KEY_Y3|KEY_Y4 :
		case KEY_Y1|KEY_Y2|KEY_Y4 :
		case KEY_Y1|KEY_Y3|KEY_Y4 :	code = JN_NINE;	break;

		default : code = CLEAR1;	/*カーソル*/
	}

	if((keyHit == (KEY_X1|KEY_X2))||(keyHit == (KEY_X1|KEY_X4)))
		code = CLEAR1;

	return code;
}


/*仮名が小さく（大きく）できるかどうか*/
int isableSmall(int line, int num)
{
	int code;
	
	code = screen_get_char1(SCREEN1, 27-line, num);
	
	switch(code)
	{
		case JH_A: case JH_I: case JH_U: case JH_E: case JH_O: case JH_TU:
		case JH_YA: case JH_YU: case JH_YO:
		case JK_A: case JK_I: case JK_U: case JK_E: case JK_O: case JK_TU:
		case JK_YA: case JK_YU: case JK_YO:
											{
												return 1;
											} break;

		case JH_LA: case JH_LI: case JH_LU: case JH_LE: case JH_LO: case JH_LTU:
		case JH_LYA: case JH_LYU: case JH_LYO:
		case JK_LA: case JK_LI: case JK_LU: case JK_LE: case JK_LO: case JK_LTU:
		case JK_LYA: case JK_LYU: case JK_LYO:
											{
												return 2;
											} break;

		default : return 0; break;
	}
}


/*仮名の大小を変える*/
int changeSmall(int line, int num)
{
	int code;
	int far *_code;

	code = screen_get_char1(SCREEN1, 27-line, num);
	_code = &code;

	if(isableSmall(line, num)==1)
	{
		code--;
		screen_set_char(SCREEN1, 27-line, num, 1, 1, _code);
		return 1;
	}
	else if(isableSmall(line, num)==2)
	{
		code++;
		screen_set_char(SCREEN1, 27-line, num, 1, 1, _code);
		return 1;
	}

	return 0;
}


/*仮名に濁点がつくかどうか*/
int isableDaku(int line, int num)
{
	int code;
	
	code = screen_get_char1(SCREEN1, 27-line, num);
	
	switch(code)
	{
		case JH_KA: case JH_KI: case JH_KU: case JH_KE: case JH_KO:
		case JH_SA: case JH_SI: case JH_SU: case JH_SE: case JH_SO:
		case JH_TA: case JH_TI: case JH_TU: case JH_TE: case JH_TO:
		case JH_HA: case JH_HI: case JH_FU: case JH_HE: case JH_HO:
		case JK_KA: case JK_KI: case JK_KU: case JK_KE: case JK_KO:
		case JK_SA: case JK_SI: case JK_SU: case JK_SE: case JK_SO:
		case JK_TA: case JK_TI: case JK_TU: case JK_TE: case JK_TO:
		case JK_HA: case JK_HI: case JK_FU: case JK_HE: case JK_HO:
		case JK_U:
					{
						return 1;
					} break;

		case JH_GA: case JH_GI: case JH_GU: case JH_GE: case JH_GO:
		case JH_ZA: case JH_JI: case JH_ZU: case JH_ZE: case JH_ZO:
		case JH_DA: case JH_DI: case JH_DU: case JH_DE: case JH_DO:
		case JH_BA: case JH_BI: case JH_BU: case JH_BE: case JH_BO:
		case JK_GA: case JK_GI: case JK_GU: case JK_GE: case JK_GO:
		case JK_ZA: case JK_JI: case JK_ZU: case JK_ZE: case JK_ZO:
		case JK_DA: case JK_DI: case JK_DU: case JK_DE: case JK_DO:
		case JK_BA: case JK_BI: case JK_BU: case JK_BE: case JK_BO:
		case JK_VU:
					{
						return 2;
					} break;

		default : return 0; break;
	}
}


/*仮名の濁点有り無しを変更*/
int changeDaku(int line, int num)
{
	int code;
	int far *_code;
	
	code = screen_get_char1(SCREEN1, 27-line, num);
	_code = &code;

	if(isableDaku(line, num)==1)
	{
		if(code==JK_U)
			code = JK_VU;
		else
			code++;
		screen_set_char(SCREEN1, 27-line, num, 1, 1, _code);
		return 1;
	}
	else if(isableDaku(line, num)==2)
	{
		if(code==JK_VU)
			code = JK_U;
		else
			code--;
		screen_set_char(SCREEN1, 27-line, num, 1, 1, _code);
		return 1;
	}

	return 0;
}


/*仮名に半濁点がつくかどうか*/
int isableHandaku(int line, int num)
{
	int code;
	
	code = screen_get_char1(SCREEN1, 27-line, num);
	
	switch(code)
	{
		case JH_HA: case JH_HI: case JH_FU: case JH_HE: case JH_HO:
		case JK_HA: case JK_HI: case JK_FU: case JK_HE: case JK_HO:
			{
				return 1;
			} break;

		case JH_PA: case JH_PI: case JH_PU: case JH_PE: case JH_PO:
		case JK_PA: case JK_PI: case JK_PU: case JK_PE: case JK_PO:
			{
				return 2;
			} break;

		default : return 0; break;
	}
}


/*仮名の半濁点有り無しを変更*/
int changeHandaku(int line, int num)
{
	int code;
	int far *_code;
	
	code = screen_get_char1(SCREEN1, 27-line, num);
	_code = &code;

	if(isableHandaku(line, num)==1)
	{
		code += 2;
		screen_set_char(SCREEN1, 27-line, num, 1, 1, _code);
		return 1;
	}
	else if(isableHandaku(line, num)==2)
	{
		code -= 2;
		screen_set_char(SCREEN1, 27-line, num, 1, 1, _code);
		return 1;
	}

	return 0;
}

