/**********************************************************************
 
	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	<stdlib.h>
#include	"memory_debug.h"
#include	"v.h"
#include	"long_char.h"
#include	"stream.h"
#include	"machine/msequence.h"
#include	"machine/v_types.h"
#include	"lc_encode.h"


typedef struct v_get_string_pic_s{
	LC_STRING_PIC * p;
	LCF_SET * str;
	int	len;
	int dir;
	VFONT * vfont;
}V_GET_STRING_PIC_S;

extern LC_FONT_ENGINE_TYPE win_font_engine_type;


static void lcf_set2w(wchar_t *buf, LCF_SET *str, int len){
	for(;len; ++str, ++buf, --len){
		*buf = (wchar_t) (str->ch & 0xffff);
	}
}

static void lcf_set2c(char *buf, LCF_SET *str, L_CHAR mask, int len){
	
	if ( mask == LCZM_7b_TYPE ) {
		for (; len; ++str,--len)
			*buf++ = (char)(str->ch & 0x7f);
	}
	else if ( mask == LCZM_1B_TYPE ) {
		for (; len; ++str,--len)
			*buf++ = (char)(str->ch & 0xff);
	}
	else if ( mask == LCZM_2B_TYPE ) {
		for (; len; ++str,--len){
			if ( (str->ch>>8) & 0xff )
				*buf++ = (char)((str->ch>>8) & 0xff);
			*buf++ = (char)(str->ch & 0xff);
		}
	}
	else if ( mask == LCZM_3B_TYPE ) {
		for (; len; ++str,--len){
			if ( (str->ch>>16) & 0xff ) {
				*buf++ = (char)((str->ch>>16) & 0xff);
				*buf++ = (char)((str->ch>>8) & 0xff);
			}
			else if( (str->ch>>8) & 0xff ){
				*buf++ = (char)((str->ch>>8) & 0xff);
			}
			*buf++ = (char)(str->ch & 0xff);
		}
	}
	else
		er_panic("lcf_set2c");
	*buf = 0;
}

int _v_get_string_pic(V_GET_STRING_PIC_S *v){

LC_STRING_PIC * p = v->p;
LCF_SET * str = v->str;
int	size = str->size;
int dir = v->dir;
int len = v->len;
L_CHAR mask;
VFONT * vfont = v->vfont;
char *char_buffer;
wchar_t *wchar_buffer;

VPOINT point;
HDC hdcMem;
HDC hdcDisplay;
HBITMAP hBitmap,hOldBitmap;
HFONT hFont,hOldFont;
RECT rect;
BYTE *pbyteBuff;
BITMAPINFO bi;
int w,h;
int use_wstring;

	mask = get_lc_mask(str->ch);
	switch(str->ch & mask){
		case LCZ_2BC_UNICODE_v1_1_JP:
		case LCZ_2BC_UNICODE_v1_1_TW:
		case LCZ_2BC_UNICODE_v1_1_CN:
		case LCZ_2BC_UNICODE_v1_1_KR:
		case LCZ_2BC_UNICODE_v2_0_JP:
		case LCZ_2BC_UNICODE_v2_0_TW:
		case LCZ_2BC_UNICODE_v2_0_CN:
		case LCZ_2BC_UNICODE_v2_0_KR:
		case LCZ_2BC_UNICODE_v3_0_JP:
		case LCZ_2BC_UNICODE_v3_0_TW:
		case LCZ_2BC_UNICODE_v3_0_CN:
		case LCZ_2BC_UNICODE_v3_0_KR:
		case LCZ_2BC_UNICODE_v1_1_UN:
		case LCZ_2BC_UNICODE_v2_0_UN:
		case LCZ_2BC_UNICODE_v3_0_UN:
		case LCZ_2BC_UNICODE_v1_1_UN_CN:
		case LCZ_2BC_UNICODE_v2_0_UN_CN:
		case LCZ_2BC_UNICODE_v3_0_UN_CN:
			{
				wchar_buffer = (wchar_t*)d_alloc((len+1)*sizeof(wchar_t));
				memset(wchar_buffer, 0, (len+1)*sizeof(wchar_t));
				lcf_set2w(wchar_buffer, str, len);
				use_wstring = 1;
			}
			break;
		default:
			{
				char_buffer = (char*)d_alloc(len*3+1);
				memset(char_buffer, 0, len*3+1);
				lcf_set2c(char_buffer, str, mask, len);
				use_wstring = 0;
			}
	}
	
	hdcDisplay = GetDC(0);
	hdcMem = CreateCompatibleDC(hdcDisplay);
	vfont->lfHeight = 12;
	vfont->lfWidth = 0;
	hFont = CreateFontIndirectW(vfont);
	hOldFont = SelectObject(hdcMem, hFont);
	memset(&rect,0,sizeof(RECT));
	if(use_wstring){
		DrawTextW(hdcMem, wchar_buffer, wcslen(wchar_buffer), &rect, DT_CALCRECT);
	}
	else{
		DrawTextA(hdcMem, char_buffer, strlen(char_buffer), &rect, DT_CALCRECT);
	}
	
	point.x = 0;point.y = 0;p->r.tl = point;
	point.x = rect.right;point.y = rect.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, &rect, GetStockObject(WHITE_BRUSH));
	if(use_wstring){
		DrawTextW(hdcMem, wchar_buffer, wcslen(wchar_buffer), &rect, DT_LEFT | DT_NOCLIP | DT_EXPANDTABS);
	}
	else{
		DrawTextA(hdcMem, char_buffer, strlen(char_buffer), &rect, 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);
	{
		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_V_L2R;

	return 0;
}


void
v_get_string_pic(
	LC_STRING_PIC * p,
	int 		dir,
	LCF_SET *	str,
	int len)
{
V_GET_STRING_PIC_S v;

	if ( str->font->fw_list[0].fe->type != &win_font_engine_type ) {
		memset(p,0,sizeof(*p));
		return;
	}
	
	v.p = p;
	v.dir = dir;
	v.str = str;
	v.len = len;
	v.vfont = (VFONT*)(str->font->fw_list[0].work);
	ms_do(_v_get_string_pic, &v, "v_get_string_pic");
}

