#include <u.h>
#include <libc.h>
#include <bio.h>
#include "dict.h"

/*
 * Routines for handling dictionaries in the "Paperback Collins"
 * `German' format (with tags surrounded by \5⋯\6 and \xba⋯\xba)
 */

/*
 *	\5...\6 escapes (fonts, mostly)
 *
 *	h	headword (helvetica 7 pt)
 *	c	clause (helvetica 7 pt)
 *	3	helvetica 7 pt
 *	4	helvetica 6.5 pt
 *	s	helvetica 8 pt
 *	x	helvetica 8 pt
 *	y	helvetica 5 pt
 *	m	helvetica 30 pt
 *	1	roman 6 pt
 *	9	roman 4.5 pt
 *	p	roman 7 pt
 *	q	roman 4.5 pt
 *	2	italic 6 pt
 *	7	italic 4.5 pt
 *	b	bold 6 pt
 *	a	`indent 0:4 left'
 *	k	`keep 9'
 *	l	`size 12'
 */

enum {
	IBASE=0x69,	/* dotless i */
	Taglen=32
};

static Rune intab[256] = {
	/*0*/	/*1*/	/*2*/	/*3*/	/*4*/	/*5*/	/*6*/	/*7*/
/*00*/	NONE,	NONE,	NONE,	NONE,	NONE,	TAGS,	TAGE,	NONE,
	NONE,	NONE,	NONE,	NONE,	NONE,	0x20,	NONE,	NONE,
/*10*/	NONE,	0x2d,	0x20,	0x20,	NONE,	NONE,	NONE,	NONE,
	0x20,	NONE,	NONE,	NONE,	0x20,	NONE,	NONE,	0x2d,
/*20*/	0x20,	0x21,	0x22,	0x23,	0x24,	0x25,	0x26,	'\'',
	0x28,	0x29,	0x2a,	0x2b,	0x2c,	0x2d,	0x2e,	0x2f,
/*30*/  0x30,	0x31,	0x32,	0x33,	0x34,	0x35,	0x36,	0x37,
	0x38,	0x39,	0x3a,	0x3b,	0x3c,	0x3d,	0x3e,	0x3f,
/*40*/  0x40,	0x41,	0x42,	0x43,	0x44,	0x45,	0x46,	0x47,
	0x48,	0x49,	0x4a,	0x4b,'L',	0x4d,	0x4e,	0x4f,
/*50*/	0x50,	0x51,	0x52,	0x53,	0x54,	0x55,	0x56,	0x57,
	0x58,	0x59,	0x5a,	0x5b,'\\',	0x5d,	0x5e,	0x5f,
/*60*/	0x60,	0x61,	0x62,	0x63,	0x64,	0x65,	0x66,	0x67,
	0x68,	0x69,	0x6a,	0x6b,	0x6c,	0x6d,	0x6e,	0x6f,
/*70*/	0x70,	0x71,	0x72,	0x73,	0x74,	0x75,	0x76,	0x77,
	0x78,	0x79,	0x7a,	0x7b,	0x7c,	0x7d,	0x7e,	NONE,
/*80*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
	NONE,	NONE,	0x20,	NONE,	NONE,	NONE,	NONE,	NONE,
/*90*/	0xdf,	0xe6,	NONE,	MOE,	NONE,	NONE,	NONE,	0xf8,
	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
/*A0*/	NONE,	NONE,	0x22,	0xa3,	NONE,	NONE,	NONE,	NONE,
	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
/*B0*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	0x7e,
	NONE,	IBASE,	SPCS,	NONE,	NONE,	NONE,	NONE,	NONE,
/*C0*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
/*D0*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
/*E0*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
/*F0*/	0x20,	0x20,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE
};

static Nassoc numtab[] = {
	{1,	0x2b},
	{4,	0x3d},
	{7,	0xb0},
	{11,	0x2248},
	{69,	0x2666},
	{114,	0xae},
	{340,	0x25b},
	{341,	0x254},
	{342,	0x28c},
	{343,	0x259},
	{345,	0x292},
	{346,	0x283},
	{347,	0x275},
	{348,	0x28a},
	{349,	0x2c8},
	{351,	0x26a},
	{352,	0x25c},
	{354,	0x251},
	{355,	0x7e},
	{356,	0x252},
	{384,	0x273},
	{445,	0xf0},	/* BUG -- should be script eth */
};

static Nassoc overtab[] = {
	{0x2c,	LCED},
	{0x2f,	LACU},
	{0x3a,	LUML},
	{'\\',	LGRV},
	{0x5e,	LFRN},
	{0x7e,	LTIL}
};

static uchar *reach(uchar*, int);

static Entry	curentry;
static char	tag[Taglen];

void
pcollgprintentry(Entry e, int cmd)
{
	uchar *p, *pe;
	int r, rprev = NONE, rx, over = 0, font;
	char buf[16];

	p = (uchar *)e.start;
	pe = (uchar *)e.end;
	curentry = e;
	if(cmd == 'h')
		outinhibit = 1;
	while(p < pe){
		if(cmd == 'r'){
			outchar(*p++);
			continue;
		}
		switch(r = intab[*p++]){	/* assign = */
		case TAGS:
			if(rprev != NONE){
				outrune(rprev);
				rprev = NONE;
			}
			p = reach(p, 0x06);
			font = tag[0];
			if(cmd == 'h')
				outinhibit = (font != 'h');
			break;

		case TAGE:	/* an extra one */
			break;
	
		case SPCS:
			p = reach(p, 0xba);
			r = looknassoc(numtab, asize(numtab), strtol(tag,0,0));
			if(r < 0){
				if(rprev != NONE){
					outrune(rprev);
					rprev = NONE;
				}
				sprint(buf, "\\N'%s'", tag);
				outchars(buf);
				break;
			}
			/* else fall through */

		default:
			if(over){
				rx = looknassoc(overtab, asize(overtab), r);
				if(rx > 0)
					rx = liglookup(rx, rprev);
				if(rx > 0 && rx != NONE)
					outrune(rx);
				else{
					outrune(rprev);
					if(r == ':')
						outrune(0xa8);
					else{
						outrune(0x5e);
						outrune(r);
					}
				}
				over = 0;
				rprev = NONE;
			}else if(r == '^'){
				over = 1;
			}else{
				if(rprev != NONE)
					outrune(rprev);
				rprev = r;
			}
		}
		
	}
	if(rprev != NONE)
		outrune(rprev);
	if(cmd == 'h')
		outinhibit = 0;
	outnl(0);
}

long
pcollgnextoff(long fromoff)
{
	int c, state = 0, defoff = -1;

	if(Bseek(bdict, fromoff, 0) < 0)
		return -1;
	while((c = Bgetc(bdict)) >= 0){
		if(c == '\r')
			defoff = Boffset(bdict);
		switch(state){
		case 0:
			if(c == 0x05)
				state = 1;
			break;
		case 1:
			if(c == 'h')
				state = 2;
			else
				state = 0;
			break;
		case 2:
			if(c == 0x06)
				return (Boffset(bdict)-3);
			else
				state = 0;
			break;
		}
	}
	return defoff;
}

void
pcollgprintkey(void)
{
	Bprint(bout, "No pronunciation key yet\n");
}

static uchar *
reach(uchar *p, int tagchar)
{
	int c; char *q=tag;

	while(p < (uchar *)curentry.end){
		c = *p++;
		if(c == tagchar)
			break;
		*q++ = c;
		if(q >= &tag[sizeof tag-1])
			break;
	}
	*q = 0;
	return p;
}
