/*
 * Copyright (C) 1994,1995	Edward Der-Hua Liu, Hsin-Chu, Taiwan
 */

#include "big5con.h"

u_char         *ch_pho;
char           *ph_pho[] = {
    "  £t£u£v£w£x£y£z£{£|£}£~£¡£¢£££¤£¥£¦£§£¨£©£ª",	/* 5 */
    "  £¸£¹£º",			/* 2 */
    "  £«£¬£­£®£¯£°£±£²£³£´£µ£¶£·",	/* 4 */
    "  £»£½£¾£¿"		/* 3 */
};

char           *phokbm_name = "zo";

int             ityp3_pho;
static int      cpg, maxi;
static int      startf;
PHOKBM          phkbm;
u_char          typ_pho[4];
char            inph[4];

void 
clrin_pho()
{
    bzero(typ_pho, sizeof(typ_pho));
    bzero(inph, sizeof(inph));
    maxi = ityp3_pho = 0;
}

void 
clr_in_area_pho()
{
    gotox(InAreaX);
    set_att(InAreaColor);
    xprintf("        ");
    set_att(NormalColor);
    xprintf("  ");
}


void 
disp_in_area_pho()
{
    int             i;
    extern int      cursor_x;

    clr_in_area_pho();
    gotox(InAreaX);
    set_att(InAreaColor);
    for (i = 0; i < 4; i++) {
	xprintf("%c%c", ph_pho[i][typ_pho[i] << 1], ph_pho[i][(typ_pho[i] << 1) + 1]);
    }
    set_att(NormalColor);
}

void 
putkey_pho(u_char * p)
{
    sendkey_b5(p);
    clrin_pho();
    ClrSelArea();
    clr_in_area_pho();
}

u_short         idxnum_pho, idx_pho[2800];
u_short         hash_pho[23];

void 
init_tab_pho(int usenow)
{
    FILE           *fr;
    int             i, cou;
    unsigned int    ttt;
    extern char     TabDir[];
    char            phofname[128];

    if (ch_pho) {
disp_prom:
	gotox(0);
	xprintf(" ¡iª`­µ¡j");
	ClrSelArea();
	clr_in_area_pho();
	clrin_pho();
	return;
    }
    bzero(typ_pho, sizeof(typ_pho));
    strcpy(phofname, TabDir);

    if ((fr = fopen(strcat(phofname, "pho.tab"), "rb")) == NULL)
	p_err("err %s\n", phofname);

    fread(&idxnum_pho, 2, 1, fr); // skip "PH"
    fread(&idxnum_pho, 2, 1, fr);
    fread(idx_pho, 2, idxnum_pho, fr);
    if (!(ch_pho = (u_char *) malloc(32000))) {
	fprintf(stderr, "malloc error");
	return;
    }
    cou = fread(ch_pho, 1, 32000, fr);
    fclose(fr);
    ttt = 0;
#if	0
    printf("idxnum %x\n", pho_idxnum);
    for (i = 0; i < pho_idxnum; i += 2)
	if (pho_idx[i] > 0x8000)
	    printf("index err %x\n", i);
#endif	/* 0 */
    idx_pho[idxnum_pho + 1] = cou;
    for (i = 0; i < 22; i++) {
	if (idx_pho[ttt] >> 9 == i)
	    hash_pho[i] = ttt;
	else {
	    printf("hash err i:%x %x %x\n", i, idx_pho[ttt], ttt);
	    continue;
	}
	while (idx_pho[ttt] >> 9 == i)
	    ttt += 2;
    }
    hash_pho[22] = idxnum_pho;

    strcat(strcat(strcpy(phofname, TabDir), phokbm_name), ".kbm");
    if ((fr = fopen(phofname, "r")) == NULL) {
	error("Cannot open %s", phofname);
	return;
    }
    fread(&phkbm, sizeof(phkbm), 1, fr);
    fclose(fr);
#if	0
    for (i = 0; i < 128; i++)
	if (phkbm.phokbm[i][0][0])
	    printf("%c %d %d\n", i, phkbm.phokbm[i][0][0], phkbm.phokbm[i][0][1]);
#endif
    if (usenow)
	goto disp_prom;
}



#define SELKEY (9)


feedkey_pho(int xkey)
{
    static int      ctyp;
    static unsigned int vv, key, ii, ttt, end;
    u_char         *pp;
    char            kno;
    int             i, j, jj, kk;

#if	0
    xkey = tolower(xkey);
#else
    if (xkey >= 'A' && xkey <= 'Z')
	xkey += 0x20;
#endif

    switch (xkey) {
    case VK_Escape:
	if (!typ_pho[0] && !typ_pho[1] && !typ_pho[2] && !typ_pho[3])
	    return 0;
	clrin_pho();
	ClrSelArea();
	clr_in_area_pho();
	return 1;
    case VK_BackSpace:
#if	DELETE_K
    case VK_Delete:
#endif
	ityp3_pho = 0;
	for (j = 3; j >= 0; j--)
	    if (typ_pho[j]) {
		typ_pho[j] = 0;
		if (!typ_pho[0] && !typ_pho[1] && !typ_pho[2] && !typ_pho[3]) {
		    ClrSelArea();
		    clr_in_area_pho();
		    clrin_pho();
		    return 1;
		}
		break;
	    }
	if (j < 0)
	    return 0;
	goto llll3;
    case '<':
	if (!ityp3_pho)
	    return 0;
	if (cpg >= SELKEY)
	    cpg -= SELKEY;
	goto proc_state;
    case ' ':
	if (!typ_pho[0] && !typ_pho[1] && !typ_pho[2])
	    return 0;
	if (!ityp3_pho && xkey == ' ') {
	    ctyp = 3;
	    kno = 0;
	    jj = 0;
	    if (typ_pho[0] && !typ_pho[1] && !typ_pho[2] && !typ_pho[3]) {
		char            tch = inph[0];
		if (phkbm.phokbm[tch][1][1] == 2) {
		    typ_pho[0] = 0;
		    typ_pho[2] = phkbm.phokbm[tch][1][0];
		}
	    }
	    goto llll1;
	}
	ii = startf + ((cpg + SELKEY) << 1);
	if (ii < end)
	    cpg += SELKEY;
	else {
	    if (cpg) {
		cpg = 0;
		ii = startf;
	    } else {
		putkey_pho(&ch_pho[startf]);
		/* maxi=ityp3_pho=0; */
		return 1;
	    }
	}
	i = 0;
	ClrSelArea();
	gotox(SelAreaX + 2);
	while (i < SELKEY && ii < end) {
#if	0
	    char            t[3];
	    b2cpy(&ch_pho[ii], t);
#endif
	    xprintf("%c%c%c ", phkbm.selkey[i], ch_pho[ii], ch_pho[ii + 1]);
	    ii += 2;
	    i = i + 1;
	}
	if (cpg)
	    xprintf("<");
	else
	    printf(" ");
	if (ii < end) {
	    if (cpg)
		xprintf("\\");
	    else
		printf(" ");
	    xprintf(">");
	}
	maxi = i;
	return 1;
    default:
	if (xkey >= 127 || xkey < ' ')
	    return 0;
	if ((pp = strchr(phkbm.selkey, xkey)) && maxi && ityp3_pho) {
	    int             c = pp - phkbm.selkey;
	    if (c < maxi) {
		putkey_pho(&ch_pho[startf + ((cpg + c) << 1)]);
		/* maxi=ityp3_pho=0; */
	    }
	    return 1;
	}
	if (ityp3_pho && !cpg) {
	    putkey_pho(&ch_pho[startf]);
	}
	cpg = 0;
    }
    for (i = 2; i >= 0; i--)
	if (typ_pho[i])
	    break;
    kno = phkbm.phokbm[xkey][0][0];
    ctyp = phkbm.phokbm[xkey][0][1];
    for (j = 0; j < 3; j++)
	if (phkbm.phokbm[xkey][j][1] > i) {
	    kno = phkbm.phokbm[xkey][j][0];
	    ctyp = phkbm.phokbm[xkey][j][1];
	    break;
	}
#if	0
    printf("xkey:%c kno:%d ctyp:%d\n", xkey, kno, ctyp);
#endif
    if (!kno)
	return 0;
    typ_pho[ctyp] = kno;
    inph[ctyp] = xkey;
llll1:
    jj = 0;
    kk = 1;
llll2:
    if (ctyp == 3) {
	ityp3_pho = 1;		/* last key is entered */
    }
llll3:
    key = (u_short) typ_pho[0] << 9 | (u_short) typ_pho[1] << 7 |
	(u_short) typ_pho[2] << 3 | typ_pho[3];
#if	0
    printf("??%d %d %d %d\n", typ_pho[0], typ_pho[1], typ_pho[2], typ_pho[3]);
#endif
    if (!key)
	return 1;
    vv = hash_pho[typ_pho[0]];
    ttt = 0xffff;
    while (vv < idxnum_pho) {
	ttt = idx_pho[vv];
	if (!typ_pho[0])
	    ttt &= ~(31 << 9);
	if (!typ_pho[1])
	    ttt &= ~(3 << 7);
	if (!typ_pho[2])
	    ttt &= ~(15 << 3);
	if (!typ_pho[3])
	    ttt &= ~(7);
	if (ttt >= key)
	    break;
	else
	    vv += 2;
    }
    if (ttt > key || (ityp3_pho && idx_pho[vv] != key)) {
	while (jj < 4) {
	    while (kk < 3)
		if (phkbm.phokbm[inph[jj]][kk][0]) {
		    if (kk) {
			ctyp = phkbm.phokbm[inph[jj]][kk - 1][1];
			typ_pho[ctyp] = 0;
		    }
		    kno = phkbm.phokbm[inph[jj]][kk][0];
		    ctyp = phkbm.phokbm[inph[jj]][kk][1];
#if	0
		    printf("## jj:%d kk:%d kno:%d ctyp:%d\n", jj, kk, kno, ctyp);
#endif	/* 0 */
		    typ_pho[ctyp] = kno;
		    kk++;
		    goto llll2;
		} else
		    kk++;
	    jj++;
	    kk = 1;
	}
	bell();
	ityp3_pho = typ_pho[3] = 0;
	disp_in_area_pho();
	return 1;
    }
proc_state:
    disp_in_area_pho();
    ii = idx_pho[vv + 1];
    end = idx_pho[vv + 3];
    ClrSelArea();
    gotox(SelAreaX + 2);
    startf = ii;
    ii += cpg << 1;

    if (ityp3_pho && end - startf == 2) {
	putkey_pho(&ch_pho[ii]);
	maxi = ityp3_pho = 0;
	return 1;
    }
    i = 0;

    if (ityp3_pho) {
	while (i < SELKEY && ii < end) {
	    xprintf("%c%c%c ", phkbm.selkey[i], ch_pho[ii], ch_pho[ii + 1]);
	    ii += 2;
	    i = i + 1;
	}
	if (cpg)
	    xprintf("<");
	else
	    xprintf(" ");
	if (ii < end) {
	    if (cpg)
		xprintf("\\");
	    else
		xprintf(" ");
	    xprintf(">");
	} else
	    cpg = 0;
	maxi = i;
    } else {
	while (i < SELKEY && ii < end) {
	    xprintf("%c%c ", ch_pho[ii], ch_pho[ii + 1]);
	    ii += 2;
	    i = i + 1;
	}
	maxi = i;
    }
    return 1;
}
