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

  ui_font.c

  NMAMEで日本語文字列を処理する関数を提供します。

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

#include "driver.h"
#ifdef KAILLERA
#include "KailleraChat.h"
#endif /* KAILLERA */
#include "osd_pal.h"

#ifdef JAPANESE

static UINT16 _uifonttable[65536];
static UINT32 colortable[MAX_COLORTABLE];

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

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

#define ISSJIS1(c) ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xfc))
#define ISSJIS2(c) ((c >= 0x40 && c <= 0xfc) && (c != 0x7f))

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

#undef ISSJIS1
#undef ISSJIS2

#else

int uifont_decodechar(unsigned char *s, unsigned short *code)
{
    *code = *s;
    return 1;
}

#endif

int uifont_drawfont(struct mame_bitmap *bitmap, const char *s, int sx,
                    int sy, int color)
{
#ifndef UI_COLOR_DISPLAY
    extern int iTrans;
    extern int iTransOpt;
#endif /* !UI_COLOR_DISPLAY */
    int x, y, wrapped, next_sy, increment, uifontwidth;
    int white = 0;
#ifdef UI_COLOR_DISPLAY
	int white_inv = 0;  /* Fixed command font color bug */
	int white_disp = 0; /* Fixed display font color bug */
#endif /* UI_COLOR_DISPLAY */
    unsigned short code;
    unsigned char *c;
    struct GfxElement *uifont;
#ifdef KAILLERA
    int colormode;
    int pos = 0;
    unsigned char *attr = NULL;
    int *clause = NULL;
    extern int nChatDrawMode;

    if (color == UI_COLOR_TRANS && nChatDrawMode)
        colormode = TRANSPARENCY_PEN;
    else
        colormode = TRANSPARENCY_NONE;

    if (color == UI_COLOR_ATTRIBUTE)
    {
        attr   = KailleraChatGetStrAttr();
        clause = KailleraChatGetStrClause();
    }
#endif /* KAILLERA */
    c      = (unsigned char *)s;
    x      = sx;
    y      = sy;
    code   = 0;
    next_sy = 0;

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

    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
        {
#ifdef JAPANESE
            if (code > 0x00ff)
            {
                uifont      = Machine->uifont2;
                uifontwidth = Machine->uifontwidth * 2;
#ifdef KAILLERA
                if (attr)
                {
                    color = attr[pos];
                    pos += 2;
                }
#endif /* KAILLERA */
            }
            else
#endif
            {
                uifont      = Machine->uifont;
                uifontwidth = Machine->uifontwidth;
#ifdef KAILLERA
                if (attr)
                {
                    color = attr[pos];
                    pos++;
                }
#endif /* KAILLERA */
            }
        }

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

        if (!wrapped)
        {
            int col = 0;

#ifdef JAPANESE
            if (code > 0x00ff)
            {
                code -= 256;
                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

#ifdef UI_COLOR_DISPLAY
			if ((color == UI_COLOR_BOLD || color == UI_COLOR_BLACK) && col == 0)
			{
				white_disp = Machine->uifont->colortable[FONT_COLOR_NORMAL];
				if (color == UI_COLOR_BOLD)
					Machine->uifont->colortable[FONT_COLOR_NORMAL] = Machine->uifont->colortable[SYSTEM_COLOR_FRAMELIGHT];
				else
					Machine->uifont->colortable[FONT_COLOR_NORMAL] = Machine->uifont->colortable[SYSTEM_COLOR_FRAMEDARK];

				drawgfx(bitmap,
					uifont,
					code,
					UI_COLOR_NORMAL,
					0,
					0,
					x + Machine->uixmin + 1,
					y + Machine->uiymin,
					0,
					TRANSPARENCY_PEN,
					0);

				Machine->uifont->colortable[FONT_COLOR_NORMAL] = white_disp;
			}

			if (color == UI_COLOR_BLACK && col == 0)
			{
				white_disp = Machine->uifont->colortable[FONT_COLOR_NORMAL];
				Machine->uifont->colortable[FONT_COLOR_NORMAL] = Machine->uifont->colortable[FONT_COLOR_BLANK];
			}
#endif /* UI_COLOR_DISPLAY */

            drawgfx(bitmap,
                uifont,
                code,
#ifdef KAILLERA
                (color == UI_COLOR_BACKBLACK) ? UI_COLOR_BACKBLACK : UI_COLOR_NORMAL,
#else /* KAILLERA */
                UI_COLOR_NORMAL,
#endif /* KAILLERA */
                0,
                0,
                x + Machine->uixmin,
                y + Machine->uiymin,
                0,
#ifdef UI_COLOR_DISPLAY
				TRANSPARENCY_FONT,
#else /* UI_COLOR_DISPLAY */
                (iTransOpt && iTrans) ? TRANSPARENCY_FONT : TRANSPARENCY_NONE,
#endif /* UI_COLOR_DISPLAY */
                0);

#ifdef UI_COLOR_DISPLAY
			if (color == UI_COLOR_BLACK && col == 0)
			{
				Machine->uifont->colortable[FONT_COLOR_NORMAL] = white_disp;
			}
#endif /* UI_COLOR_DISPLAY */

            x += uifontwidth;

            while (increment)
            {
                c++;
                increment--;
            }
            if (col)
                Machine->uifont->colortable[FONT_COLOR_NORMAL] = white;
        }
    }

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

    return next_sy;
}

#ifdef KAILLERA
int uifont_drawfont_back(struct mame_bitmap *bitmap, const char *s, int sx,
                    int sy, int color)
{
    int x, y, wrapped, next_sy, increment, uifontwidth;
    unsigned short code;
    unsigned char *c;
    struct GfxElement *uifont;
    int pos = 0;
    unsigned char *attr = NULL;
    int *clause = NULL;

	int ret = 1;
	if ((color & UI_COLOR_MASK) >= UI_COLOR_SHADOW && (color & UI_COLOR_MASK) <= UI_COLOR_FRAME_3)
		ret = 0;
    
	if (color == UI_COLOR_ATTRIBUTE)
    {
        attr   = KailleraChatGetStrAttr();
        clause = KailleraChatGetStrClause();
		ret = 0;
    }

	if (ret)	return 0;

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

    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;
                if (attr)
                {
                    color = attr[pos];
                    pos += 2;
                }
            }
            else
            {
                uifont      = Machine->uifont;
                uifontwidth = Machine->uifontwidth;
                if (attr)
                {
                    color = attr[pos];
                    pos++;
                }
            }
        }

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

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

			if ((color & UI_COLOR_MASK) >= UI_COLOR_SHADOW && (color & UI_COLOR_MASK) <= UI_COLOR_FRAME_3)
			{
				const int posx[12] = { 0,-2, 2, 0, 0,-1, 1, 0,-1,-1, 1, 1};
				const int posy[12] = {-2, 0, 0, 2,-1, 0, 0, 1,-1, 1,-1, 1};
				int i=4,j=12;

				if ((color & UI_COLOR_MASK) == UI_COLOR_SHADOW) i=11;
				if ((color & UI_COLOR_MASK) == UI_COLOR_FRAME)	j=8;
				if ((color & UI_COLOR_MASK) == UI_COLOR_FRAME_3) i=0;

				for (; i<j; i++)
					drawgfx(bitmap,
		                uifont,
						code,
						UI_COLOR_INVERSE,
						0,
						0,
						x + Machine->uixmin+posx[i],
						y + Machine->uiymin+posy[i],
						0,
						TRANSPARENCY_PEN,
						0);
			}

            x += uifontwidth;

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

    return next_sy;
}
#endif /* KAILLERA */
