/***************************************************************************

	ui_font.c

	function for dealing with a Japanese character sequence.

****************************************************************************/

#include "driver.h"
#include "artwork.h"
#ifdef UI_COLOR_DISPLAY
#include "video.h"
#endif

static UINT16 _uifonttable[65536];
#ifdef UI_COLOR_DISPLAY
static UINT32 colortable[MAX_COLORTABLE];
#else
static UINT32 colortable[2 * 2];
#endif

/***************************************************************************/

static UINT16 uifont_buildtable(UINT16 code)
{
	UINT8 c1, c2;

	c1 = (code >> 8) & 0xff;
	c2 = code & 0xff;

	if (code >= 0x8140 && code <= 0x9ffc)
	{
		code = ((c1 - 0x81) << 8) + (c2 - 0x40);
	}
	else if (code >= 0xe040 && code <= 0xfcfc)
	{
		code = ((c1 - 0xe0 + (0xa0 - 0x81)) << 8) + (c2 - 0x40);
	}
	else
		return 0x60;

	return (code - ((code >> 8) & 0xff) * 0x40);
}


int uifont_buildfont(void)
{
	static unsigned char fontdata6x12[] =
	{
#include "font\h8x12.dat"
	};
	static unsigned char fontdata12x12[] =
	{
#include "font\z16x12.dat"
	};
	static struct GfxLayout fontlayout6x12 =
	{
		6,12,	/* 6*12 characters */
		256,    /* 128 characters */
		1,	/* 1 bit per pixel */
		{ 0 },
		{ 0, 1, 2, 3, 4, 5, 6, 7 },	/* straightforward layout */
		{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8, 11*8 },
		8*12	/* every char takes 8 consecutive bytes */
	};
	static struct GfxLayout fontlayout12x12 =
	{
		12,12,	/* 6*12 characters */
		256,    /* 128 characters */
		1,	/* 1 bit per pixel */
		{ 0 },
		{ 0,0, 1,1, 2,2, 3,3, 4,4, 5,5, 6,6, 7,7 },	/* straightforward layout */
		{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8, 11*8 },
		8*12	/* every char takes 8 consecutive bytes */
	};
	static struct GfxLayout fontlayout6x24 =
	{
		6,24,	/* 6*12 characters */
		256,    /* 128 characters */
		1,	/* 1 bit per pixel */
		{ 0 },
		{ 0, 1, 2, 3, 4, 5, 6, 7 },	/* straightforward layout */
		{ 0*8,0*8, 1*8,1*8, 2*8,2*8, 3*8,3*8, 4*8,4*8, 5*8,5*8,
		  6*8,6*8, 7*8,7*8, 8*8,8*8, 9*8,9*8, 10*8,10*8, 11*8,11*8 },
		8*12	/* every char takes 8 consecutive bytes */
	};
	static struct GfxLayout fontlayout12x12z =
	{
		12,12,
		(0x9fff - 0x8140) + (0xfcff - 0xe040) + 1,
		1,
		{ 0 },
		{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 },
		{ 0*16,1*16,2*16,3*16,4*16,5*16,6*16,7*16,8*16,9*16,10*16,11*16 },
		16*12
	};
	static struct GfxLayout fontlayout24x12z =
	{
		24,12,
		(0x9fff - 0x8140) + (0xfcff - 0xe040) + 1,
		1,
		{ 0 },
		{ 0,0, 1,1, 2,2, 3,3, 4,4, 5,5, 6,6, 7,7,
		  8,8, 9,9, 10,10, 11,11, 12,12, 13,13, 14,14, 15,15 },
		{ 0*16,1*16,2*16,3*16,4*16,5*16,6*16,7*16,8*16,9*16,10*16,11*16 },
		16*12
	};
	static struct GfxLayout fontlayout12x24z =
	{
		12,24,
		(0x9fff - 0x8140) + (0xfcff - 0xe040) + 1,
		1,
		{ 0 },
		{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 },
		{ 0*16,0*16, 1*16,1*16, 2*16,2*16, 3*16,3*16, 4*16,4*16, 5*16,5*16,
		  6*16,6*16, 7*16,7*16, 8*16,8*16, 9*16,9*16, 10*16,10*16, 11*16,11*16 },
		16*12
	};
	int i;

	Machine->uifont   = 0;
	Machine->uifont2  = 0;

	switch_ui_orientation(NULL);

	if ((Machine->drv->video_attributes & VIDEO_PIXEL_ASPECT_RATIO_MASK)
			== VIDEO_PIXEL_ASPECT_RATIO_1_2)
	{
		if (Machine->gamedrv->flags & ORIENTATION_SWAP_XY)
		{
			if ((Machine->uifont = decodegfx(fontdata6x12, &fontlayout6x24)))
			{
				Machine->uifont->colortable = colortable;
				Machine->uifont->total_colors = 2;
				Machine->uifontwidth = 6;
				Machine->uifontheight = 24;
			}
			else
				return 0;

			if ((Machine->uifont2 = decodegfx(fontdata12x12, &fontlayout12x24z)))
			{
				Machine->uifont2->colortable = colortable;
				Machine->uifont2->total_colors = 2;
				Machine->uifontwidth2 = 12;
				Machine->uifontheight2 =24;
			}
			else
				return 0;
		}
		else
		{
			if ((Machine->uifont = decodegfx(fontdata6x12, &fontlayout12x12)))
			{
				Machine->uifont->colortable = colortable;
				Machine->uifont->total_colors = 2;
				Machine->uifontwidth = 12;
				Machine->uifontheight = 12;
			}
			else
				return 0;

			if ((Machine->uifont2 = decodegfx(fontdata12x12, &fontlayout24x12z)))
			{
				Machine->uifont2->colortable = colortable;
				Machine->uifont2->total_colors = 2;
				Machine->uifontwidth2 = 24;
				Machine->uifontheight2 =12;
			}
			else
				return 0;
		}
	}
	else
	{
		if ((Machine->uifont = decodegfx(fontdata6x12, &fontlayout6x12)))
		{
			Machine->uifont->colortable = colortable;
			Machine->uifont->total_colors = 2;
			Machine->uifontwidth = 6;
			Machine->uifontheight = 12;
		}
		else
			return 0;

		if ((Machine->uifont2 = decodegfx(fontdata12x12, &fontlayout12x12z)))
		{
			Machine->uifont2->colortable = colortable;
			Machine->uifont2->total_colors = 2;
			Machine->uifontwidth2 = 12;
			Machine->uifontheight2 =12;
		}
		else
			return 0;
	}

	switch_true_orientation(NULL);

	for (i = 0x4081; i < 0xfffc; i++)
		_uifonttable[i] = uifont_buildtable(i) + 256;

	return 1;
}


void uifont_freefont(void)
{
	if (Machine->uifont2)
	{
		freegfx(Machine->uifont2);
		Machine->uifont2 = 0;
	}
	if (Machine->uifont)
	{
		freegfx(Machine->uifont);
		Machine->uifont = 0;
	}
}

int uifont_decodechar(unsigned char *s, unsigned short *code)
{
	unsigned char c1 = *(unsigned char *)s;
	unsigned char c2 = *(unsigned char *)(s + 1);

	if (ISSJIS1(c1) && ISSJIS2(c2))
	{
		*code = _uifonttable[(c1 << 8) | c2];

		if (*code == 0)
			*code = _uifonttable[0x817f];

		return 2;
	}

	*code = c1;
	return 1;
}

int uifont_drawfont(struct mame_bitmap *bitmap, const char *s, int sx,
                    int sy, int color)
{
	int x, y, wrapped, next_sy, increment, uifontwidth;
#ifdef UI_COLOR_DISPLAY
	int white = 0;
#endif
	unsigned short code;
	unsigned char *c;
	struct GfxElement *uifont;

	c      = (unsigned char *)s;
	x      = sx;
	y      = sy;
	code   = 0;
	next_sy = 0;

#ifdef UI_COLOR_DISPLAY
	if (color == UI_COLOR_INVERSE)
	{
		white = Machine->uifont->colortable[FONT_COLOR_NORMAL];
		Machine->uifont->colortable[FONT_COLOR_NORMAL] = Machine->uifont->colortable[BUTTON_COLOR_YELLOW];
	}
#endif

	while (*c)
	{
		wrapped = 0;

		increment = uifont_decodechar(c, &code);

		if (*c == '\n')
		{
			x = sx;
			y += Machine->uifontheight + 1;
			next_sy += Machine->uifontheight;
			c++;
			continue;
		}
		else
		{
			if (code > 0x00ff)
			{
				uifont      = Machine->uifont2;
				uifontwidth = Machine->uifontwidth * 2;
			}
			else
			{
				uifont      = Machine->uifont;
				uifontwidth = Machine->uifontwidth;
			}
		}

		if (y >= Machine->uiheight)
			return next_sy;

		if (!wrapped)
		{
#ifdef UI_COLOR_DISPLAY
			int col = 0;
#endif

			if (code > 0x00ff)
			{
				code -= 256;

#ifdef UI_COLOR_DISPLAY
				if      (code == 0x0080 || code == 0x00a9)	col = BUTTON_COLOR_RED;
				else if (code == 0x0081 || code == 0x00aa)	col = BUTTON_COLOR_YELLOW;
				else if (code == 0x0082 || code == 0x00ab)	col = BUTTON_COLOR_GREEN;
				else if (code == 0x0083 || code == 0x00ac)	col = BUTTON_COLOR_BLUE;
				else if (code == 0x0086 || code == 0x00ad)	col = BUTTON_COLOR_PURPLE;
				else if (code == 0x0085 || code == 0x00ae)	col = BUTTON_COLOR_PINK;
				else if (code == 0x00af)			col = BUTTON_COLOR_AQUA;

				if (col)
				{
					white = Machine->uifont->colortable[FONT_COLOR_NORMAL];
					Machine->uifont->colortable[FONT_COLOR_NORMAL] = Machine->uifont->colortable[col];
				}
#endif
			}

			artwork_mark_ui_dirty(x + Machine->uixmin,
			                      y + Machine->uiymin,
			                      x + Machine->uixmin + uifontwidth - 1,
			                      y + Machine->uiymin + Machine->uifontheight - 1);

			drawgfx(bitmap,
				uifont,
				code,
#ifdef UI_COLOR_DISPLAY
				UI_COLOR_NORMAL,
#else
				color,
#endif
				0,
				0,
				x + Machine->uixmin,
				y + Machine->uiymin,
				0,
#ifdef UI_COLOR_DISPLAY
				TRANSPARENCY_PEN,
#else
				TRANSPARENCY_NONE,
#endif
				0);

			x += uifontwidth;

			while (increment)
			{
				c++;
				increment--;
			}

#ifdef UI_COLOR_DISPLAY
			if (col)
				Machine->uifont->colortable[FONT_COLOR_NORMAL] = white;
#endif
		}
	}

#ifdef UI_COLOR_DISPLAY
	if (color == UI_COLOR_INVERSE)
		Machine->uifont->colortable[FONT_COLOR_NORMAL] = white;
#endif

	return next_sy;
}
