/* -*- mode: C; mode: fold; -*- */
/* 
 * Copyright (c) 1995, 1998 Kazuhisa Yoshino (k-yosino@inatori.netsweb.ne.jp)
 * All rights reserved.
 */

#include "config.h"
#include "jed-feat.h"

#include <sys/types.h>
#include "buffer.h"
#include "sysdep.h"
#include "kanji.h"


/*{{{ Global Variables */

int	file_kanjicode_detect = FALSE;

SLang_Name_Type *jed_keyboard_input_hook = NULL;

/*}}}*/

int is_kanji_jedcode() /*{{{*/
{
   return	kSLis_kanji_code();
}

/*}}}*/


unsigned char *
KanjiCodeConv(unsigned char *src, int *siz, int incode, int outcode, int KanaChgFlag) /*{{{*/
{
   return kSLCodeConv(src, siz, incode, outcode, KanaChgFlag);

}

/*}}}*/

int is_kanji_filecode(char *filename) /*{{{*/
{
   int	code;
   
   if(is_kanji_jedcode())
     {
        if(file_kanjicode_detect)
          {
               code = kcode_detect(filename);
          }
        else   code = kSLfile_code;
     }
   else code = ASCII;

   return code;
}

/*}}}*/

void set_kanji_file_code(int *code) /*{{{*/
{
   if(*code < ASCII || SJIS < *code)	CBuf->kfcode = ASCII;
   else	CBuf->kfcode = *code;
}

/*}}}*/

void rot_kanji_file_code() /*{{{*/
{
   CBuf->kfcode++;
   if(BINARY < CBuf->kfcode)	CBuf->kfcode = ASCII;
}

/*}}}*/

int get_kanji_file_code() /*{{{*/
{
   return CBuf->kfcode;
}

/*}}}*/


#define	BUFSIZE	10
#define	ISMARU(c)	(202 <= (c & 0xff) && (c & 0xff) <= 206)
#define ISNIGORI(c)	((182 <= (c & 0xff) && (c & 0xff) <= 196)\
			|| (202 <= (c & 0xff) && (c & 0xff) <= 206)\
			|| (179 == (c & 0xff)))


/* getkey function for KANJI
 * input: EUC
 * buffer code SJIS
 */
int ja_EUC_to_SJIS_getkey () /*{{{*/
{
   static unsigned char buf[BUFSIZE], dst[BUFSIZE];
   int jp_kana_flag = 0;
   int	ret;
   
   
   ret = buf[0] = my_getkey();
/*   buf[1] = '\0'; */

   if(buf[0] == SS2)
     return my_getkey ();
   else if(iseuckanji(buf[0]))
     {
	int i;
	buf[1] = my_getkey();
	euctosjis(buf, dst);
	i = (int)dst[1];
	ungetkey(&i);
	ret = dst[0];
     }
   
   return ret;

}

/*}}}*/

/* getkey function for KANJI
 * input: EUC
 * buffer code EUC
 */
int ja_EUC_to_EUC_getkey () /*{{{*/
{
   return my_getkey();
}

/*}}}*/





/* getkey function for KANJI
 * input: JIS
 * buffer code SJIS
 */
int ja_JIS_to_SJIS_getkey () /*{{{*/
{
   static unsigned char buf[BUFSIZE], dst[BUFSIZE];
   int len=0;
   int jp_kana_flag = 0;
   static int	kflg	= FALSE;
   static int	hflg	= FALSE;
   unsigned char nxtchar = 0;
   int	ret = -1;
   struct _jis_data
     {
	char *sequence;
	int length;	/* string length of "sequence" */
	int kflag, hflag;
	int len;
     } *p, jis_data[32] =
     {
	{ "\x1b$B", 3, TRUE, FALSE, 2 },	/* jisx0208-1983 */
	{ "\x1b$@", 3, TRUE, FALSE, 2 },	/* jisx0208-1978 */
	{ "\x1b\(I", 3, FALSE, TRUE, 1 },
	{ "\x1b\(B", 3, FALSE, FALSE, 1 },	/* ascii */
	{ "\x1b\(J", 3, FALSE, FALSE, 1 },	/* jisx0201-roman */
	NULL
     };

   p = jis_data;

   ret = buf[len++] = my_getkey ();
/*   buf[len] = '\0'; */

   while (buf[0] == ESC)
     {
	if (input_pending(&Number_Zero))
	  {
	     buf[len++] = my_getkey ();
	  }
	else
	  break;
	
	for (p=jis_data ; p ; p++)
	  {
	     if (len == p->length && SLstrcmp(p->sequence, buf) == 0)
	       {
		  kflg = p->kflag;
		  hflg = p->hflag;
		  len = 0;
		  ret = buf[len++] = my_getkey ();		/* ???(k-yosino) */
/*		  .... */
		  break;
	       }
	     else if (len < p->length && SLstrncmp(buf, p->sequence, len) == 0)
	       {
		  break;
	       }
	  }
	
	
		  
	if (p == NULL)
	  {
	     ungetkey_string(&buf[1], len - 1);
	     return	ret;
	  }
     }

   if(kflg)
     {
	if(isjiskanji(ret))
	  {
	     int i;
	     buf[1] = my_getkey();
	     jistosjis(buf, dst);
	     ret = dst[0];
	     i = (int)dst[1];
	     ungetkey(&i);
	  }
     }
   else if(hflg)
     {
	ret = buf[0] = buf[0] | 0x80;
     }
/*   else
     ret = buf[0]; */

   return ret;
}

/*}}}*/

/* getkey function for KANJI
 * input: JIS
 * buffer code EUC
 */
int ja_JIS_to_EUC_getkey () /*{{{*/
{
   static unsigned char buf[BUFSIZE], dst[BUFSIZE];
   int len=0;
   int jp_kana_flag = 0;
   static int	kflg	= FALSE;
   static int	hflg	= FALSE;
   unsigned char nxtchar = 0;
   int	ret = -1;
   struct _jis_data
     {
	char *sequence;
	int length;	/* string length of "code_char" */
	int kflag, hflag;
	int len;
     } *p, jis_data[32] =
     {
	{ "\x1b$B", 3, TRUE, FALSE, 2 },	/* jisx0208-1983 */
	{ "\x1b$@", 3, TRUE, FALSE, 2 },	/* jisx0208-1978 */
	{ "\x1b\(I", 3, FALSE, TRUE, 1 },
	{ "\x1b\(B", 3, FALSE, FALSE, 1 },	/* ascii */
	{ "\x1b\(J", 3, FALSE, FALSE, 1 },	/* jisx0201-roman */
	NULL
     };



   ret = buf[len++] = my_getkey();
/*   buf[len] = '\0'; */

   while (buf[0] == ESC)
     {
	if (input_pending(&Number_Zero))
	  {
	     buf[len++] = my_getkey();
	  }
	else
	  break;
	
	for (p=jis_data ; p ; p++)
	  {
	     if (len == p->length && SLstrcmp(p->sequence, buf) == 0)
	       {
		  kflg = p->kflag;
		  hflg = p->hflag;
		  len = 0;
		  ret = buf[len++] = my_getkey();		/* ???(k-yosino) */
/*		  .... */
		  break;
	       }
	     else if (len < p->length && SLstrncmp(buf, p->sequence, len) == 0)
	       {
		  break;
	       }
	  }
	
	
	if (p == NULL)
	  {
	     ungetkey_string(&buf[1], len - 1);
	     return	ret;
	  }
     }

   if(kflg)
     {
	if(isjiskanji(ret))
	  {
	     int i;
	     buf[1] = my_getkey();
	     jistoeuc(buf, dst);
	     ret = dst[0];
	     i = (int)dst[1];
	     ungetkey(&i);
	  }
     }
   else if(hflg)
     {
	ret = buf[0] = buf[0] | 0x80;
     }
/*   else
     ret = buf[0]; */

   return ret;
}

/*}}}*/


/* getkey function for KANJI
 * input: SJIS
 * buffer code SJIS
 */
int ja_SJIS_to_SJIS_getkey () /*{{{*/
{
	return my_getkey ();
}

/*}}}*/


/* getkey function for KANJI
 * input: SJIS
 * buffer code EUC
 */
int ja_SJIS_to_EUC_getkey () /*{{{*/
{
   static unsigned char buf[BUFSIZE], dst[BUFSIZE];
   int jp_kana_flag = 0;
   int	ret;
   
   
   ret = buf[0] = my_getkey();
/*   buf[1] = '\0'; */

   if(ishkana(buf[0]))
     {
	ungetkey(&ret);
	ret = SS2;
     }
   else if(issjiskanji(ret))
     {
	int i;
	buf[1] = my_getkey();
	euctosjis(buf, dst);
	i = (int)dst[1];
	ungetkey(&i);
	ret = dst[0];
     }
   
   return ret;
}

/*}}}*/


int default_getkey () /*{{{*/
{
   return my_getkey ();
}

/*}}}*/

int (*kanji_getkey_func[NCODE][NCODE])() =	/* [kSLinput_code][kSLcode] */
{
     {default_getkey, default_getkey, default_getkey, default_getkey},
   {default_getkey, ja_EUC_to_EUC_getkey, default_getkey, ja_EUC_to_SJIS_getkey},
   {default_getkey, ja_JIS_to_EUC_getkey, default_getkey, ja_JIS_to_SJIS_getkey},
   {default_getkey, ja_SJIS_to_EUC_getkey, default_getkey, ja_SJIS_to_SJIS_getkey}
};

int jed_kanji_getkey () /*{{{*/
{
   int ret;
   static int in_func = 0;
   
   if (Kanji_Code_Conved || !is_kanji_jedcode())
     {
	if(Kanji_Code_Conved)   Kanji_Code_Conved--;
	return my_getkey();
     }
   
   ret = kanji_getkey_func[kSLinput_code][kSLcode]();
   
/*   if (jed_keyboard_input_hook) */
   if (!in_func && SLang_is_defined("jed_getkey_hook"))
     {
	int n;
	in_func = 1;
	SLang_push_integer (ret);
/*	SLexecute_function (jed_keyboard_input_hook); */
	SLang_run_hooks("jed_getkey_hook", 0);
	if (-1 != SLang_pop_integer (&n))
	  ret = n;
	in_func = 0;
     }
   return ret;
   
}

/*}}}*/


#if 0
/* 
 * 
 */
int kanji_getkey() /*{{{*/
{
   static unsigned char buf[BUFSIZE], dst[BUFSIZE];
   static int	kflg	= FALSE;
   static int	hflg	= FALSE;
   unsigned char nxtchar = 0;
   int	ret = -1;


   if(Kanji_Code_Conved || !is_kanji_jedcode())
     {
	if(Kanji_Code_Conved)	Kanji_Code_Conved--;
	return my_getkey();
     }


   ret = buf[0] = my_getkey();
   buf[1] = '\0';


   if(kSLinput_code == EUC)
     {
	if(buf[0] == SS2)
	  {
	     ret = buf[0] = my_getkey();
	     if(SKanaToDKana && input_pending(&Number_One))
	       {
		  buf[1] = nxtchar = my_getkey();
		  if(buf[1] == SS2)
		    {
		       buf[2] = my_getkey();
		       if((ISNIGORI(buf[0]) && buf[2] == 222) ||
			  (ISMARU(buf[0]) && buf[2] == 223))
			 buf[1] = buf[2];
		       else	ungetkey_string(&buf[1], 2);
		    }
		  else	ungetkey_string(&buf[1], 1);
		  nxtchar = 0;
	       }
	  }
	else if(iseuckanji(buf[0]))
	  {
	     buf[1] = my_getkey();
	     if (kSLcode == SJIS)
	       euctosjis(buf, dst);
	     else if (kSLcode == EUC)
	       notconv(buf, dst);
	     else
	       notconv(buf, dst);
	     ret = dst[0];
	  }
     }
   else if(kSLinput_code == JIS)
     {
	while(buf[0] == ESC)
	  {
	     if(input_pending(&Number_One))
	       {
		  buf[1] = my_getkey();
		  if(input_pending(&Number_One))
		    {
		       buf[2] = my_getkey();
		    }
		  else
		    {
		       ungetkey_string(&buf[1], 1);
		       return	ret;
		    }
	       }
	     else	return	ret;

	     if(buf[1] == '$' && (buf[2] == '@' || buf[2] == 'B'))
	       {
		  kflg = TRUE;
		  hflg = FALSE;
	       }
	     else if(buf[1] == '(' && buf[2] == 'I')
	       {
		  kflg = FALSE;
		  hflg = TRUE;
	       }
	     else if(buf[1] == '(' && (buf[2] == 'B' || buf[2] == 'J'))
	       {
		  kflg = hflg = FALSE;
	       }
	     else
	       {
		  ungetkey_string(&buf[1], 2);
		  return	ret;
	       }
	     ret = buf[0] = my_getkey();
	  }


	if(kflg)
	  {
	     if(isjiskanji(ret))
	       {
		  buf[1] = my_getkey();
		  if (kSLcode == SJIS)
		    jistosjis(buf, dst);
		  else if (kSLcode == EUC)
		    jistoeuc(buf, dst);
		  else
		    notconv(buf, dst);
		  ret = dst[0];
	       }
	     else	return ret;
	  }

	else if(hflg)
	  {
	     ret = buf[0] = buf[0] | 0x80;
	     if(SKanaToDKana && ISNIGORI(ret) && input_pending(&Number_One))
	       {
		  nxtchar = buf[1] = my_getkey();
		  buf[1] |= 0x80;
		  if(buf[1] == 222 || (buf[1] == 223 && ISMARU(ret)))
		    nxtchar = 0;
	       }
	  }
	else
	  ret = buf[0];
     }
   else if(kSLinput_code == SJIS)
     {
	if(issjiskanji(ret))
	  {
	     buf[1] = my_getkey();
	     if (kSLcode == SJIS)
	       notconv(buf, dst);
	     else if (kSLcode == EUC)
	       sjistoeuc(buf, dst);
	     else
	       notconv(buf, dst);
	     ret = dst[0];
	  }
	else if(SKanaToDKana && ISNIGORI(ret)  && input_pending(&Number_Ten) )
	  {
	     nxtchar = buf[1] = my_getkey();
	     if(buf[1] == 222 || (buf[1] == 223 && ISMARU(ret)))
	       {
		  nxtchar = 0;
	       }
	  }
     }

	if(nxtchar) {
		ungetkey_string(&nxtchar, 1);
	}
	if(SKanaToDKana && kSLcode== SJIS && ishkana(ret)) {
		int dummy;
		buf[0] = (unsigned char)ret;
		han2zen(buf, dst, &dummy, &dummy, SJIS);
/*	   if (kSLcode == EUC) sjistoeuc (dst, dst); */
		ret = dst[0];
	}

	if(iskanji(ret)) {
	   int i = (int)dst[1];			/* bugfix by Toyofuku(unbound@papaya.juice.or.jp) */
		ungetkey(&i);
	}

	return	ret;
}

/*}}}*/
#endif
