/*
    KCTRL - Dynamic Link Library of Japanization Toolkit for Windows CE
    Copyright (C) 1997-2001  ITO, Eiichiro

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#define	IS_SJS_AN(c)	(((0xFF&(c))>=0x20)&&((0xFF&(c))<=0x7F))
#define	IS_SJS_HANK(c)	((0xA0<=(0xFF&(c))) && ((0xFF&(c))<=0xDF))
#define	IS_SJS_KANJ(c)	\
    ((((0xFF&(c))>=0x81)&&((0xFF&(c))<=0x9F)) \
 ||  (((0xFF&(c))>=0xE0)&&((0xFF&(c))<=0xFC)))

/* hankaku --> zenkaku henkan you code */
#define	C_AN		(0x20)
#define	C_KANA		(0xA0)
#define	C_DAKUTEN	(0xDE)
#define	C_HANDAKU	(0xDF)
#define	C_U		(0xB3)
#define	C_KA		(0xB6)
#define	C_TO		(0xC4)
#define	C_HA		(0xCA)
#define	C_HO		(0xCE)

#define	SJS_VU		(0x8394)
#define	SJS_DAKUTEN	(0x814A)
#define	SJS_HANDAKU	(0x814B)

/* 英数字の変換テーブル(0x20..0x7F) */
const	WORD	h2z_207F[] = {
    0x8140, 0x8149, 0x8168, 0x8194, 0x8190, 0x8193, 0x8195, 0x8166,
    0x8169, 0x816A, 0x8196, 0x817B, 0x8143, 0x817C, 0x8144, 0x815E,
    0x824F, 0x8250, 0x8251, 0x8252, 0x8253, 0x8254, 0x8255, 0x8256,
    0x8257, 0x8258, 0x8146, 0x8147, 0x8183, 0x8181, 0x8184, 0x8148,
    0x8197, 0x8260, 0x8261, 0x8262, 0x8263, 0x8264, 0x8265, 0x8266,
    0x8267, 0x8268, 0x8269, 0x826A, 0x826B, 0x826C, 0x826D, 0x826E,
    0x826F, 0x8270, 0x8271, 0x8272, 0x8273, 0x8274, 0x8275, 0x8276,
    0x8277, 0x8278, 0x8279, 0x816D, 0x818F, 0x816E, 0x814F, 0x8151,
    0x8165, 0x8281, 0x8282, 0x8283, 0x8284, 0x8285, 0x8286, 0x8287,
    0x8288, 0x8289, 0x828A, 0x828B, 0x828C, 0x828D, 0x828E, 0x828F,
    0x8290, 0x8291, 0x8292, 0x8293, 0x8294, 0x8295, 0x8296, 0x8297,
    0x8298, 0x8299, 0x829A, 0x816F, 0x8162, 0x8170, 0x8150, 0x0000,
} ;

/* ひらがなの変換テーブル(0xA0..0xDF) */
const	WORD	hira_a0df[] = {
    0x8140, 0x8142, 0x8175, 0x8176, 0x8141, 0x8145, 0x82F0, 0x829F,
    0x82A1, 0x82A3, 0x82A5, 0x82A7, 0x82E1, 0x82E3, 0x82E5, 0x82C1,
    0x815B, 0x82A0, 0x82A2, 0x82A4, 0x82A6, 0x82A8, 0x82A9, 0x82AB,
    0x82AD, 0x82AF, 0x82B1, 0x82B3, 0x82B5, 0x82B7, 0x82B9, 0x82BB,
    0x82BD, 0x82BF, 0x82C2, 0x82C4, 0x82C6, 0x82C8, 0x82C9, 0x82CA,
    0x82CB, 0x82CC, 0x82CD, 0x82D0, 0x82D3, 0x82D6, 0x82D9, 0x82DC,
    0x82DD, 0x82DE, 0x82DF, 0x82E0, 0x82E2, 0x82E4, 0x82E6, 0x82E7,
    0x82E8, 0x82E9, 0x82EA, 0x82EB, 0x82ED, 0x82F1, 0x814A, 0x814B,
} ;
/* 「が」〜「ど」までの変換テーブル */
const	WORD	hira_gado[] = {
    0x82AA, 0x82AC, 0x82AE, 0x82B0, 0x82B2,
    0x82B4, 0x82B6, 0x82B8, 0x82BA, 0x82BC,
    0x82BE, 0x82C0, 0x82C3, 0x82C5, 0x82C7,
} ;
/* 「ば」〜「ぼ」までの変換テーブル */
const	WORD	hira_babo[] = {
    0x82CE, 0x82D1, 0x82D4, 0x82D7, 0x82DA,
} ;
/* 「ぱ」〜「ぽ」までの変換テーブル */
const	WORD	hira_papo[] = {
    0x82CF, 0x82D2, 0x82D5, 0x82D8, 0x82DB,
} ;

/* カタカナの変換テーブル(0xA0..0xDF) */
const	WORD	kata_a0df[] = {
    0x8140, 0x8142, 0x8175, 0x8176, 0x8141, 0x8145, 0x8392, 0x8340,
    0x8342, 0x8344, 0x8346, 0x8348, 0x8383, 0x8385, 0x8387, 0x8362,
    0x815B, 0x8341, 0x8343, 0x8345, 0x8347, 0x8349, 0x834A, 0x834C,
    0x834E, 0x8350, 0x8352, 0x8354, 0x8356, 0x8358, 0x835A, 0x835C,
    0x835E, 0x8360, 0x8363, 0x8365, 0x8367, 0x8369, 0x836A, 0x836B,
    0x836C, 0x836D, 0x836E, 0x8371, 0x8374, 0x8377, 0x837A, 0x837D,
    0x837E, 0x8380, 0x8381, 0x8382, 0x8384, 0x8386, 0x8388, 0x8389,
    0x838A, 0x838B, 0x838C, 0x838D, 0x838F, 0x8393, 0x814A, 0x814B,
} ;
/* 「ガ」〜「ド」までの変換テーブル */
const	WORD	kata_gado[] = {
    0x834B, 0x834D, 0x834F, 0x8351, 0x8353,
    0x8355, 0x8357, 0x8359, 0x835B, 0x835D,
    0x835F, 0x8361, 0x8364, 0x8366, 0x8368,
} ;
/* 「バ」〜「ボ」までの変換テーブル */
const	WORD	kata_babo[] = {
    0x836F, 0x8372, 0x8375, 0x8378, 0x837B,
} ;
/* 「パ」〜「ポ」までの変換テーブル */
const	WORD	kata_papo[] = {
    0x8370, 0x8373, 0x8376, 0x8379, 0x837C,
} ;

BOOL
han2zen_kanastr( const BYTE *src, LPBYTE dst, DWORD dstlen, BOOL fHira )
{
    WORD	sjis ;
    BYTE	c, c1 ;
    const WORD	*h2z_kana, *h2z_gado, *h2z_babo, *h2z_papo ;

    if ( fHira ) {
	h2z_kana = hira_a0df ;
	h2z_gado = hira_gado ;
	h2z_babo = hira_babo ;
	h2z_papo = hira_papo ;
    } else {
	h2z_kana = kata_a0df ;
	h2z_gado = kata_gado ;
	h2z_babo = kata_babo ;
	h2z_papo = kata_papo ;
    }
    if ( !dstlen ) {
	return FALSE ;
    }
    while ( 1 ) {
	c = *src++ ;
	if ( !c ) {
	    break ;
	}
	if ( IS_SJS_AN( c ) ) {
	    sjis = h2z_207F[ c - C_AN ] ;
	} else if ( IS_SJS_KANJ( c ) ) {
	    c1 = *src++ ;
	    if ( !c1 ) {
		break ;
	    }
	    sjis = (c << 8) | c1 ;
	} else if ( IS_SJS_HANK( c ) ) {
	    c1 = *src ;
	    if ( c1 == C_DAKUTEN ) {
		src ++ ;
		if ( !fHira && c == C_U ) {
		    sjis = SJS_VU ;
		} else if ( c >= C_KA && c <= C_TO ) {
		    sjis = h2z_gado[ c - C_KA ] ;
		} else if ( c >= C_HA && c <= C_HO ) {
		    sjis = h2z_babo[ c - C_HA ] ;
		} else {
		    sjis = h2z_kana[ c - C_KANA ] ;
		    if ( dstlen < 2 ) {
			return FALSE ;
		    }
		    dstlen -= 2 ;
		    *dst++ = sjis / 256 ;
		    *dst++ = sjis % 256 ;
		    sjis = SJS_DAKUTEN ;
		}
	    } else if ( c1 == C_HANDAKU ) {
		src ++ ;
		if ( c >= C_HA && c <= C_HO ) {
		    sjis = h2z_papo[ c - C_HA ] ;
		} else {
		    sjis = h2z_kana[ c - C_KANA ] ;
		    if ( dstlen < 2 ) {
			return FALSE ;
		    }
		    dstlen -= 2 ;
		    *dst++ = sjis / 256 ;
		    *dst++ = sjis % 256 ;
		    sjis = SJS_HANDAKU ;
		}
	    } else {
		sjis = h2z_kana[ c - C_KANA ] ;
	    }
	} else if ( c != 0x0D ) {
	    if ( dstlen < 1 ) {
		return FALSE ;
	    }
	    dstlen -- ;
	    *dst++ = c ;
	    continue ;
	} else {
	    continue ;
	}
	if ( dstlen < 2 ) {
	    return FALSE ;
	}
	dstlen -= 2 ;
	*dst++ = sjis / 256 ;
	*dst++ = sjis % 256 ;
    }
    if ( dstlen < 1 ) {
	return FALSE ;
    }
    dstlen -- ;
    *dst = 0 ;
    return TRUE ;
}
