/**********************************************************************
 
	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 <string.h>

#include "v/VxlText.h"
#include "v/vobj_utils.h"

extern "C" {
#include	"memory_debug.h"
#include 	"xl.h"
#include	"xlerror.h"



int get_flag_VxlText(L_CHAR * fname);
char * get_writing_direction(int dir);
XL_SEXP * get_VxlTextStatus_battr_LineAttr(TR_LINE_ATTR * a);
XL_SEXP * get_VxlTextStatus_battr_sexp(TR_BOX_ATTR * battr);
XL_SEXP * get_VxlTextStatus_sexp(VxlTextStatus * xsts,int flags);
XL_SEXP * vobj_get_VxlText(XLISP_ENV * env,XL_SEXP * arg,XLISP_ENV * a,XL_SYM_FIELD * sf);
XL_SEXP * vobj_VxlText(XLISP_ENV *env, XL_SEXP *arg, XLISP_ENV *a, XL_SYM_FIELD *sf);


int
get_flag_VxlText(L_CHAR * fname)
{
#define RET_FLAG(value, ff)  if ( l_strcmp(fname, l_string(std_cm, #value)) == 0 ) return ff
	RET_FLAG(xltext.Algorism,VSF_XLTEXT_ALGORISM);
	RET_FLAG(xltext.Editable,VSF_XLTEXT_EDITABLE);
	RET_FLAG(xltext.battr,VSF_XLTEXT_BATTR);
	return 0;
}

char *
get_writing_direction(int dir)
{
char * data;
	switch ( dir ) {
	case VSD_V_L2R:
		data = "VirticalLeftToRight";
		break;
	case VSD_V_R2L:
		data = "VirticalRightToLeft";
		break;
	case VSD_H_L2R:
		data = "HorizontalLeftToRight";
		break;
	case VSD_H_R2L:
		data = "HorizontalRightToLeft";
		break;
	}
	return data;
}

XL_SEXP *
get_VxlTextStatus_battr_LineAttr(TR_LINE_ATTR * a)
{
XL_SEXP * ret;
char * data;
	ret = 0;
	if ( a->flags & TRLF_PITCH ) {
		ret = cons(
			List(n_get_symbol("xltext.battr.LineAttr.Pitch"),
			get_integer(a->pitch,0),
			-1),
			ret );
	}
	if ( a->flags & TRLF_DEFAULT_DIR ) {
		data = get_writing_direction(a->default_dir);
		ret = cons(
			List(n_get_symbol("xltext.battr.LineAttr.DefaultDir"),
				n_get_string(data),
				-1),
			ret);
	}
	if ( a->flags & TRLF_ALIGN ) {
		switch ( a->align ) {
		case TRT_CENTER:
			data = "Center";
			break;
		case TRT_CAPITA_BASIS_ALL:
			data = "CapitaBasisAll";
			break;
		case TRT_LINE_START:
			data = "LineStart";
			break;
		case TRT_LINE_END:
			data = "LineEnd";
			break;
		case TRT_CAPITA_BASIS:
			data = "CapitaBasis";
			break;
		default:
			er_panic("get_VxlTextStatus_battrLineAtter");
		}
		ret = cons(
			List(n_get_symbol("xltext.battr.LineAttr.Align"),
				n_get_string(data),
				-1),
			ret);
	}
	return ret;
}

XL_SEXP *
get_VxlTextStatus_battr_sexp(TR_BOX_ATTR * battr)
{
XL_SEXP * ret;
	ret = 0;
	ret = cons(
		List(n_get_symbol("xltext.battr.MaxDocDirPixels"),
			n_get_integer(battr->max_doc_dir_pixels,0),
			-1),
		ret);
	ret = cons(
		List(n_get_symbol("xltext.battr.MaxLinePixels"),
			n_get_integer(battr->max_line_pixels,0),
			-1),
		ret);
	ret = cons(
		get_VxlTextStatus_battr_LineAttr(&battr->default_lattr),
		ret);
	return ret;
}


XL_SEXP *
get_VxlTextStatus_sexp(VxlTextStatus * xsts,int flags)
{
XL_SEXP * ret;
	ret = 0;
	if ( flags & VSF_XLTEXT_BATTR ) {
		ret = cons(
			get_VxlTextStatus_battr_sexp(&xsts->battr),
			ret);
	}
	if ( flags & VSF_XLTEXT_EDITABLE ) {
		ret = cons(
			List(n_get_symbol("xltext.Editable"),
				get_integer(xsts->editable,0),
				-1),
			ret);
	}
	if ( flags & VSF_XLTEXT_ALGORISM ) {
		switch ( xsts->algorism ) {
		case VXLT_A_DRAW:
			ret = cons(
				List(n_get_symbol("xltext.Algorism"),
					n_get_string("VDraw"),
					-1),
				ret);
			break;
		default:
		case VXLT_A_TEXT:
			ret = cons(
				List(n_get_symbol("xltext.Algorism"),
					n_get_string("VText"),
					-1),
				ret);
			break;
		}		
	}
	return ret;
}


XL_SEXP *
vobj_get_VxlText(XLISP_ENV * env,XL_SEXP * arg,XLISP_ENV * a,XL_SYM_FIELD * sf)
{
XL_SEXP * ret,* ret2;
VStatusFlagsFromFS vsffs[2];
VxlTextStatus xsts;
VObject * obj;
VxlText * tobj;
VExError err;
	vsffs[0].get_flag = get_flag_VxlText;
	vsffs[1].get_flag = 0;
	ret = _vobj_GetStatus(&obj,env,arg,a,sf,vsffs);
	if ( ret == 0 && obj == 0 )
		return ret;
	if ( get_type(ret) == XLT_ERROR || vsffs[0].flags == 0 )
		return ret;
	tobj = dynamic_cast<VxlText*>(obj);
	err = tobj->get_xltext_status(&xsts,vsffs[0].flags);
	if ( err.code ) {
		return vobj_get_error(err,arg);
	}
	ret2 = get_VxlTextStatus_sexp(&xsts,vsffs[0].flags);
	if ( get_type(ret2) == XLT_ERROR )
		return ret2;
	return append(ret,ret2);
}


XL_SEXP *
vobj_VxlText(XLISP_ENV *env, XL_SEXP *arg, XLISP_ENV *a, XL_SYM_FIELD *sf)
{
VExError ex_er;
VObjectStatus _sts;
char * param_ret;
//int flags = get_sts_from_sf(&sts,0, sf, &free_list);
XL_SEXP * p;
VxlText * obj;
L_CHAR * _type,* _ps_flags;
int ps_flags;
XL_SEXP * _ref;
VxlTextStatus xsts;
int x_flags;
VObjectAppStatusAry app[2];

	_ref = vobj_get_VxlText(env,arg,a,sf);
	if ( get_type(_ref) != 0 )
		return _ref;

	_type = get_sf_attribute(sf,l_string(std_cm,"type"));
	_ps_flags = get_sf_attribute(sf,l_string(std_cm,"ps-flags"));
	param_ret = VxlText_get_xltext_from_sf(&xsts,&x_flags,env,sf);
	if ( param_ret )
		goto param_err;
	app[0].sts = (void*)&xsts;
	app[0].flags = x_flags;
	app[1].sts = 0;
	app[1].flags = 0;
	_ref = get_refered_object<VxlText>(&obj,env,arg,sf,VO_XTXT,"VxlText",
			&_sts,0,app);
	if ( get_type(_ref) == XLT_ERROR )
		return _ref;
	if ( _ps_flags ) {
		ps_flags = get_ps_flags(_ps_flags);
		if ( ps_flags == -1 ) {
			param_ret = "ps-flags";
			goto param_err;
		}
	}
	else ps_flags = 0;

	if ( get_type(_ref) != XLT_INTEGER ) {
		ex_er = obj->set_xltext_status(&xsts,x_flags);
		if ( ex_er.code != V_ER_NO_ERR )
			goto err2;
	}
	p = gb_quote_trace(env,cdr(arg),_type);
	if ( get_type(p) != XLT_NULL )
		obj->set_xl_sexp_loop(env,p,ps_flags);
	if ( get_type(_ref) == XLT_INTEGER )
		return vobj_get_id_list(_ref->integer.data, 0, sf,OIF_INTERNAL);
	else	return 0;
err2:
	obj->destroy();
	return vobj_get_error(ex_er, arg);
param_err:
	return get_error(
		arg->h.file,
		arg->h.line,
		XLE_PROTO_INV_PARAM,
		l_string(std_cm,"VxlText"),
		List(n_get_string("invalid param of attribute ::"),
			n_get_string(param_ret),
			-1));
}

void
init_vobj_VxlText(XLISP_ENV *env)
{
	set_env(env,l_string(std_cm,"VxlText"),
		get_func_prim((XL_SEXP*(*)())vobj_VxlText,FO_NORMAL,0,1,-1));
}


} // extern "C"
