/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	This program is distributed in the hope that it will be 
	useful, but WITHOUT ANY WARRANTY; without even the 
	implied warranty of MERCHANTABILITY or FITNESS FOR A 
	PARTICULAR PURPOSE.

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

#include	"memory_debug.h"
#include "v.h"
#include	"long_char.h"
#include	"stream.h"
#include	"machine/msequence.h"

extern CODE_METHOD euc_cm, jis_cm,sjis_cm;

typedef struct xchar2b
{
	unsigned char byte1;
	unsigned char byte2;
}XChar2b;

void
get_strbuf(char ** bufp,XChar2b ** buf16p,int * lenp,L_CHAR * str,int len,
        L_CHAR mask)
{
int i;
char * buf;
XChar2b * buf16;

int dst;
	buf16 = d_alloc(sizeof(XChar2b)*len,13);
	buf = d_alloc(len,12);
	dst = 0;

	for ( i = 0 ; i < len ; i ++ ) {
		buf16[dst].byte2 = (unsigned char)(str[i]&0xff);
		buf16[dst].byte1 = (unsigned char)((str[i]>>8)&0xff);
		if ( mask == LCZM_7b_TYPE )
			buf[dst++] = (unsigned char)(str[i]|0x80);
		else    
			buf[dst++] = (unsigned char)str[i];
	}
	*bufp = buf;
	*buf16p = buf16;
	*lenp = dst;

/*
int i,j;
char * buf;
XChar2b * buf16;
char * b1;
L_CHAR * b2;
int dst;
	buf16 = d_alloc(sizeof(XChar2b)*len,13);
	buf = d_alloc(len,12);
	dst = 0;
	
	switch ( font_type ) {
	case LCZ_2BC_JIS:
		for ( i = 0 ; i < len ; i ++ ) {
			buf16[dst].byte2 = str[i]&0xff;
			buf16[dst].byte1 = (str[i]>>8)&0xff;
			buf[dst++] = '?';
		}
		break;
	case LCZ_1BC_ASCII:
		for ( i = 0 ; i < len ; i ++ ) {
			buf16[dst].byte2 = '?';
			buf16[dst].byte1 = '?';
			buf[dst++] = str[i];
		}
		break;
	default:
		for ( i = 0 ; i < len ; i ++ ) {
			buf16[dst].byte2 = '?';
			buf16[dst].byte1 = '?';
			buf[dst++] = '?';
		}
	}
	*bufp = buf;
	*buf16p = buf16;
	*lenp = dst;
*/

}

void
v_get_string_pic_call(
	V_STRING_PIC * p,
	VDISPLAY * disp,
	L_CHAR * str,
	int len,
	VFONT * vf,
	int	size,
	int dir,
	L_CHAR mask)
{
unsigned char * buf;
int w,h;


HDC hdcMem;
HDC hdcDisplay;
HBITMAP hBitmap,hOldBitmap;
HFONT hFont,hOldFont;
RECT rc;
VPOINT point;
BYTE *pbyteBuff;
BITMAPINFO bi;
L_CHAR *tmp;
	tmp = malloc(sizeof(L_CHAR)*(len+1));
	memset(tmp,0,sizeof(L_CHAR)*(len+1));
	memcpy(tmp,str,sizeof(L_CHAR)*len);
	buf = n_string(&sjis_cm, tmp);
	free(tmp);
	hdcDisplay = GetDC(0);
	hdcMem = CreateCompatibleDC(hdcDisplay);
	
	hFont = CreateFontIndirect(&vf->lf);
	
	//hFont = CreateFont(12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, SHIFTJIS_CHARSET, OUT_TT_ONLY_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, VARIABLE_PITCH|FF_ROMAN, "‚l‚r ƒSƒVƒbƒN");
	hOldFont = SelectObject(hdcMem,hFont);

	memset(&rc,0,sizeof(RECT));
	DrawText(hdcMem,buf,strlen(buf),&rc,DT_CALCRECT);

	point.x = 0;point.y = 0;p->r.tl = point;
	point.x = rc.right;point.y = rc.bottom;p->r.br = point;
	p->width = p->r.br.x - p->r.tl.x;
	w = p->r.br.x - p->r.tl.x;
	h = p->r.br.y - p->r.tl.y;

	bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bi.bmiHeader.biPlanes = 1;
	bi.bmiHeader.biBitCount = 32;
	bi.bmiHeader.biCompression = BI_RGB;
	bi.bmiHeader.biSizeImage = 0;
	bi.bmiHeader.biXPelsPerMeter = 0;
	bi.bmiHeader.biYPelsPerMeter = 0;
	bi.bmiHeader.biClrUsed = 0;
	bi.bmiHeader.biClrImportant = 0;
	bi.bmiHeader.biWidth = w;
	bi.bmiHeader.biHeight = -h;
	hBitmap = CreateDIBSection(hdcMem,&bi,DIB_RGB_COLORS,NULL,NULL,0);
	hOldBitmap = SelectObject(hdcMem,hBitmap);

	FillRect(hdcMem, &rc, GetStockObject(WHITE_BRUSH));
	DrawText(hdcMem, buf, strlen(buf), &rc, DT_LEFT | DT_NOCLIP | DT_EXPANDTABS);

	pbyteBuff = calloc(sizeof(BYTE),w*h*4);
	GetDIBits(hdcMem, hBitmap, 0, h, pbyteBuff, &bi, DIB_RGB_COLORS);

	p->pic = d_alloc(w*h,23);
	{
		int nDest=0, nSrc=0;
		int nPixcel=0;
		for(nPixcel=0;nPixcel<w*h*4;nPixcel+=4)
		{
			if(pbyteBuff[nPixcel] == 0)
				p->pic[nDest] = (char)0;
			else
				p->pic[nDest] = (char)255;
			++nDest;
		}
	}
	free(pbyteBuff);
	DeleteObject(SelectObject(hdcMem, hOldBitmap));
	DeleteObject(SelectObject(hdcMem,hOldFont));
	DeleteObject(hdcMem);
	ReleaseDC(0,hdcDisplay);
	p->dir = VSD_L2R;
}
void
compose_pic(V_STRING_PIC * p,V_STRING_PIC * pp)
{
V_STRING_PIC ppp;
int w,h,ww,hh;
int x,y,i;
int y_ofs,x_ofs;
	ppp.width = p->width + pp->width;
	ppp.dir = p->dir;
	ppp.r.tl.x = p->r.tl.x;
	if ( p->r.tl.y < pp->r.tl.y )
		ppp.r.tl.y = p->r.tl.y;
	else	ppp.r.tl.y = pp->r.tl.y;
	ppp.r.br.x = p->width + pp->r.br.x;
	if ( p->r.br.y < pp->r.br.y )
		ppp.r.br.y = pp->r.br.y;
	else	ppp.r.br.y = p->r.br.y;
	w = ppp.r.br.x - ppp.r.tl.x;
	h = ppp.r.br.y - ppp.r.tl.y;
	ppp.pic = d_alloc(w*h,230);
	for ( i = 0 ; i < w*h ; i ++ )
		ppp.pic[i] = 255;
	ww = p->r.br.x - p->r.tl.x;
	hh = p->r.br.y - p->r.tl.y;
	y_ofs = p->r.tl.y - ppp.r.tl.y;
	i = 0;
	for ( y = y_ofs ; y < hh+y_ofs ; y ++ )
		for ( x = 0 ; x < ww ; x ++ )
			ppp.pic[x + y*w] = p->pic[i++];
	x_ofs = -ppp.r.tl.x+p->width+pp->r.tl.x;
	y_ofs = pp->r.tl.y - ppp.r.tl.y;
	ww = pp->r.br.x - pp->r.tl.x;
	hh = pp->r.br.y - pp->r.tl.y;
	i = 0;
	for ( y = y_ofs ; y < hh+y_ofs ; y ++ )
		for ( x = x_ofs ; x < ww+x_ofs ; x ++ ){
			if ( pp->pic[i] != 255 )
				ppp.pic[x + y*w] = pp->pic[i];
			i ++;
		}
	d_f_ree(p->pic);
	d_f_ree(pp->pic);
	*p = ppp;
}

typedef struct v_get_string_pic_s{
	V_STRING_PIC * p;
	VDISPLAY * disp;
	L_CHAR * str;
	int	size;
	int dir;
	VFONT * vf;
	L_CHAR mask;
}V_GET_STRING_PIC_S;


int _v_get_string_pic(V_GET_STRING_PIC_S *v){

V_STRING_PIC * p = v->p;
VDISPLAY * disp = v->disp;
L_CHAR * str = v->str;
int	size = v->size;
int dir = v->dir;
VFONT * vf = v->vf;

int len;
int i,j;
V_STRING_PIC pp;
L_CHAR unknown;
int f;
WRITABLE_CODE_TABLE * t;

	len = l_strlen(str);

	unknown = '?';
	f = 0;
	for ( i = 0 ; i < len ; ) {
		t = get_wct(disp->font_work,str[i]);
		if ( t ) {
			for ( j = i ; j < len &&
				(str[j]&t->mask) == t->lcz ; j ++ );
			v_get_string_pic_call(
				&pp,
				disp,
				&str[i],
				j-i,
				t->work,
				size,
				dir,
				t->mask);
			i = j;
		}
		else {
			printf("aaaaaaaaaa %x\n",str[i]);
			v_get_string_pic_call(
				&pp,
				disp,
				&unknown,
				1,
				&disp->iso8859_1,
				size,
				dir,
				t->mask);
			i ++;
		}
		if ( f == 0 ) {
			*p = pp;
			f = 1;
		}
		else {
			compose_pic(p,&pp);
		}
	}
	return 0;
}

void v_get_string_pic(
	V_STRING_PIC * p,
	VDISPLAY * disp,
	L_CHAR * str,
	int	size,
	int 	dir)
{
	V_GET_STRING_PIC_S v;
	v.p = p;
	v.disp = disp;
	v.str = str;
	v.size = size;
	v.dir = dir;
	ms_do(_v_get_string_pic, &v, "v_get_string_pic");
}