/**********************************************************************
 
	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	<stdio.h>
#include	"machine/dummy_x11.h"
#include	"memory_debug.h"





void
v_draw_text(VOBJECT * obj)
{
int i,j;
int f;
int write_len;
int len;
LCF_SET * str;
VPOINT st;
VRECT rct,r;
LC_FONT * lf;
VFONT * vf;
LC_FONT_ENGINE * fe;
LC_FONT_ENGINE * fe_list[2];
LC_FONT_WORK * w;
int size;
LC_WS_COND c;

	fe = v_get_font_engine(obj);
	fe_list[0] = fe;
	fe_list[1] = 0;
	c.fe = &fe_list[0];
	c.cond = WSC_FE_LIST|WSC_PIC_REQUIRED;

	len = obj->vtext.in.length;
	str = ws_convert(
		obj->vtext.in.ws,
		&c,
		obj->vtext.in.size,
		obj->vtext.in.data,
		obj->vtext.in.length,
		0);
	st.x = obj->vtext.in.st_x;
	st.y = obj->vtext.in.st_y;
	obj->vtext.in.minrect.tl.x = obj->vtext.in.minrect.tl.y = 0;
	obj->vtext.in.minrect.br.x = obj->vtext.in.minrect.br.y = -1;
	for ( i = 0 ; i < len ; ) {
		lf = str[i].font;
		size = str[i].size;
		for ( j = i ; j < len && str[j].font == lf &&
			str[j].size == size ; j ++ );
		w = get_font_work(lf,fe);
		if ( w ) {
			vf = (VFONT*)w->work;
			v_draw_text_one_font(
					&r,
					obj,
					&st,
					&str[i],
					j-i,
					vf,
					str[i].size,
					get_lc_mask(str[i].ch));
		}
		else {
			er_panic("unimprement");
		}
		i = j;
		marge_vrect(&obj->vtext.in.minrect,&r);
	}
	d_f_ree(str);
}


int
_v_redraw_text(VOBJECT*args)
{

	v_draw_text(args);
	return 0;
}

void v_redraw_text(VTEXT * vt)
{
	ms_do((int (*)(void*))_v_redraw_text,(void*)vt,1,"v_redraw_text");
}


void
v_text_handler(
	VOBJECT *	obj,
	int		cmd)
{
	switch ( cmd ) {
	case VE_REDRAW:
		v_redraw_text(&obj->vtext);
		break;
	case VE_BUTTON:
		break;
	default:
		fprintf(stderr,"v_text::unsupport cmd %i\n",cmd);
	}
}



typedef struct v_set_text_s {
	VERROR * err;
	VOBJECT * obj;
	LC_WRITING_STYLE * ws;
	unsigned long color;
	unsigned long background;
	L_CHAR * data;
	int	length;
} V_SET_TEXT_S;


typedef struct v_create_text {
	VOBJECT *	ret;
	VERROR *	err;

	VWINDOW *	win;
	unsigned long	color;
	unsigned long	background;
	LC_WRITING_STYLE *	ws;
	int		size;
	int		dir;
	int		st_x;
	int 		st_y;
	L_CHAR *	data;
	int		length;
} V_CREATE_TEXT_S;



int
_v_create_text(V_CREATE_TEXT_S * v)
{
VOBJECT * obj;
int fid;
VWINDOW *	win;
unsigned long	color;
unsigned long	background;
int		st_x;
int 		st_y;
char *		fname;
L_CHAR *	data;
int		length;
LCF_SET * s;

	win = v->win;
	color = v->color;
	background = v->background;
	st_x = v->st_x;
	st_y = v->st_y;
	data = v->data;
	length = v->length;

	obj = d_alloc(sizeof(VTEXT));
	obj->vtext.in.st_x = st_x;
	obj->vtext.in.st_y = st_y;
	obj->vtext.in.ws = v->ws;
	obj->vtext.in.data = d_alloc(sizeof(L_CHAR)*length);
	memcpy(obj->vtext.in.data,data,sizeof(L_CHAR)*length);
	obj->vtext.in.length = length;
	obj->vtext.in.color = color;
	obj->vtext.in.background = background;
	obj->vtext.in.size = v->size;
	obj->vtext.in.dir = v->dir;
	obj->header.type = VT_TEXT;
	obj->header.handler = v_text_handler;
	obj->header.win = win;
	obj->header.next = win->obj_list;
	win->obj_list = obj;
	v->err->err1 = E_OK;

	v_draw_text(obj);
	v_after_handling(obj);
	v->ret = obj;
	return 0;
}

VOBJECT *
v_create_text(VERROR * err,
	VWINDOW *	win,
	unsigned long	color,
	unsigned long	background,
	LC_WRITING_STYLE *	ws,
	int		size,
	int		dir,
	int		st_x,
	int 		st_y,
	L_CHAR *	data,
	int		length)
{
V_CREATE_TEXT_S v;
	v.err = err;
	v.win = win;
	v.color = color;
	v.background = background;
	v.size = size;
	v.dir = dir;
	v.st_x = st_x;
	v.st_y = st_y;
	v.data = data;
	v.length = length;
	v.ret = 0;
	v.ws = ws;
	ms_do((int (*)(void*))_v_create_text,&v,1,"v_create_text");
	return v.ret;
}


int
_v_set_text(void * args)
{
V_SET_TEXT_S *pvst = (V_SET_TEXT_S*)args;
VERROR * err = pvst->err;
VOBJECT * obj = pvst->obj;
unsigned long color = pvst->color;
unsigned long background = pvst->background;
L_CHAR *data = pvst->data;
LC_WRITING_STYLE * ws = pvst->ws;
int	length = pvst->length;
int i;
/*
printf("##### start v_set_text(threadID:=%d)\n",get_tid());fflush(stdout);
*/

	if ( !(color & C_NULL) ) {
		obj->vtext.in.color = color;
	}
	if ( !(background & C_NULL) ) {
		obj->vtext.in.background = background;
	}
	if ( obj->header.type != VT_TEXT ) {
		err->err1 = E_PARAM;
		err->err2 = 0;
	}
	if ( ws )
		obj->vtext.in.ws = ws;

	if ( data ) {
		d_f_ree(obj->vtext.in.data);
		obj->vtext.in.data = d_alloc(length*sizeof(L_CHAR));
		memcpy(obj->vtext.in.data,data,length*sizeof(L_CHAR));
		obj->vtext.in.length = length;
	}


	v_draw_text(obj);
/*
printf("end Draw\n");fflush(stdout);
*/
	v_after_handling(obj);
	err->err1 = E_OK;
/*
printf("end v_set_text\n");fflush(stdout);
*/
	return 0;
}


int 
v_set_text(VERROR * err,
	VOBJECT * obj,
	unsigned long color,
	unsigned long background,
	LC_WRITING_STYLE * ws,
	L_CHAR *data,
	int	length)
{
V_SET_TEXT_S vst;

	vst.ws = ws;
	vst.obj = obj;
	vst.color = color;
	vst.background = background;
	vst.length = length;	
	vst.data = data;
	vst.err = err;

	ms_do(_v_set_text, (void *)&vst,1, "v_set_text");

	return 0;
}

typedef struct _v_move_text_s {
	int		x;
	int		y;
	VOBJECT *	obj;
} _V_MOVE_TEXT_S;

int
_v_move_text(_V_MOVE_TEXT_S * t)
{
	t->obj->vtext.in.st_x = t->x;
	t->obj->vtext.in.st_y = t->y;
	v_draw_text(t->obj);
	return 0;
}

void
v_move_text(VOBJECT * obj,int x,int y)
{
_V_MOVE_TEXT_S v;
	v.x = x;
	v.y = y;
	v.obj = obj;
	ms_do((int (*)(void*))_v_move_text,&v,1,"v_move_text");
}

typedef struct v_text_minrect_s {
	VRECT *		r;
	VOBJECT *	obj;
} V_TEXT_MINRECT_S;


int
_v_text_minrect(void *args)
{

V_TEXT_MINRECT_S *vtm = (V_TEXT_MINRECT_S*)args;
VRECT* r = vtm->r;
VOBJECT *obj = vtm->obj;


	*vtm->r = obj->vtext.in.minrect;

	return 0;
}

int 
v_text_minrect(VRECT * r,VOBJECT * obj)
{

V_TEXT_MINRECT_S vtm;
	vtm.r = r;
	vtm.obj = obj;
	
	ms_do(_v_text_minrect,(void*)&vtm,1,"v_text_minrect");
	
	return 0;
}



