/**********************************************************************
 
	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	"utils.h"
#include	"long_char.h"
#include	"lc_encode.h"
#include	"text_render.h"
#include	"tr_lang.h"


TR_ERROR
make_ja_render(TR_SEQUENCE * ,TR_CHAR_INFO *);
void
setup_ja_render(TR_LANG * lang,int type,void * work);
void *
get_ja_render(TR_LANG *,void *);
void
free_ja_work(void *);


TR_LANG ja_render = {
	"ja",
	VSD_H_L2R,VSD_H_R2L,
	setup_ja_render,
	get_ja_render,
	free_ja_work,
	make_ja_render,
	0
};

void
free_ja_work(void * _w)
{
JA_WORK * w;
	w = _w;
	if ( w->line_end_escape_delim )
		d_f_ree(w->line_end_escape_delim);
	if ( w->line_top_escape_delim )
		d_f_ree(w->line_top_escape_delim);
	d_f_ree(w);
}

void *
get_ja_render(TR_LANG * lang,void * w)
{
JA_WORK * wp;
JA_WORK * out;
	if ( w )
		out = w;
	else	out = d_calloc(sizeof(JA_WORK),1);
	wp = lang->work;
	*out = *wp;
	if ( wp->line_end_escape_delim )
		out->line_end_escape_delim = ll_copy_str(
				wp->line_end_escape_delim);
	else	out->line_end_escape_delim = 0;
	if ( wp->line_top_escape_delim )
		out->line_top_escape_delim = ll_copy_str(
				wp->line_top_escape_delim);
	else	out->line_top_escape_delim = 0;
	return out;
}

void
setup_ja_render(TR_LANG * lang,int type,void * work)
{
JA_WORK * w, * wp;
	switch ( type ) {
	case TRT_INIT_BIN:
		w = (JA_WORK*)work;
		if ( lang->work )
			free_ja_work(lang->work);
		lang->work = d_alloc(sizeof(*w));
		wp = lang->work;
		memset(wp,0,sizeof(*wp));
		if ( w == 0 )
			break;
		*wp = *w;
		wp->line_end_escape_delim = 
			ll_copy_str(w->line_end_escape_delim);
		wp->line_top_escape_delim = 
			ll_copy_str(w->line_top_escape_delim);
		break;
	default:
		er_panic("setup_ja_render(1)");
	}
	if ( wp->dir == 0 )
		wp->dir = VSD_V_R2L|VSD_H_L2R;
}

TR_ERROR
make_ja_render(TR_SEQUENCE * sq,TR_CHAR_INFO * ci)
{
TR_ERROR e;
TR_PTR p;
TR_CHAR_ELEMENT * el;
TR_PTR_STACK *pos_stack;
TR_CHAR_INFO target;
TR_LL_CTL	ctl;
JA_WORK * w;
int gyo_tou_kinshi,gyo_matsu_kinshi,st;

	w = ci->lang->work;
	if ( ci->box_line->attr.default_dir & VSD_V )
		ci->lang_line->dir = w->dir & VSD_V;
	else	ci->lang_line->dir = w->dir & VSD_H;
	pos_stack = 0;
	_tr_push_ptr_stack(&pos_stack,ci->p);
	(*sq->box_op->start_lang_line_op)(sq,ci);
	gyo_matsu_kinshi = 0;
	gyo_tou_kinshi = 0;
	for ( p = ci->p ; ; ) {
		e.code = TRE_OK;
		e.subcode = TRE_OK_NONE;
		if ( p.buf == 0 )
			break;
		if ( p.ptr >= p.buf->buf_len )
			break;
		_tr_get_char_info(&target,sq,p);
		if ( _tr_lang_area_cmp_ci(sq,ci,&target) )
			break;
		if ( gyo_matsu_kinshi == 1 )
			st = 0;
		else	st = 1;
		el = &p.buf->element_buf[p.ptr];
		if ( in_table(el->ch,w->line_end_escape_delim) == 0 )
			gyo_matsu_kinshi = 1;
		else	gyo_matsu_kinshi = 0;
		if ( in_table(el->ch,w->line_top_escape_delim) == 0 ) {
			gyo_tou_kinshi = 1;
			st = 0;
		}
		else 	gyo_tou_kinshi = 0;
		if ( st )
			_tr_push_ptr_stack(&pos_stack,p);
		ctl.h.cmd = LLC_WEIGHT;
		ctl.w.weight = TRW_DONTCARE;
		e = (*sq->box_op->lang_line_ctl)(sq,ci,&ctl);
		if ( e.code == TRE_OK )
			e = (*sq->box_op->put_box_line)(sq,ci,p,el);
	ctl_err:
		switch ( e.code ) {
		case TRE_INSERT_CHAR:
			for ( ; ; ) {
				p = _tr_pop_ptr_stack(&pos_stack);
				e = (*sq->box_op->pop_box_line)(sq,ci,p);
				if ( e.code == TRE_OK )
					break;
			}
			e.subcode = TRE_OK_NEW_LINE;
			goto end;
		case TRE_INSERT_LINE:
			p = ci->p;
			goto end;
		case TRE_OK:
			break;
		}
		e = (*sq->box_op->lang_line_ctl)(sq,ci,&ctl);
		if ( e.code != TRE_OK )
			goto ctl_err;
	/* next: */
		p = tr_ptr_next(p);
	}
end:
	ci->lang_line->end = p;
	e = _tr_stop_lang_line_op(e,sq,ci);
	_tr_free_ptr_stack(&pos_stack);
	return e;
}

