#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;
}
