/*////////////////////////////////////////////////////////////////////////
Copyright (c) 1993 Electrotechnical Laboratry (ETL)

Permission to use, copy, modify, and distribute this material for any
purpose and without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies, and
that the name of ETL not be used in advertising or publicity pertaining
to this material without the specific, prior written permission of an
authorized representative of ETL.
ETL MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY OF THIS
MATERIAL FOR ANY PURPOSE.  IT IS PROVIDED "AS IS", WITHOUT ANY EXPRESS
OR IMPLIED WARRANTIES.
/////////////////////////////////////////////////////////////////////////
Content-Type:	program/C; charset=US-ASCII
Program:	CannaRk.c (romaji-kana translation with Canna)
Author:		Yutaka Sato <ysato@etl.go.jp>
Description:
History:
	931104	created
	931127	added RKTAB searching in RKPATH
	931214	deleted exceptional NN handling
///////////////////////////////////////////////////////////////////////*/
int RomkanExists;
int ONEW_kanamode;

#include <ctype.h>
#include <stdio.h>

#include <canna/RK.h>
#include <canna/jrkanji.h>
#include "onew.h"
/*/////////////////////////////////////////////////////////////////////*/

static int RkInitDone;
static struct RkRxDic *RKTAB;
static int RK_MODE;
int ONEW_CannarcDone;

static ONEWromkan_modesw();

static ONEWromkan_ready(rrkfile)
	char *rrkfile;
{	Pathname rkfile;
	char *rkname,*rkpath;
	int rkfd;

	if( RkInitDone )
		return RkInitDone;

	if( !ONEW_CannarcDone ){
		/*Onew_putmsg_sys(1," Canna Initialization ...");*/
		jrKanjiControl(0,KC_INITIALIZE,0);
		ONEW_CannarcDone = 1;
	}

	if( (rkname = getenv("ONEW_CANNA_RKTAB")) == 0 )
		rkname = CANNA_RKTAB;
	if( (rkpath = getenv("ONEW_CANNA_RKPATH")) == 0 )
		rkpath = CANNA_RKPATH;

	if((rkfd = Onew_searchPath(rkfile,rkname,rkpath)) < 0)
	if( Onew_extract_rktabs() )
	if((rkfd = Onew_searchPath(rkfile,rkname,rkpath)) < 0)
	{
		Onew_putmsg(1,"[CANNA] cannot open %s in (%s)\n",rkname,rkpath);
		return RkInitDone = -1;
	}
	close(rkfd);

	if( RKTAB = (struct RkRxDic*)RkOpenRoma(rkfile) ){
		RkInitDone =  1;
		ONEWromkan_modesw(0);
		if( rrkfile )
			strcpy(rrkfile,rkfile);
	}else{
		RkInitDone = -1;
		Onew_putmsg(1,"[CANNA] error in romaji-kana table:%s\n",rkfile);
	}
	return RkInitDone;
}

static unsigned char pending[8];
static int pendx;
static int inQ;
static int outQ;

static romkan_clear(){
	pending[0] = 0;
	pendx = 0;
	inQ = 0;
	outQ = 0;
}
static ONEWromkan_clear(){
	romkan_clear();
}

static ONEWromkan_getc(){
	int ch;
	unsigned char src[256],dst[256];
	int rlen,klen;

	if( ch = outQ ){
		outQ = 0;
		return ch;
	}
	if( ch = inQ )
		inQ = 0;
	else	ch = ONEW_getch1();

	if( ch == EOF )
		return ch;

	if( RK_MODE == RK_NFER )
		return ch;

	if( pendx && (ch == DEL_CH || ch == '\b') ){
		pendx--;
		pending[pendx] = 0;
		return 0x80000000;
	}

if( ch != '\n' && ch != '\r' )
	if( iscntrl(ch) || ch & 0x80 )
		return ch & 0xFF;

	if( pendx == 0 ){
		if( ch == ' ' )
			return ch;
	}

	strcpy(src,pending);
	src[pendx] = ch;
	src[pendx+1] = 0;

	klen = 0;
	if( RK_MODE == RK_ZFER )
		klen = RkCvtZen(dst,sizeof(dst),src,strlen(src));
	else{

		rlen = RkMapRoma(RKTAB,dst,sizeof(dst),src,strlen(src),
			RK_MODE,&klen);

		if( klen == 2 && inQ == 0 && src[0] == src[1] )
			if( src[0] != 'n' || !ONEW_NN_THRU )
				inQ = src[0];
	}

	switch( klen ){
		case -1:
			romkan_clear();
		case 0:
			if( (ch & 0x80) == 0 )
			if( islower(ch) && 'a'<=ch && ch<='z' ){
				pending[pendx++] = ch;
				pending[pendx] = 0;
				ch = 0x80000000 | Onew_toupper(ch);
			}
			break;
		case 1:
			ch = dst[0];
			pendx = 0;
			break;

		case 4:
			outQ = dst[2]<<8 | dst[3];
		case 2:
			ch = dst[0] << 8 | dst[1];
			pendx = 0;
			if( rlen == 1 )
				inQ = src[1];
			break;
	}
	return ch;
}

static ONEWromkan_next(){
	int ch;

	if( ch = inQ )
		inQ = 0;
	else	ch = ONEW_getch1();
	return ch;
}
static ONEWromkan_gotch(ch)
{
	if( ch == EOF )
		return ch;

	if((ch & 0xFFFFFF00) == 0x80000000){
		Onew_disp_kanahalves(pending);
		ch = 0;
	}
	return ch;
}

static ONEWromkan_modesw(imode)
{	int omode;

	if( ONEWromkan_ready(0) <= 0 )
		return 0;

	omode = ONEW_kanamode;
	ONEW_kanamode = imode;
	switch( ONEW_kanamode ){
		case RK_ROMHIRA: RK_MODE = RK_XFER; break;
		case RK_ROMKATA: RK_MODE = RK_KFER; break;
		case RK_ZENKAKU: RK_MODE = RK_ZFER; break;
		case RK_THROUGH:
		default:	 RK_MODE = RK_NFER; break;
	}
	if( ONEW_kanamode != imode )
		romkan_clear();
	return omode;
}
static char*
ONEWromkan_dispmode(){
    switch( ONEW_kanamode ){
	case RK_ROMHIRA: return ONEW_NN_THRU ?
			ONEW_mode_CromhiraNN : ONEW_mode_Cromhira;
	case RK_ROMKATA: return ONEW_NN_THRU ?
			ONEW_mode_CromkataNN : ONEW_mode_Cromkata;
	case RK_ZENKAKU: return ONEW_mode_romzen;
	case RK_THROUGH:
	default:	 return "[---]";
    }
}

RegisterRomkan(ONEW_CannaRk);


syntax highlighted by Code2HTML, v. 0.9.1