/**********************************************************************
 
	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	"server_work.h"
#include	"mp.h"
#include	"lock_level.h"

XL_SEXP * xl_GetElement();

SEM mpw_lock;
MP_WORK mpw;
int mpw_load;

void
init_mp_work()
{

	mpw_lock = new_lock(LL_MPW);

}

void
get_mp_work(MP_WORK * w,int type)
{
XL_SEXP * s;
XL_SEXP * tm,* tm_data;

	lock_task(mpw_lock);
	if ( mpw_load && type == 0 )
		goto end;
	gc_push(0,0,"get_mp_work");
	s = get_swork(MP_FILENAME);
	if ( s == 0 ) {
		mpw.total_maps = 1;
		mpw.total_map_references = 0;
		mpw.interval_avg = MAPPING_INTERVAL_AVG;
		mpw.loop_lock_max = LOOP_LOCK_TOLERANCE;
		mpw.lump_id = 1;
	}
	else {
		tm = xl_GetElement(
			gblisp_top_env0,
			List(	n_get_symbol("GetElement"),
				get_el(s,1),
				n_get_symbol("total-maps"),
				-1));
		if ( get_type(tm) == 0 || get_type(tm) == XLT_ERROR ) {
			mpw.total_maps = 1;
			goto next1;
		}
		tm_data = get_el(tm,1);
		if ( get_type(tm_data) != XLT_INTEGER ) {
			mpw.total_maps = 1;
			goto next1;
		}
		mpw.total_maps = tm_data->integer.data;
	next1:	
		tm = xl_GetElement(
			gblisp_top_env0,
			List(	n_get_symbol("GetElement"),
				get_el(s,1),
				n_get_symbol("total-map-references"),
				-1));
		if ( get_type(tm) == 0 || get_type(tm) == XLT_ERROR ) {
			mpw.total_map_references = 1;
			goto next2;
		}
		tm_data = get_el(tm,1);
		if ( get_type(tm_data) != XLT_INTEGER ) {
			mpw.total_map_references = 1;
			goto next2;
		}
		mpw.total_map_references = tm_data->integer.data;
	next2:
		tm = xl_GetElement(
			gblisp_top_env0,
			List(	n_get_symbol("GetElement"),
				get_el(s,1),
				n_get_symbol("interval-avg"),
				-1));
		if ( get_type(tm) == 0 || get_type(tm) == XLT_ERROR ) {
			mpw.interval_avg = MAPPING_INTERVAL_AVG;
			goto next3;
		}
		tm_data = get_el(tm,1);
		if ( get_type(tm_data) != XLT_INTEGER ) {
			mpw.interval_avg = MAPPING_INTERVAL_AVG;
			goto next3;
		}
		mpw.interval_avg = tm_data->integer.data;
	next3:
		tm = xl_GetElement(
			gblisp_top_env0,
			List(	n_get_symbol("GetElement"),
				get_el(s,1),
				n_get_symbol("lump-id"),
				-1));
		if ( get_type(tm) == 0 || get_type(tm) == XLT_ERROR ) {
			mpw.lump_id = 0;
			goto next4;
		}
		tm_data = get_el(tm,1);
		if ( get_type(tm_data) != XLT_INTEGER ) {
			mpw.lump_id = 0;
			goto next4;
		}
		mpw.lump_id = tm_data->integer.data;
	next4:
		tm = xl_GetElement(
			gblisp_top_env0,
			List(	n_get_symbol("GetElement"),
				get_el(s,1),
				n_get_symbol("loop-lock-max"),
				-1));
		if ( get_type(tm) == 0 || get_type(tm) == XLT_ERROR ) {
			mpw.loop_lock_max = LOOP_LOCK_TOLERANCE;
			goto next5;
		}
		tm_data = get_el(tm,1);
		if ( get_type(tm_data) != XLT_INTEGER ) {
			mpw.loop_lock_max = LOOP_LOCK_TOLERANCE;
			goto next5;
		}
		mpw.loop_lock_max = tm_data->integer.data;
	next5:
		tm = xl_GetElement(
			gblisp_top_env0,
			List(	n_get_symbol("GetElement"),
				get_el(s,1),
				n_get_symbol("c-min-interval"),
				-1));
		if ( get_type(tm) == 0 || get_type(tm) == XLT_ERROR ) {
			mpw.c_min_interval = CINDEX_MIN_INTERVAL;
			goto next6;
		}
		tm_data = get_el(tm,1);
		if ( get_type(tm_data) != XLT_INTEGER ) {
			mpw.c_min_interval = CINDEX_MIN_INTERVAL;
			goto next6;
		}
		mpw.c_min_interval = tm_data->integer.data;
	next6:	{}
	}
	gc_pop(0,0);

	mpw_load = 1;
end:
	*w = mpw;
	unlock_task(mpw_lock,"mpw_init");
}


void
set_mp_work(MP_WORK * w)
{
XL_SEXP * s;
XL_SEXP * header;

	lock_task(mpw_lock);
	mpw = *w;
	gc_push(0,0,"get_mp_work");
	header = n_get_symbol("xl");
	set_attribute(
		header,
		l_string(std_cm,"version"),
		l_string(std_cm,"1.0"));
	set_attribute(
		header,
		l_string(std_cm,"encoding"),
		l_string(std_cm,"EUC-JP"));
	s = List(
		List(header,-1),
		List(n_get_symbol("mp"),
			List(n_get_symbol("total-maps"),
				get_integer(mpw.total_maps,0),
				-1),
			List(n_get_symbol("total-map-references"),
				get_integer(mpw.total_map_references,0),
				-1),
			List(n_get_symbol("interval-avg"),
				get_integer(mpw.interval_avg,0),
				-1),
			List(n_get_symbol("lump-id"),
				get_integer(mpw.lump_id,0),
				-1),
			List(n_get_symbol("loop-lock-max"),
				get_integer(mpw.loop_lock_max,0),
				-1),
			List(n_get_symbol("c-min-interval"),
				get_integer(mpw.c_min_interval,0),
				-1),
			-1),
		-1);
	set_swork(MP_FILENAME,s);
	gc_pop(0,0);
	unlock_task(mpw_lock,"get_mp_work");
}
