/**********************************************************************
 
	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	"xlerror.h"
#include	"memory_routine.h"
#include	"utils.h"
#include	"xl.h"
#include	"resource.h"
#include	"lock_level.h"
#include	"task.h"

int default_dgb_pixel = DEFAULT_DGB_PIXEL;
SEM draw_lock;

void
init_vector()
{
	draw_lock = new_lock(LL_DRAW);

}

void
lock_pdb_lock(RESOURCE * r,int msg)
{
int t;
/*
ss_printf("lock_pdb 1 %ls %i\n",
get_url_str2(&r->h.entry),
get_tid());
*/
	lock_task(draw_lock);
/*
printf("lock_pdb 2 %i\n",get_tid());
*/
	t = get_tid();
	if ( r->draw_gb.pdb_lock == 0 )
		goto next;
	if ( r->draw_gb.pdb_lock_task == t )
		goto next;
	for ( ; r->draw_gb.pdb_lock ; ) {
/*
printf("lock_pdb 3 %i\n",get_tid());
*/
		sleep_task((int)&r->draw_gb.pdb_lock,draw_lock);
/*
printf("lock_pdb 4 %i\n",get_tid());
*/
		lock_task(draw_lock);
	}
next:
	if ( msg )
		r->draw_gb.pdb_lock_msg = msg;
	r->draw_gb.pdb_lock ++;
	r->draw_gb.pdb_lock_task = t;
	unlock_task(draw_lock,"lock_pdb_lock");
}


void
unlock_pdb_lock(RESOURCE * r)
{
	lock_task(draw_lock);
	if ( r->draw_gb.pdb_lock ) {
		if ( r->draw_gb.pdb_lock_task == 0 )
			goto next;
		if ( r->draw_gb.pdb_lock_task != get_tid() )
			er_panic("unlock_pdb_lock");
		r->draw_gb.pdb_lock --;
	next:
		if ( r->draw_gb.pdb_lock == 0 ) {
			r->draw_gb.pdb_lock_task = 0;
			wakeup_task((int)&r->draw_gb.pdb_lock);
		}
	}
	unlock_task(draw_lock,"unlock_pdb_lock");
/*
printf("unlock_pdb 1 %ls %i\n",
get_url_str2(&r->h.entry),
get_tid());
*/
}

int
gc_gv_draw_func(AVT_NODE * a)
{
OBJ * o;
	o = a->data;
	gc_gb_sexp(o->h.info_org);
	gc_gb_sexp(o->h.info_card);
	gc_gb_sexp(o->h.info_onmap);
	return 0;
}

void
gc_gv_draw(RESOURCE * r)
{
	avt_trace_from_small(r->draw_gb.obj_code_tree,
		gc_gv_draw_func,0);
}


XL_SEXP *
gv_new_vector(RESOURCE * r,XL_SEXP * s,int ds)
{
int i;
int ret_dpm,ret_level;
double dpm;
int level;
L_CHAR * l_unit,* d_unit;
char * e_param;
XL_SEXP * e_data;
int er;

	if ( ds == NR_KEEP )
		return 0;
	i = l_strlen(r->h.target.resource);
	i--;
	for ( ; i >= 0 ; i -- )
		if ( r->h.target.resource[i] == '.' )
			break;
	if ( r->h.target.resource[i] != '.' )
		goto non_prog;
	if ( l_strcmp(&r->h.target.resource[i],
			l_string(std_cm,".pp")) == 0 )
		goto pdb_prog;
non_prog:
	r->draw_gb.flags = 0;
	r->draw_gb.type = DGT_LOAD;
	r->draw_gb.level = 0;
	r->draw_gb.resolution = 0;
	r->draw_gb.hit_level = 0;
	r->draw_gb.hit_outofcircle = 0;

	new_vector_option1(r,ds);

	r->draw_gb.ir_queue = 0;
	r->draw_gb.ischeme = 0;
	r->draw_gb.onmap_indicate_size = DEFAULT_ONMAP_INDICATE_SIZE;
	return 0;
pdb_prog:
	r->draw_gb.flags = 0;
	r->draw_gb.hit_level = 0;
	r->draw_gb.hit_outofcircle = 0;
	r->draw_gb.type = DGT_PDB;
	get_field(s,
		l_string(std_cm,"level"),"i",&level,&ret_level,&l_unit,
		l_string(std_cm,"resolution"),"lf",&dpm,&ret_dpm,&d_unit,
		0);
	if ( ret_dpm || ret_level ) {
		e_param = "resolution or level error";
		e_data = s;
		goto subtype_error;
	}
	r->draw_gb.loop_no = 0;
	r->draw_gb.level = level;
	r->draw_gb.resolution = conv_unit(&er,
		r->h.cu.uenv,
		dpm,d_unit,
		reso_c_unit(&r->h.cu));
	r->draw_gb.matrix_ofs.x =
		(1+DM_RATE)*r->h.minrect.tl.x
		- DM_RATE*r->h.minrect.br.x;
	r->draw_gb.matrix_ofs.y =
		(1+DM_RATE)*r->h.minrect.tl.y
		- DM_RATE*r->h.minrect.br.y;
	if ( ds == NR_CLEAR )
		d_f_ree(r->draw_gb.pitch_list);
	r->draw_gb.pitch_list
		= d_alloc(sizeof(GB_POINT)*level,35);
	r->draw_gb.pitch_list[level-1].x =
		(r->h.minrect.br.x - r->h.minrect.tl.x)*(1+2*DM_RATE)/2;
	r->draw_gb.pitch_list[level-1].y =
		(r->h.minrect.br.y - r->h.minrect.tl.y)*(1+2*DM_RATE)/2;
	for ( i = level-2 ; i >= 0 ; i -- ) {
		r->draw_gb.pitch_list[i].x
			= r->draw_gb.pitch_list[i+1].x/DM_DIM;
		r->draw_gb.pitch_list[i].y
			= r->draw_gb.pitch_list[i+1].y/DM_DIM;
	}
	if ( r->draw_gb.pitch_list[0].x <
			default_dgb_pixel/r->draw_gb.resolution ) {
		r->draw_gb.pitch_list[0].x =
			default_dgb_pixel/r->draw_gb.resolution;
		for ( i = 1 ; i < level ; i ++ )
			r->draw_gb.pitch_list[i].x
				= r->draw_gb.pitch_list[i-1].x*DM_DIM;
	}
	if ( r->draw_gb.pitch_list[0].y <
			default_dgb_pixel/r->draw_gb.resolution ) {
		r->draw_gb.pitch_list[0].y =
			default_dgb_pixel/r->draw_gb.resolution;
		for ( i = 1 ; i < level ; i ++ )
			r->draw_gb.pitch_list[i].y
				= r->draw_gb.pitch_list[i-1].y*DM_DIM;
	}
	new_vector_option2(r,ds,level);

	r->draw_gb.ir_queue = 0;
	r->draw_gb.ischeme = 0;
	r->draw_gb.onmap_indicate_size = DEFAULT_ONMAP_INDICATE_SIZE;
	return 0;
subtype_error:
	return get_error(
		s->h.file,
		s->h.line,
		XLE_PROTO_INV_PARAM,
		l_string(std_cm,"gv-new-resource(draw_gb)"),
		List(n_get_string("invalid subtype in the meta info"),
			get_string(l_string(std_cm,e_param)),
			n_get_string("argument"),
			e_data,
			-1));
}

