/**********************************************************************
 
	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	"machine/u_math.h"
#include	"memory_debug.h"
#include	"task.h"
#include	"lock_level.h"
#include	"resource.h"
#include	"radar.h"
#include	"routing.h"
#include	"avt.h"
#include	"xlerror.h"
#include	"xl.h"
#include	"pri_level.h"
#include	"lump.h"
#include	"win_flame.h"


extern GBVIEW_ENV env;
RADAR_CACHE	rc;
SEM		radar_lock,query_lock;
XLISP_ENV *	radar_env;
REAL1		resolution_width = WIN_RESO_WINDOW_MAX;

int opening_state;
int main_tid;

void _clean_radar_matrix();

void wakeup_win_manage();
void loading_task();
void min_route_task();
void win_manage_task();
void gc_gb_sexp();
void beam_task();
void beam_load_resource_task();
void beam_insert_task();
void retrieve_lump_task();

void _query_trigger(int fn_flag);

void gc_load_to_beam();
void gc_load_to_beam_get();
void gc_beam_to_resource();
void gc_beam_to_resource_get();

XL_SEXP * gv_is_insert_query();
XL_SEXP * gv_is_set_query();
XL_SEXP * gv_is_get_query();
XL_SEXP * gv_is_delete_query();
XL_SEXP * gv_zoom();
XL_SEXP * gv_radar_status();
RADAR_CRD * _search_radar_crd(L_CHAR *,L_CHAR*);

int lock_pattern[] = {
	TMM_MIN|TMM_TRIG,
	TMM_WMAN|TMM_LOAD|TMM_INS,
	TMM_LOAD|TMM_WMAN|TMM_INS,
	TMM_TRIG|TMM_MIN,
	TMM_REMK,
	TMM_LOAD|TMM_WMAN|TMM_INS,
};


/*
void
_check_matrix(RADAR_MATRIX * mx)
{
int x,y;
	if ( mx == 0 )
		return;
	if ( mx->resolution < 0 )
		er_panic("matrix(1)");
	if ( mx->loaded_reso < 0 )
		er_panic("check_matrix(1.1)");
	if ( check_fnan(mx->resolution) < 0 )
		er_panic("matrix(20)");
	if ( check_fnan(mx->loaded_reso) < 0 )
		er_panic("matrix(21)");


	if ( mx->rect[0][0].tl.x != mx->rect[0][1].tl.x )
		er_panic("check_matrix(2)");
	if ( mx->rect[0][0].br.x != mx->rect[0][1].br.x )
		er_panic("check_matrix(3)");
	if ( mx->rect[0][0].br.x != mx->rect[1][0].tl.x )
		er_panic("check_matrix(4)");
	if ( mx->rect[0][0].br.x != mx->rect[1][1].tl.x )
		er_panic("check_matrix(5)");
	if ( mx->rect[1][0].br.x != mx->rect[1][1].br.x )
		er_panic("check_matrix(6)");
	if ( mx->rect[0][0].tl.y != mx->rect[1][0].tl.y )
		er_panic("check_matrix(7)");
	if ( mx->rect[0][0].br.y != mx->rect[1][0].br.y )
		er_panic("check_matrix(8)");
	if ( mx->rect[0][0].br.y != mx->rect[0][1].tl.y )
		er_panic("check_matrix(9)");
	if ( mx->rect[0][0].br.y != mx->rect[1][1].tl.y )
		er_panic("check_matrix(10)");
	if ( mx->rect[0][1].br.y != mx->rect[1][1].br.y )
		er_panic("check_matrix(11)");

	for ( x = 0 ; x < 2 ; x ++ )
		for ( y = 0 ; y < 2 ; y ++ ) {
			if ( check_fnan(mx->rect[x][y].tl.x) < 0 )
				er_panic("matrix(22)");
			if ( check_fnan(mx->rect[x][y].tl.y) < 0 )
				er_panic("matrix(23)");
			if ( check_fnan(mx->rect[x][y].br.x) < 0 )
				er_panic("matrix(24)");
			if ( check_fnan(mx->rect[x][y].br.y) < 0 )
				er_panic("matrix(25)");

			if ( mx->mx[x][y] == 0 )
				continue;
			if ( mx->mx[x][y]->parent != mx )
				er_panic("check_matrix(12)");
			_check_matrix(mx->mx[x][y]);
		}
}

void
_x_check_matrix()
{
	if ( rc.matrix == 0 )
		return;
	if ( rc.matrix->parent != 0 )
		er_panic("check_matrix(100)");
	_check_matrix(rc.matrix);
}

void
check_matrix()
{
	lock_task(radar_lock);
	_x_check_matrix();
	unlock_task(radar_lock,"check_matrix");
}



void
check_parent(RADAR_MATRIX * mx)
{
	for ( ; mx ; mx = mx->parent )
		_check_matrix(mx);
}
*/

int
_check_matrix_size(RADAR_MATRIX * mx)
{
int x,y;
int ret;
	if ( mx == 0 )
		return 0;
	ret = 1;
	for ( x = 0; x < 2 ; x ++ )
		for ( y = 0 ; y < 2 ; y ++ )
			ret += _check_matrix_size(mx->mx[x][y]);
	return ret;
}

int
check_matrix_size()
{
	return _check_matrix_size(rc.matrix);
}

void
init_radar()
{
int i;
	radar_lock = new_lock(LL_RADAR);
	query_lock = new_lock(LL_RADAR_QUERY);
	rc.win_reso_window = WIN_RESO_WINDOW_MAX;
	rc.crd = d_alloc(sizeof(RADAR_CRD)*RADAR_CACHE_SIZE,12);
	rc.ptr = d_alloc(sizeof(GB_POINT)*RADAR_CACHE_SIZE*8,13);
	rc.res = d_alloc(sizeof(REAL1)*RADAR_CACHE_SIZE*8,14);
	rc.free_list = 0;
	for ( i = 1 ; i < RADAR_CACHE_SIZE ; i ++ ) {
		rc.crd[i].bufid = i;
		rc.ptr[i].x = rc.ptr[i].y = 0;
		rc.res[i] = -1;
		rc.crd[i].next = rc.free_list;
		rc.free_list = &rc.crd[i];
	}
	rc.crd[0].bufid = 0;
	rc.ptr[0].x = rc.ptr[i].y = 0;
	rc.res[0] = -1;
	rc.crd[0].next = rc.crd[0].prev = &rc.crd[0];

	rc.mtx_h.next = rc.mtx_h.prev = &rc.mtx_h;

	rc.matrix = 0;
	rc.matrix_count = 0;
	rc.query = 0;
	rc.query_mode = 0;
	rc.load_mode = 0;
	rc.lump = 0;

	memset(&rc.load_to_beam,0,sizeof(SYS_QUEUE));
	rc.load_to_beam.flags = QF_FIFO;
	rc.load_to_beam.gc_func = gc_load_to_beam;
	rc.load_to_beam.gc_get = gc_load_to_beam_get;
	rc.load_to_beam.key_func = beam_task;
	rc.load_to_beam.pri = PRI_FETCH;
	setup_queue(&rc.load_to_beam);

	memset(&rc.beam_to_resource,0,sizeof(SYS_QUEUE));
	rc.beam_to_resource.flags = QF_FIFO;
	rc.beam_to_resource.gc_func = gc_beam_to_resource;
	rc.beam_to_resource.gc_get = gc_beam_to_resource_get;
	setup_queue(&rc.beam_to_resource);

	memset(&rc.resource_to_insert,0,sizeof(SYS_QUEUE));
	rc.resource_to_insert.flags = QF_STACK|QF_HIGH;
	setup_queue(&rc.resource_to_insert);


	radar_env = new_env(gblisp_top_env0);
	set_env(radar_env,l_string(std_cm,"gv-insert-query"),
		get_func_prim(gv_is_insert_query,FO_NORMAL,0,2,2));
	set_env(radar_env,l_string(std_cm,"gv-set-query"),
		get_func_prim(gv_is_set_query,FO_NORMAL,0,2,2));
	set_env(radar_env,l_string(std_cm,"gv-get-query"),
		get_func_prim(gv_is_get_query,FO_APPLICATIVE,0,1,1));
	set_env(radar_env,l_string(std_cm,"gv-delete-query"),
		get_func_prim(gv_is_delete_query,FO_APPLICATIVE,0,2,2));
	set_env(radar_env,l_string(std_cm,"gv-zoom"),
		get_func_prim(gv_zoom,FO_APPLICATIVE,0,2,4));
	set_env(radar_env,l_string(std_cm,"gv-status"),
		get_func_prim(gv_radar_status,FO_APPLICATIVE,0,1,1));

	set_gv_sp_resource(RID_RADAR,radar_env);
	set_env(gblisp_top_env0,l_string(std_cm,"radar"),
		get_env(radar_env));

	create_task(beam_load_resource_task,0,PRI_FETCH);
	create_task(beam_insert_task,0,PRI_FETCH);
	create_task(retrieve_lump_task,0,PRI_FETCH);
	create_task(loading_task,0,PRI_FETCH_STRONG);
	create_task(win_manage_task,0,PRI_FETCH_STRONG);
	create_task(min_route_task,0,PRI_FETCH_STRONG);

}


void
gc_load_to_beam(T_LOAD_TO_BEAM * n)
{
	gc_gb_sexp(n->query);
}

void
gc_beam_to_resource(T_BEAM_TO_RESOURCE * n)
{
	gc_gb_sexp(n->urls);
}

void
gc_load_to_beam_get(T_LOAD_TO_BEAM * n)
{
	lock_mem();
	gc_set_nl(n->query,gc_gb_sexp);
	unlock_mem();
}

void
gc_beam_to_resource_get(T_BEAM_TO_RESOURCE * n)
{
	lock_mem();
	gc_set_nl(n->urls,gc_gb_sexp);
	unlock_mem();
}

void
insert_beam_to_resource(XL_SEXP * urls)
{
T_BEAM_TO_RESOURCE * n;
	n = new_queue_node(sizeof(*n),236);
	n->h.key = 0;
	n->h.ins = 0;
	n->urls = urls;
	insert_queue(&rc.beam_to_resource,n,0);
}

void
free_load_to_beam(T_LOAD_TO_BEAM * n)
{
void _free_radar_lump();
	if ( n->h.key )
		d_f_ree(n->h.key);
	d_f_ree(n->base_url);
	if ( n->rl )
		_free_radar_lump(n->rl);
	d_f_ree(n);
}

void
free_resource_to_insert(T_RESOURCE_TO_INSERT * n)
{
	if ( n->h.key )
		d_f_ree(n->h.key);
	d_f_ree(n->crd_path);
	d_f_ree(n->obj_path);
	d_f_ree(n);
}

void
gc_radar()
{
	gc_gb_sexp(rc.query);
}


void
_wlock_base_url(char * msg)
{
int tid;
	tid = get_tid();
	if ( rc.base_url_lock == 0 )
		goto ok;
	if ( rc.base_url_lock > 0 )
		goto retry_loop;
	if ( rc.base_url_lock_task == tid ) {
		rc.base_url_lock --;
		goto end;
	}
retry_loop:
	for ( ; rc.base_url_lock ; ) {
		sleep_task((int)&rc.base_url_lock,radar_lock);
		lock_task(radar_lock);
	}
ok:
	rc.base_url_lock = -1;
	rc.base_url_lock_task = tid;
end:	{}
/*
printf("BASE_URL W(%i) %s - %i\n",get_tid(),msg,rc.base_url_lock);
*/
}

void
_rlock_base_url(char * msg)
{
int tid;
	if ( rc.base_url_lock >= 0 )
		goto end;
	if ( rc.base_url_lock_task == get_tid() ) {
		_wlock_base_url(msg);
		return;
	}
	for ( ; rc.base_url_lock < 0 ; ) {
		sleep_task((int)&rc.base_url_lock,radar_lock);
		lock_task(radar_lock);
	}
end:
	rc.base_url_lock ++;
/*
printf("BASE_URL R(%i) %s - %i\n",get_tid(),msg,rc.base_url_lock);
*/
}

void
_unlock_base_url()
{
int tid;

	if ( rc.base_url_lock > 0 ) {
		rc.base_url_lock --;
		goto end;
	}
	if ( rc.base_url_lock < 0 ) {
		if ( rc.base_url_lock_task != get_tid() )
			er_panic("_unlock_base_url");
		rc.base_url_lock ++;
		goto end;
	}
	er_panic("_unlock_Base_url(1)");
end:
	if ( rc.base_url_lock == 0 ) {
		rc.base_url_lock_task = 0;
		wakeup_task((int)&rc.base_url_lock);
	}
/*
printf("BASE_URL(%i) UNLOCK %i\n",get_tid(),rc.base_url_lock);
*/
}

void
wlock_base_url(char * msg)
{
	lock_task(radar_lock);
	_wlock_base_url(msg);
	unlock_task(radar_lock,"lock_base_url");
}

void
rlock_base_url(char * msg)
{
	lock_task(radar_lock);
	_rlock_base_url(msg);
	unlock_task(radar_lock,"lock_base_url");
}

void
unlock_base_url()
{
	lock_task(radar_lock);
	_unlock_base_url();
	unlock_task(radar_lock,"unlock_base_url");
}


void
_set_q_mode()
{
	for ( ; rc.query_mode ; ) {
		/* alreay there is another query task */
		sleep_task((int)&rc.query_mode,query_lock);
		lock_task(query_lock);
	}
	rc.query_mode = 1;
	for ( ; rc.load_mode ; ) {
		wakeup_task((int)&rc.query_mode);
		wakeup_task((int)&rc.first_max);
		sleep_task((int)&rc.query_mode,query_lock);
		lock_task(query_lock);
	}
}

void
set_q_mode()
{
	lock_task(query_lock);
	_set_q_mode();
	unlock_task(query_lock,"set_q_mode");
}

void
reset_q_mode()
{
	lock_task(query_lock);
	rc.query_mode = 0;
	wakeup_task((int)&rc.query_mode);
	unlock_task(query_lock,"reset_q_mode");
}


void
set_l_mode()
{
	lock_task(query_lock);
	for ( ; rc.query_mode ; ) {
		sleep_task((int)&rc.query_mode,query_lock);
		lock_task(query_lock);
	}
	rc.load_mode = 1;
	unlock_task(query_lock,"set_l_mode");
}


void
reset_l_mode()
{
	lock_task(query_lock);
	rc.load_mode = 0;
	wakeup_task((int)&rc.query_mode);
	unlock_task(query_lock,"reset_l_mode");
}

void
_set_opening_state(int state)
{
	if ( opening_state < state )
		opening_state = state;
ss_printf("set_opening_state %i %i\n",opening_state,state);
	wakeup_task((int)&opening_state);
}

void
set_opening_state(int state)
{
	lock_task(radar_lock);
	_set_opening_state(state);
	unlock_task(radar_lock,"sethome_opening_state");
}

void
set_opening_state_query()
{
	lock_task(radar_lock);
	if ( main_tid != get_tid() ) {
		for ( ; opening_state < OS_SETHOME_COMPLETE ; ) {
			sleep_task((int)&opening_state,radar_lock);
			lock_task(radar_lock);
		}
		_set_opening_state(OS_RUN);
		wakeup_task((int)&opening_state);
	}
	unlock_task(radar_lock,"sethome_opening_state");
}

void
_insert_radar_crd_ring(RADAR_CRD * c)
{
	c->prev = &rc.crd[0];
	c->next = rc.crd[0].next;
	c->prev->next = c;
	c->next->prev = c;
}

int
_rc_task_lock_check(int t)
{
int lp;


	lp = lock_pattern[t];
	if ( rc.task_mode&(~lp) )
		return -1;
	return 0;
}

int
rc_task_lock_check(int t)
{
int ret;
	lock_task(radar_lock);
	ret = _rc_task_lock_check(t);
	unlock_task(radar_lock,"rc_task_lock_check");
	return ret;
}

void
_rc_task_lock(int t)
{
int lp;

	lp = lock_pattern[t];
/*
printf("lock_pattern %x %i\n",rc.task_mode,t);
*/
	for ( ; rc.task_mode&(~lp) ; ) {
		sleep_task((int)lock_pattern,radar_lock);
		lock_task(radar_lock);
	}
	rc.task_mode |= 1<<t;
}

void
rc_task_lock(int t)
{
	lock_task(radar_lock);
	_rc_task_lock(t);
	unlock_task(radar_lock,"rc_task_lock");
}

void
_rc_task_unlock(int t)
{
	rc.task_mode &= ~(1<<t);
	wakeup_task((int)lock_pattern);
/*
printf("unlock_pattern %x %i\n",rc.task_mode,t);
*/
}

void
rc_task_unlock(int t)
{
	lock_task(radar_lock);
	_rc_task_unlock(t);
	unlock_task(radar_lock,"rc_task_unlock");
}



void
_delete_radar_crd_ring(RADAR_CRD * c)
{
	c->prev->next = c->next;
	c->next->prev = c->prev;
}

void
_insert_radar_mtx_ring(RADAR_MATRIX * mx)
{
	mx->prev = &rc.mtx_h;
	mx->next = rc.mtx_h.next;
	mx->next->prev = mx;
	mx->prev->next = mx;
}

void
_delete_radar_mtx_ring(RADAR_MATRIX * mx)
{
	mx->prev->next = mx->next;
	mx->next->prev = mx->prev;
}


RADAR_LUMP *
_search_radar_lump(L_CHAR * lumpcrd_path)
{
RADAR_LUMP * ret;
	for ( ret = rc.lump ; ret ; ret = ret->next )
		if ( l_strcmp(ret->lumpcrd_path,lumpcrd_path) == 0 )
			return ret;
	return 0;
}

void
_insert_radar_lump(RADAR_CRD * c,RADAR_LUMP * rl)
{
LUMP_CRD_NODE * n;
	n = d_alloc(sizeof(*n),12);
	n->crd = c;
	n->lump = rl;
	n->crd_next = c->lump;
	c->lump = n;
	n->lump_next = rl->crd;
	rl->crd = n;
}

void
_delete_lump_crd_node_from_lump(RADAR_LUMP * l)
{
LUMP_CRD_NODE * n, ** np;
RADAR_CRD * c;
	for ( ; l->crd ; ) {
		n = l->crd;
		c = n->crd;
		np = &c->lump;
		for ( ; *np && *np != n ; np = &(*np)->crd_next );
		if ( *np == 0 )
			er_panic("_delete_lump_crd_node_form_lump(1)");
		*np = n->crd_next;
		l->crd = n->lump_next;
		d_f_ree(n);
	}
}

void
_free_radar_lump(RADAR_LUMP * l)
{
RADAR_LUMP ** lp;

	for ( lp = &rc.lump ; *lp && *lp != l ; lp = &(*lp)->next );
	if ( *lp )
		*lp = l->next;
	d_f_ree(l->db_path);
	d_f_ree(l->lumpcrd_path);
	_delete_lump_crd_node_from_lump(l);
	d_f_ree(l);

}

RADAR_LUMP *
_copy_radar_lump(RADAR_LUMP * l)
{
RADAR_LUMP * ret, * ll;
	ret = 0;
	for ( ; l ; l = l->next ) {
		ll = d_alloc(sizeof(*ll),1651);
		*ll = *l;
		ll->crd = 0;
		ll->db_path = ll_copy_str(ll->db_path,1511);
		ll->lumpcrd_path = ll_copy_str(ll->lumpcrd_path,1512);
		ll->next = ret;
		ret = ll;
	}
	return ret;
}

void
change_rl_memtype(RADAR_LUMP * ll,int no)
{
	for ( ; ll ; ll = ll->next )
		change_memtype(ll,no);
}

void
_delete_lump_crd_node_from_crd(RADAR_CRD * c)
{
LUMP_CRD_NODE * n, ** np;
RADAR_LUMP * l;
	for ( ; c->lump ; ) {


		n = c->lump;
		l = n->lump;
		np = &l->crd;
		for ( ; *np && *np != n ; np = &(*np)->lump_next );
		if ( *np == 0 )
			er_panic("_delete_lump_crd_node_from_crd(1)");

		*np = n->lump_next;
		c->lump = n->crd_next;
		d_f_ree(n);
		if ( l->crd == 0 )
			_free_radar_lump(l);

	}
}

RADAR_LUMP *
_new_radar_lump(L_CHAR * crd,L_CHAR * db)
{
RADAR_LUMP * l;

	l = d_alloc(sizeof(*l),1);
	l->lumpcrd_path = ll_copy_str(crd,1513);
	l->db_path = ll_copy_str(db,1514);
	l->next = 0;
	l->crd = 0;
	return l;
}

int
_insert_radar_lump_list(RADAR_LUMP * l)
{
RADAR_LUMP * ll;
	ll = _search_radar_lump(l->lumpcrd_path);
	if ( ll )
		return -1;
	l->next = rc.lump;
	rc.lump = l;
	return 0;
}


RADAR_LUMP *
setup_radar_lump(int ses,L_CHAR * crd,L_CHAR * db)
{
XL_SEXP * xl_GetElement();
RADAR_LUMP * l;
L_CHAR * db_path;
int len;
XL_SEXP * ret, * sts;
URL u;
XL_SEXP * mr, * v;
int ret_mr;
GB_RECT r;
XL_SEXP * v_min,* v_max;
REAL1 reso_min,reso_max;
int er;


	l = 0;
	db_path = ll_copy_str(db,1515);
	len = l_strlen(db_path);
	db_path = d_re_alloc(db_path,(len + 10)*sizeof(L_CHAR));
	l_strcpy(&db_path[len],l_string(std_cm,"db.pmd"));
	get_url2(&u,crd,1552);
	if ( u.resource )
		d_f_ree(u.resource);
	u.resource = nl_copy_str(std_cm,"db.pmd");

	gc_push(0,0,"setup_radar_lump");
	sts = List(n_get_symbol("pmd-status"),get_string(db_path),-1);
	ret = remote_session(
		gblisp_top_env0,
		ses,
		&u,
		l_string(std_cm,"gbpmd.get"),
		l_string(std_cm,"user"),
		l_string(std_cm,"Get"),
		List(sts,-1),
		0,0,0);
set_cpu_msg(9900);
	if ( get_type(ret) == XLT_ERROR )
		goto end;
	get_field(ret,
		l_string(std_cm,"mr"),"sexp",&mr,&ret_mr,
		0);
	if ( ret_mr ) {
		goto end;
	}
	get_minrect(0,&r,mr);
	v = xl_GetElement(0,
		List(n_get_symbol("GetElement"),
			ret,
			n_get_symbol("v"),
			-1));
	v_min = get_el(v,1);
	switch ( get_type(v_min) ) {
	case XLT_INTEGER:
		reso_min = v_min->integer.data;
		break;
	case XLT_FLOAT:
		reso_min = v_min->floating.data;
		break;
	default:
		goto end;
	}
	v_max = get_el(v,2);
	switch ( get_type(v_max) ) {
	case XLT_INTEGER:
		reso_max = v_max->integer.data;
		break;
	case XLT_FLOAT:
		reso_max = v_max->floating.data;
		break;
	default:
		goto end;
	}
	l = _new_radar_lump(crd,db_path);
	l->sphere = r;
	l->reso_min = reso_min;
	l->reso_max = reso_max;
	call_gv_event(RID_RADAR,l_string(std_cm,"insert"));
end:
	gc_pop(0,0);

	free_url(&u);
	d_f_ree(db_path);
	return l;
}

RADAR_CRD * 
_search_crd_path(L_CHAR * path)
{
RADAR_CRD * ret;
	for ( ret = rc.crd[0].next; ret != &rc.crd[0] ; ret = ret->next ) {
		if ( ret->lump == 0 )
			continue;
		if ( l_strcmp(ret->crd_path,path) == 0 )
			return ret;
	}
	return 0;
}

int
_retrieve_lump(int ses)
{
int nos;
int i;
RADAR_CRD * c, * c1;
int ret;
L_CHAR * crd, * obj;
XL_SEXP * lmp;
LUMP_ROUTE * lr, * lr1, * lr2;
LUMP_OPT opt;
RADAR_LUMP * l;
LUMP_CRD_NODE * n;
int ret_f;


	ret = 0;
	for ( nos = 0 ; ; nos ++ ) {
		lock_task(radar_lock);
		c = rc.crd[0].next;
		for ( i = 0 ; i < nos && c != &rc.crd[0] ; i ++ )
			c = c->next;
		if ( c == &rc.crd[0] ) {
			unlock_task(radar_lock,"retrieve_lump");
			break;
		}
		if ( c->resolution <= 0 ) {
			unlock_task(radar_lock,"retrieve_lump");
			continue;
		}
		if ( c->lump ) {
			unlock_task(radar_lock,"retrieve_lump");
			continue;
		}
		c1 = _search_crd_path(c->crd_path);
		if ( c1 ) {
			for ( n = c1->lump ; n ; n = n->crd_next )
				_insert_radar_lump(c,n->lump);
			unlock_task(radar_lock,"retrieve_lump");
			continue;
		}
		crd = ll_copy_str(c->crd_path,1516);
		obj = ll_copy_str(c->obj_path,1517);
		unlock_task(radar_lock,"retrieve_lump");
		lmp = load_meta(ses,"lump",crd);
		if ( get_type(lmp) == XLT_ERROR )
			goto end0;
		lr = get_lr(0,lmp,0);

		for ( lr1 = lr ; lr1 ; lr1 = lr1->next ) {

ss_printf("retrieve loop %ls\n",lr1->lump_crd);

			ret_f = 0;
			lmp = load_meta(ses,"lump",lr1->lump_crd);
set_cpu_msg(101);
			if ( get_type(lmp) == XLT_ERROR )
				continue;
			init_lump_opt(&opt);
			lr2 = get_lr(&opt,lmp,0);
			free_lr(lr2);
			if ( opt.lump == 0 )
{ss_printf("E1\n");
				goto next2;
}
			lock_task(radar_lock);
			l = _search_radar_lump(lr1->lump_crd);
			if ( l )
{ss_printf("E2\n");
				goto next1;
}
			unlock_task(radar_lock,"retrieve_lump");
			l = setup_radar_lump(ses,lr1->lump_crd,opt.lump);
			if ( l == 0 )
				goto next2;
			lock_task(radar_lock);
			c = _search_radar_crd(crd,obj);
			if ( c == 0 ) {
				free_lump_opt(&opt);
				_free_radar_lump(l);
				unlock_task(radar_lock,"retrieve_lump");
				call_gv_event(RID_RADAR,
					l_string(std_cm,"delete"));
ss_printf("E3\n");
				goto end1;
			}
			if ( _insert_radar_lump_list(l) < 0 ) {
				free_lump_opt(&opt);
				_free_radar_lump(l);
				unlock_task(radar_lock,"retrieve_lump");
				call_gv_event(RID_RADAR,
					l_string(std_cm,"delete"));
ss_printf("E4\n");
				goto end1;
			}
			ret = 1;
			ret_f = 1;
ss_printf("OK\n");
		next1:
			_insert_radar_lump(c,l);
			unlock_task(radar_lock,"retrieve_lump");
		next2:
			free_lump_opt(&opt);

			if ( ret_f ) {
				_query_trigger(0);

				lock_task(radar_lock);
				rc.win_force = 1;
				wakeup_task((int)loading_task);
				unlock_task(radar_lock,
					"retrieve_lump_task");
			}
		}
	end1:
		free_lr(lr);
	end0:
		d_f_ree(obj);
		d_f_ree(crd);
ss_printf("EEE\n");
	}
	return ret;
}

int
retrieve_lump(int ses)
{
int ret;

	gc_push(0,0,"retrieve");
	ret = _retrieve_lump(ses);
	gc_pop(0,0);

	return ret;
}

void
retrieve_lump_task()
{
XL_INTERPRETER * xli;
int ses;
int ret;

	xli = new_xl_interpreter();
	xli->a_type = XLA_SELF;
	setup_i(xli);

	ses = open_session(SEST_OPTIMIZE);

	for ( ; ; ) {
		lock_task(radar_lock);
		for ( ; rc.retrieve_flag == 0 ; ) {
			sleep_task((int)&rc.retrieve_flag,radar_lock);
			lock_task(radar_lock);
		}
		rc.retrieve_flag = 0;
		unlock_task(radar_lock,"retrieve_lump_task");
		if ( retrieve_lump(ses) ) {
			_query_trigger(0);

			lock_task(radar_lock);
			rc.win_force = 1;
			wakeup_task((int)loading_task);
			unlock_task(radar_lock,"retrieve_lump_task");
		}
	}
}


void
_delete_turning_loaded_reso(RADAR_MATRIX * mx,REAL1 lr)
{
int x,y;
	if ( mx->loaded_reso < lr )
		mx->loaded_reso = lr;
	for ( x = 0 ; x < 2 ; x ++ )
		for ( y = 0 ; y < 2 ; y ++ ) {
			if ( mx->mx[x][y] == 0 )
				continue;
			_delete_turning_loaded_reso(
				mx->mx[x][y],lr);
		}
}

void
_delete_node_from_crd(RADAR_CRD * c)
{
RADAR_NODE ** np;
RADAR_NODE * n;
	for ( ; c->list ; ) {
		n = c->list;
		c->list = n->crd_next;
		n->matrix->loaded_reso = n->matrix->resolution*2;
		_delete_turning_loaded_reso(n->matrix,
			n->matrix->loaded_reso);
		for ( np = &n->matrix->list ; *np ;
				np = &(*np)->matrix_next )
			if ( *np == n )
				break;
		if ( *np == 0 )
			er_panic("_delete_node_from_crd");
		*np = n->matrix_next;
		d_f_ree(n);
	}
}



RADAR_CRD *
new_radar_crd()
{
RADAR_CRD * c1;
int i,p;
	lock_task(radar_lock);
	if ( rc.free_list == 0 ) {
		c1 = rc.crd[0].prev;
		for ( ; c1 != &rc.crd[0] ; c1 = c1->prev ) {
			if ( c1->lock == 0 )
				break;
		}
		if ( c1 == &rc.crd[0] )
			er_panic("_new_radar_crd");
		_delete_node_from_crd(c1);
		d_f_ree(c1->crd_path);
		d_f_ree(c1->obj_path);
		for ( i = 8 , p = 8*c1->bufid ; i > 0 ; i -- , p ++ )
			rc.res[p] = -1;
		_delete_radar_crd_ring(c1);
		_insert_radar_crd_ring(c1);
	}
	else {
		c1 = rc.free_list;
		rc.free_list = c1->next;
		_insert_radar_crd_ring(c1);
	}
	c1->crd_path = 0;
	c1->obj_path = 0;
	c1->lock = -1;
	c1->list = 0;
	c1->base_url = 0;
	c1->lump = 0;
	c1->crd_bib = c1->obj_bib = 0;
	c1->crd_r = c1->obj_r = 0;
	unlock_task(radar_lock,"new_radar_crd");
	return c1;
}

void
_free_radar_crd(RADAR_CRD * c)
{
int i,p;


	if ( c->list )
		er_panic("_free_radar_crd");

	for ( i = 8 , p = 8*c->bufid ; i > 0 ; i -- , p ++ )
		rc.res[p] = -1;

	d_f_ree(c->crd_path);
	d_f_ree(c->obj_path);
	c->crd_path = c->obj_path = 0;

	free_bib_list(c->crd_bib);
	free_bib_list(c->obj_bib);
	c->crd_r = c->obj_r = 0;

	if ( c->base_url )
		d_f_ree(c->base_url);

	c->base_url = 0;

	_delete_lump_crd_node_from_crd(c);

	_delete_radar_crd_ring(c);

	c->next = rc.free_list;
	rc.free_list = c;

}

void
_flush_radar_crd(RADAR_CRD * c)
{
	if ( c->lock < 0 ) {
		c->lock = 0;
		wakeup_task((int)c);
	}
	else {
		c->lock --;
		if ( c->lock == 0 )
			wakeup_task((int)c);
	}
}

void
flush_radar_crd(RADAR_CRD * c)
{
	lock_task(radar_lock);
	_flush_radar_crd(c);
	unlock_task(radar_lock,"flush_radar_crd");
}


RADAR_CRD *
_search_radar_crd(L_CHAR * crd,L_CHAR * obj)
{
RADAR_CRD * c;
	for ( c = rc.crd[0].next ; c != &rc.crd[0] ; c = c->next )
		if ( l_strcmp(c->crd_path,crd) == 0 &&
			l_strcmp(c->obj_path,obj) == 0 ) {
			c->lock ++;
			return c;
		}
	return 0;
}

RADAR_CRD *
search_radar_crd(L_CHAR * crd,L_CHAR * obj)
{
RADAR_CRD * c;
	lock_task(radar_lock);
	c = _search_radar_crd(crd,obj);
	unlock_task(radar_lock,"search_radar_crd");
	return c;
}

RADAR_MATRIX *
_new_radar_matrix()
{
int x,y;
RADAR_MATRIX * ret;

	ret = d_alloc(sizeof(*ret),124);
	for ( x = 0 ; x < 2 ; x ++ )
		for ( y = 0 ; y < 2 ; y ++ )
			ret->mx[x][y] = 0;
	ret->list = 0;
	ret->parent = 0;
	_insert_radar_mtx_ring(ret);
	rc.matrix_count ++;

	return ret;
}

void
_init_radar_matrix(GB_RECT * r)
{
RADAR_MATRIX * mx;
int x,y;
REAL1 w,h,radius;
GB_POINT org;

	mx = _new_radar_matrix();
	w = r->br.x - r->tl.x;
	h = r->br.y - r->tl.y;

	mx->resolution = ((RADAR_DOTS/w + RADAR_DOTS/h)/2)*0.70710678118;
/*
if ( check_fnan(mx->resolution) < 0 )
er_panic("1");
*/
	mx->loaded_reso = mx->resolution*2;

	radius = 2*RADAR_DOTS_RATE*w*h/(w+h);
	org = p_avg(r->tl,r->br);
	org.x -= radius/2;
	org.y -= radius/2;
	for ( x = 0 ; x < 2 ; x ++ )
		for ( y = 0 ; y < 2 ; y ++ ) {
			mx->rect[x][y].tl.x = radius*x + org.x;
			mx->rect[x][y].tl.y = radius*y + org.y;
			mx->rect[x][y].br.x = radius*(x+1) + org.x;
			mx->rect[x][y].br.y = radius*(y+1) + org.y;
			mx->mx[x][y] = 0;
		}
	mx->list = 0;
	rc.matrix = mx;
	mx->parent = 0;
}

void
_check_mx_rect(int x,int y,RADAR_MATRIX *mx)
{
printf("MX RECT (%f %f)-(%f %f)\n",
mx->rect[x][y].tl.x,
mx->rect[x][y].tl.y,
mx->rect[x][y].br.x,
mx->rect[x][y].br.y);
if ( check_fnan(mx->rect[x][y].tl.x) < 0 )
er_panic("_init_radar_matrix 1");
if ( check_fnan(mx->rect[x][y].tl.y) < 0 )
er_panic("_init_radar_matrix 2");
if ( mx->rect[x][y].tl.x > mx->rect[x][y].br.x )
er_panic("3");
if ( mx->rect[x][y].tl.y > mx->rect[x][y].br.y )
er_panic("4");
}

void
check_mx_rect(RADAR_MATRIX * mx)
{
	_check_mx_rect(0,0,mx);
	_check_mx_rect(0,1,mx);
	_check_mx_rect(1,0,mx);
	_check_mx_rect(1,1,mx);
}

void
set_mx_rect(RADAR_MATRIX * mx,GB_POINT tl,GB_POINT c,GB_POINT br)
{
GB_RECT * r;
	r = &mx->rect[0][0];
	r->tl = tl;
	r->br = c;
	r = &mx->rect[1][0];
	r->tl.x = c.x;
	r->tl.y = tl.y;
	r->br.x = br.x;
	r->br.y = c.y;
	r = &mx->rect[0][1];
	r->tl.x = tl.x;
	r->tl.y = c.y;
	r->br.x = c.x;
	r->br.y = br.y;
	r = &mx->rect[1][1];
	r->tl = c;
	r->br = br;


}

RADAR_MATRIX *
_new_radar_matrix2(REAL1 reso,GB_RECT * r)
{
RADAR_MATRIX * mx;
int x,y;
GB_RECT * rr;
GB_POINT c;

	c.x = (r->tl.x + r->br.x)/2;
	c.y = (r->tl.y + r->br.y)/2;
	mx = _new_radar_matrix();
	mx->resolution = 2*reso;
/*
if ( check_fnan(mx->resolution) < 0 )
er_panic("2");
*/
	mx->loaded_reso = mx->resolution*2;


	set_mx_rect(mx,r->tl,c,r->br);
	mx->list = 0;
	return mx;
}

RADAR_MATRIX_LIST *
_new_radar_matrix_list(RADAR_MATRIX * mx)
{
RADAR_MATRIX_LIST * ret;

	ret = d_alloc(sizeof(*ret),125);
	ret->mx = mx;
	ret->next = 0;
	return ret;
}

void
_free_radar_matrix_list(RADAR_MATRIX_LIST * lst)
{
RADAR_MATRIX_LIST * lst2;
	for ( ; lst ; ) {
		lst2 = lst->next;
		d_f_ree(lst);
		lst = lst2;
	}
}

RADAR_MATRIX_LIST *
append_rml(RADAR_MATRIX_LIST * lst1,RADAR_MATRIX_LIST * lst2)
{
RADAR_MATRIX_LIST * ret;
	if ( lst1 == 0 )
		return lst2;
	ret = lst1;
	for ( ; lst1->next ; lst1 = lst1->next );
	lst1->next = lst2;
	return ret;
}

RADAR_MATRIX_LIST *
__get_radar_matrix(REAL1 reso,GB_RECT * r,RADAR_MATRIX * mx)
{
int x,y;
RADAR_MATRIX_LIST * lst1, * lst2;
GB_RECT * rr;
RADAR_MATRIX * mx2;


	if ( mx == 0 )
		er_panic("__get_radar_matrix(2)"); 
	if ( 2*mx->resolution >= reso )
		return _new_radar_matrix_list(mx);
	lst1 = 0;
	for ( x = 0 ; x < 2 ; x ++ )
		for ( y = 0 ; y < 2 ; y ++ ) {
			rr = &mx->rect[x][y];
			if ( cross_rect_rect(r,rr) == 0 )
				continue;
			if ( mx->mx[x][y] == 0 ) {
				mx->mx[x][y] = _new_radar_matrix2(
					mx->resolution,rr);
				mx->mx[x][y]->parent = mx;
			}
			lst2 = __get_radar_matrix(reso,r,mx->mx[x][y]);
			lst1 = append_rml(lst2,lst1);
		}
	return lst1;
}

void
stepup_radar_matrix(int xx,int yy)
{
RADAR_MATRIX * mx;
int x,y;
GB_RECT * rr;
GB_POINT tl,c,br;
GB_POINT rtl,rbr;

	mx = _new_radar_matrix();
	mx->resolution = rc.matrix->resolution/2;
/*
if ( check_fnan(mx->resolution) < 0 )
er_panic("3");
*/
	mx->loaded_reso = mx->resolution*2;


	rtl = rc.matrix->rect[0][0].tl;
	rbr = rc.matrix->rect[1][1].br;
	if ( xx == 0 && yy == 0 ) {
		tl = rtl;
		c = rbr;
		br.x = 2*c.x - tl.x;
		br.y = 2*c.y - tl.y;
	}
	else if ( xx == 1 && yy == 0 ) {
		tl.x = 2*rtl.x - rbr.x;
		tl.y = rtl.y;
		c.x = rtl.x;
		c.y = rbr.y;
		br.x = rbr.x;
		br.y = 2*rbr.y - rtl.y;
	}
	else if ( xx == 0 && yy == 1 ) {
		tl.x = rtl.x;
		tl.y = 2*rtl.y - rbr.y;
		c.x = rbr.x;
		c.y = rtl.y;
		br.x = 2*rbr.x - rtl.x;
		br.y = rbr.y;
	}
	else {
		tl.x = 2*rtl.x - rbr.x;
		tl.y = 2*rtl.y - rbr.y;
		c = rtl;
		br = rbr;
	}
	set_mx_rect(mx,tl,c,br);
	mx->list = 0;
	mx->mx[xx][yy] = rc.matrix;
	rc.matrix->parent = mx;
	rc.matrix = mx;


	mx->parent = 0;
}

void
including_matrix(GB_RECT * r)
{
GB_POINT p;
int x,y;


	for ( ; ; ) {
		p = rc.matrix->rect[0][0].tl;
		if ( p.x <= r->tl.x )
			x = 0;
		else	x = 1;
		if ( p.y <= r->tl.y )
			y = 0;
		else	y = 1;
		if ( x || y ) {
			stepup_radar_matrix(x,y);
			continue;
		}
		p = rc.matrix->rect[1][1].br;
		if ( p.x < r->br.x ) {
			stepup_radar_matrix(0,0);
			continue;
		}
		if ( p.y < r->br.y ) {
			stepup_radar_matrix(0,0);
			continue;
		}
		break;
	}
}

RADAR_MATRIX_LIST *
_get_radar_matrix(REAL1 reso,GB_RECT * r)
{
RADAR_MATRIX * mx;
int x,y;


	if ( reso <= 0 )
		er_panic("_get_radar_matrix(1)");

	if ( rc.matrix == 0 ) {
		_init_radar_matrix(r);
	}

	including_matrix(r);
	mx = rc.matrix;

	if ( mx->resolution > reso ) {
		for ( ; rc.matrix->resolution > reso ; )
			stepup_radar_matrix(0,0);
		return _new_radar_matrix_list(rc.matrix);
	}
	else if ( 2*mx->resolution <= reso ) {
		return __get_radar_matrix(reso,r,mx);
	}
	else {
		return _new_radar_matrix_list(mx);
	}
}

void
_insert_radar_matrix(RADAR_MATRIX * mx,RADAR_CRD * c)
{
RADAR_NODE * n;

	_delete_radar_mtx_ring(mx);
	_insert_radar_mtx_ring(mx);

	for ( n = mx->list ; n ; n = n->matrix_next )
		if ( n->crd == c )
			return;
	n = d_alloc(sizeof(*n),125);
	n->matrix = mx;
	n->crd = c;
	n->matrix_next = mx->list;
	mx->list = n;
	n->crd_next = c->list;
	c->list = n;
}

void
insert_radar_matrix(RADAR_CRD * c)
{
int p;
int i;
RADAR_MATRIX_LIST * lst, * lst2;
RADAR_NODE * n;

	if ( c->resolution <= 0 )
		return; 
	c->minrect.tl.x = c->minrect.tl.y = 0;
	c->minrect.br.x = c->minrect.br.y = -1;
	for ( i = 8, p = 8*c->bufid ; i > 0 ; i -- , p ++ )
		insert_rect(&c->minrect,rc.ptr[p]);
/*
printf("irm %f (%f %f)-(%f %f)\n",c->resolution,
c->minrect.tl.x,
c->minrect.tl.y,
c->minrect.br.x,
c->minrect.br.y);
*/
	lock_task(radar_lock);


	lst = _get_radar_matrix(c->resolution,&c->minrect);

	if ( lst ) {
		for ( lst2 = lst ; lst2 ; lst2 = lst2->next )
			_insert_radar_matrix(lst2->mx,c);
		_free_radar_matrix_list(lst);
	}
	else {
		er_panic("insert_radar_matrix(1)");
		/***/
	}
	unlock_task(radar_lock,"insert_radar_matirx");
}


void
_free_node_from_matrix(RADAR_MATRIX * mx)
{
RADAR_NODE * n,** np;


	for ( ; mx->list ; ) {
		n = mx->list;
		mx->list = n->matrix_next;
		for ( np = &n->crd->list; *np ; np = &(*np)->crd_next )
			if ( *np == n )
				break;
		if ( *np == 0 )
			er_panic("_free_node_from_matrix");
		*np = n->crd_next;
		d_f_ree(n);
	}
}


void
_free_node_from_matrix2(RADAR_MATRIX * mx)
{
RADAR_NODE * n,** np;

	for ( ; mx->list ; ) {
		n = mx->list;
		mx->list = n->matrix_next;
		for ( np = &n->crd->list; *np ; np = &(*np)->crd_next )
			if ( *np == n )
				break;
		if ( *np == 0 )
			er_panic("_free_node_from_matrix");
		*np = n->crd_next;
		d_f_ree(n);
	}
}
void
_free_radar_matrix(RADAR_MATRIX * mx)
{
int x,y;
RADAR_MATRIX * p;
	if ( mx == 0 )
		return;
	for ( x = 0; x < 2 ; x ++ )
		for ( y = 0 ; y < 2 ; y ++ )
			_free_radar_matrix(mx->mx[x][y]);
	_free_node_from_matrix(mx);
	_delete_radar_mtx_ring(mx);
	rc.matrix_count --;
	p = mx->parent;
	if ( p ) {
		for ( x = 0 ; x < 2 ; x ++ )
			for ( y = 0 ; y < 2 ; y ++ )
				if ( p->mx[x][y] == mx )
					p->mx[x][y] = 0;
	}
	d_f_ree(mx);
}


void
free_radar_matrix(void)
{
	lock_task(radar_lock);
	_free_radar_matrix(rc.matrix);
ss_printf("FREE RM\n");
	rc.matrix = 0;
	unlock_task(radar_lock,"free_radar_matrix");
}


void
_clean_top_of_matrix()
{
RADAR_MATRIX * mx;
int x,y;
	for ( ; ; ) {
		if ( rc.matrix == 0 )
			return;
		if ( rc.matrix->resolution*2 >= 
				rc.win_reso_max / rc.win_reso_window / 2 )
			return;
		mx = 0;
		for ( x = 0 ; x < 2 ; x ++ )
			for ( y = 0 ; y < 2 ; y ++ ) {
				if ( rc.matrix->mx[x][y] ) {
					if ( mx )
						return;
					mx = rc.matrix->mx[x][y];
				}
			}
		_free_node_from_matrix(rc.matrix);
		_delete_radar_mtx_ring(rc.matrix);
		rc.matrix_count --;
		d_f_ree(rc.matrix);
		rc.matrix = mx;
		mx->parent = 0;
	}
}

int
__clean_radar_matrix(RADAR_MATRIX * mx)
{
int x,y;
int f;
	if ( mx == 0 )
		return 0;
	f = 0;
	for ( x = 0 ; x < 2 ; x ++ )
		for ( y = 0 ; y < 2 ; y ++ ) {
			if ( __clean_radar_matrix(mx->mx[x][y]) == 0 ) {
				mx->mx[x][y] = 0;
			}
			else {
				f = 1;
			}
		}
	if ( f )
		return 1;
	_free_radar_matrix(mx);
	return 0;
}

void
_clean_radar_matrix()
{
	if ( __clean_radar_matrix(rc.matrix) == 0 )
{
ss_printf("CREAN\n");
		rc.matrix = 0;
}
	_clean_top_of_matrix();
}

void
_clean_force_matrix(int clear_count)
{
RADAR_MATRIX * mx;
int x,y;
int f;

int loop;

loop = 0;

	for ( mx = rc.mtx_h.prev ; mx != &rc.mtx_h && clear_count > 0 ;
				mx = mx->prev , loop ++ ) {
		f = 0;

		for ( x = 0 ; x < 2 ; x ++ )
			for ( y = 0 ; y < 2 ; y ++ )
				if ( mx->mx[x][y] ) {
					f = 1;
					break;
				}
		if ( f )
			continue;
/*
printf("clean force %x %f %f %i\n",mx->list,mx->resolution,mx->loaded_reso,loop);
*/
		mx->loaded_reso = mx->resolution*2;

		_free_node_from_matrix(mx);

		clear_count --;

		return;
	}
}

void
clean_radar_matrix()
{
	if ( rc.matrix_count < 2*RADAR_MATRIX_CACHE_SIZE )
		goto end;
retry:
	_clean_radar_matrix();
	if ( rc.matrix_count <= RADAR_MATRIX_CACHE_SIZE )
		goto end;
	_clean_force_matrix(rc.matrix_count-RADAR_MATRIX_CACHE_SIZE);
/*
printf("retry %i\n",rc.matrix_count);
if ( rc.matrix_count > 100 )
er_panic("a\n");
*/
	goto retry;
end:
	{}
/*
printf("retry end %i\n",rc.matrix_count);
*/
}


int
set_ptr_list(int ses,RADAR_CRD * c)
{
L_CHAR * url;
MP_ROUTE * mpr;
MAP_HISTORY * mh;
RESOURCE * r, * map_r;
GB_POINT ptr[8];
REAL1	reso[8];
int i;
GB_RECT mr;
URL u,u2;
int ret;
int len;
LOAD_RESOURCE_WORK * w;


set_t_msg(100);

	w = 0;
	url = c->crd_path;
	get_url2(&u,url,1553);
	get_url2(&u2,rc.base_url,1554);
set_t_msg(101);
	if ( url_cmp(&u,&u2) == 0 ) {

		free_url(&u);
		free_url(&u2);
		mh = 0;
		mpr = 0;
		if ( c->base_url )
			d_f_ree(c->base_url);
		c->base_url = ll_copy_str(rc.base_url,123);
		goto same;
	}
	free_url(&u);
	free_url(&u2);
set_t_msg(102);
	if ( c->base_url )
		d_f_ree(c->base_url);
	c->base_url = ll_copy_str(rc.base_url,123);
	{
	L_CHAR * tmp;
		tmp = ll_copy_str(rc.base_url,123);
		mpr = resolve_route(tmp,url,RR_WM_INDIRECT);
		d_f_ree(tmp);
	}
	if ( mpr == 0 || mpr == MP_NO_ROUTE ) {
		ret = -1;
		goto end;
	}
	get_url2(&u,rc.base_url,1555);
	mh = get_mh_from_route(ses,&u,mpr);
	free_url(&u);
	if ( mh == MP_MH_NO_ROUTE ) {
		ret = -2;
		goto mp_flush_end;
	}
same:

set_t_msg(104);
	len = l_strlen(c->obj_path);
	if ( l_strcmp(&c->obj_path[len-4],l_string(std_cm,".crd")) ) {
		map_r = get_map_between(ses,c->obj_path,c->crd_path);
		if ( map_r == 0 ) {
			ret = -3;
			goto mp_flush_end;
		}
	}
	else {
		map_r = 0;
	}
set_t_msg(105);
	get_url2(&u,c->obj_path,1556);
	w = new_lrw(0);
	get_url2(&w->url,c->crd_path,123);
	w = new_lrw(w);
	get_url2(&w->url,c->obj_path,123);
	load_resource_list(w,Q_PRI_RADAR,1);
	r = get_lrw(w,&u);
	if ( r == 0 )
		er_panic("radar");
	free_url(&u);
	if ( r == 0 ) {
		ret = -4;
		goto mp_flush_end;
	}
	mr = r->h.minrect;
	if ( r->h.visible_resolution == 0 ||
		mr.br.x - mr.tl.x < 1/r->h.visible_resolution ||
		mr.br.y - mr.tl.y < 1/r->h.visible_resolution ) {

		ret = -5;
		goto mp_flush_end;
	}

	ptr[0] = mr.tl;
	ptr[1] = mr.br;
	ptr[2].x = mr.tl.x;
	ptr[2].y = mr.br.y;
	ptr[3].x = mr.br.x;
	ptr[3].y = mr.tl.y;
	ptr[4] = p_add(ptr[0],ptr[2]);
	ptr[4].x = ptr[4].x/2;
	ptr[4].y = ptr[4].y/2;
	ptr[5] = p_add(ptr[0],ptr[3]);
	ptr[5].x = ptr[5].x/2;
	ptr[5].y = ptr[5].y/2;
	ptr[6] = p_add(ptr[1],ptr[2]);
	ptr[6].x = ptr[6].x/2;
	ptr[6].y = ptr[6].y/2;
	ptr[7] = p_add(ptr[1],ptr[3]);
	ptr[7].x = ptr[7].x/2;
	ptr[7].y = ptr[7].y/2;
set_t_msg(106);
	for ( i = 0 ; i < 8 ; i ++ )
		reso[i] = 1;
set_t_msg(107);
	if ( map_r )
		map_conv_forward(map_r,ptr,reso,8);
set_t_msg(108);

	get_url2(&u,c->crd_path,1557);
	r = get_lrw(w,&u);
set_t_msg(109);
	if ( r == 0 )
		er_panic("radar");
	free_url(&u);
set_t_msg(110);
	if ( r == 0 ) {
		ret = -6;
		goto mp_flush_end;
	}
set_t_msg(111);
	for ( i = 0 ; i < 8 ; i ++ )
		reso[i] = r->h.visible_resolution;
set_t_msg(112);
	if ( mh )
		map_from_resource(mh,ptr,reso,8);
set_t_msg(113);
	for ( i = 0 ; i < 8 ; i ++ ) {
		rc.ptr[c->bufid*8 + i] = ptr[i];
		rc.res[c->bufid*8 + i] = reso[i];
	}

set_t_msg(114);
	free_mh(mh);
	c->resolution = reso[0];

	if ( c->resolution == 0 ) {
		ret = -7;
		goto mp_flush_end;
	}
set_t_msg(116);

	mr.tl.x = mr.tl.y = 0;
	mr.br.x = mr.br.y = -1;
	for ( i = 0 ; i < 8 ; i ++ )
		insert_rect(&mr,rc.ptr[c->bufid*8+i]);
	c->minrect = mr;
	ret = 0;

set_t_msg(117);

mp_flush_end:

set_t_msg(118);
	flush_route(mpr);
end:
	free_lrw_req_next(w);
set_t_msg(119);

	return ret;
}

int
_insert_radar_url(int ses,L_CHAR * crd,L_CHAR * obj)
{
RADAR_CRD * c;
int ret;
GB_RECT mr;
int i;
RESOURCE * r, * r2;
URL u;
LOAD_RESOURCE_WORK * w;

	w = 0;
if ( l_strcmp(crd,obj) == 0 )
printf("ins_url %s\n",n_string(std_cm,crd));
	rlock_base_url("_insert_radar_url");
/*
printf("R1\n");
*/
	if ( rc.base_url == 0 ) {
		ret = -1;
		goto end;
	}
	c = search_radar_crd(crd,obj);

	if ( c ) {
/*
printf("reso2 %f (%f %f)-(%f %f)\n",c->resolution,
c->minrect.tl.x,
c->minrect.tl.y,
c->minrect.br.x,
c->minrect.br.y);
*/
		if ( c->resolution <= 0 )
			goto flush_end;
		insert_radar_matrix(c);
		ret = 0;
		goto flush_end;
	}
	c = search_radar_crd(crd,crd);
	if ( c ) {
		if ( c->resolution <= 0 )
			goto flush_end;
		insert_radar_matrix(c);
		ret = 0;
		goto flush_end;
	}
	w = new_lrw(0);
	get_url2(&w->url,crd,1234);
	w = new_lrw(w);
	get_url2(&w->url,obj,1234);
	load_resource_list(w,Q_PRI_RADAR,1);

	get_url2(&u,crd,1234);
	r = get_lrw(w,&u);
	free_url(&u);
	if ( r == 0 )
		goto flush_end;

	get_url2(&u,obj,1234);
	r2 = get_lrw(w,&u);
	free_url(&u);
	if ( r2 == 0 )
		goto flush_end;
/*
printf("AA\n");
*/
	c = new_radar_crd();
	c->crd_path = ll_copy_str(crd,1518);
	c->obj_path = ll_copy_str(obj,1519);
	c->base_url = ll_copy_str(rc.base_url,1520);

	c->crd_bib = copy_bib_list(r->h.bib);
	c->obj_bib = copy_bib_list(r2->h.bib);
	c->crd_r = r;
	c->obj_r = r2;
	ret = set_ptr_list(ses,c);

/*
printf("reso1 %f (%f %f)-(%f %f)\n",c->resolution,
c->minrect.tl.x,
c->minrect.tl.y,
c->minrect.br.x,
c->minrect.br.y);

printf(">> %i\n",ret);
*/

	if ( ret == 0 )
		insert_radar_matrix(c);
	else	c->resolution = 0;

flush_end:


	if ( c )
	  flush_radar_crd(c);
end:


	free_lrw_req_next(w);

	if ( ret == 0 ) {
		rc.win_load = 1;
		wakeup_win_manage();
	}
	unlock_base_url();
	return ret;
}




int
remake_cache(int ses,int type,WF_ID wfid,WF_ID next)
#define RCT_CHANGE	1
#define RCT_DELETE	2
{
MAP_HISTORY * mh;
MP_ROUTE * mpr;
RADAR_CRD * c;
URL u;
L_CHAR * new;
RESOURCE *draw;
int i,j;


set_cpu_msg(2501);

ss_printf("NEXT %i\n",next);


	wfid = wf_get_current();
	if ( next )
		wf_set_current_target(next);
if ( env.flame == 0 )
er_panic("???");

	switch ( type ) {
	case RCT_CHANGE:
		if ( next && wfid == next )
			return 0;
		break;
	case RCT_DELETE:
		if ( rc.win_delete_lock == 0 &&
				wf_check_last(wfid) == 0 )
{ss_printf("REMAKE FREE\n");
			free_win_flame(wfid);
}
		else return 0;
		wf_wait_stable();
		break;
	default:
		er_panic("remake_cache");
	}
	wfid = wf_get_current();
	draw = wf_get_resource(wfid);


	wlock_base_url("remake_cache");

	if ( draw == 0 ) {


ss_printf("DRAW ZERO *************************************** DRAW ZERO\n");
if ( env.flame == 0 )
er_panic("stop");
		lock_task(radar_lock);
		if ( rc.base_url )
			d_f_ree(rc.base_url);
		rc.base_url = 0;
		_free_radar_matrix(rc.matrix);
		rc.matrix = 0;
		for ( ; rc.crd[0].next != &rc.crd[0] ; ) {
			c = rc.crd[0].next;
			_free_radar_crd(c);
		}

		unlock_task(radar_lock,"remake");

		goto last;
	}
	new = ll_copy_str(get_url_str2(&draw->h.entry),1521);



	if ( rc.base_url == 0 ) {

		free_radar_matrix();
		rc.base_url = ll_copy_str(new,1522);
		goto end;
	}


	{
	L_CHAR * tmp;
		tmp = ll_copy_str(rc.base_url,124);
		mpr = resolve_route(tmp,new,RR_WM_INDIRECT);
		d_f_ree(tmp);
	}
	if ( mpr == 0 || mpr == MP_NO_ROUTE )
		goto end;
	get_url2(&u,rc.base_url,1558);


	mh = get_mh_from_route(ses,&u,mpr);


	free_url(&u);
	if ( mh == MP_MH_NO_ROUTE )
		goto end_flush;
	for ( i = 0; i < RADAR_CACHE_SIZE ; i ++ ) {
		c = &rc.crd[i];
		c->flags &= ~RCF_INMATRIX;
	}
	for ( c = rc.crd[0].next ; c != &rc.crd[0] ; c = c->next ) {
		if ( c->list == 0 )
			continue;
		c->flags |= RCF_INMATRIX;
	}




	free_radar_matrix();

	map_from_flame(mh,rc.ptr,rc.res,RADAR_CACHE_SIZE*8);


	for ( c = rc.crd[0].next ; c != &rc.crd[0] ; c = c->next ) {
		c->resolution = rc.res[c->bufid*8];

		c->minrect.tl.x = c->minrect.tl.y = 0;
		c->minrect.br.x = c->minrect.br.y = -1;
		for ( j = 0 ; j < 8 ; j ++ )
			insert_rect(&c->minrect,rc.ptr[c->bufid*8+j]);
		c->lock = 0;


		if ( (c->flags & RCF_INMATRIX) == 0  )
			continue;

		if ( c->base_url )
			d_f_ree(c->base_url);
		c->base_url = 0;
ss_printf("ins %s\n",n_string(std_cm,c->obj_path));
		if ( c->flags & RCF_INMATRIX ) 
			insert_radar_matrix(c);
	}



ss_printf("REMAKE %ls --> ",rc.base_url);

	d_f_ree(rc.base_url);

ss_printf("%ls\n",new);

	rc.base_url = ll_copy_str(new,1523);

end_flush:
	flush_route(mpr);
end:
	d_f_ree(new);
last:
	unlock_base_url();
	{}


	return 1;
}


int
cmp_wf_crd(CRD_LIST * c1,CRD_LIST * c2)
{
URL u;
L_CHAR * fp1, * fp2;
RESOURCE * draw;
	if ( c1->crd )
		fp1 = c1->crd->crd_path;
	else {
		draw = wf_get_resource(c1->wfid);
		if ( draw )
			fp1 = get_url_str2(&draw->h.entry);
		else	fp1 = l_string(std_cm,"");
	}
	if ( c2->crd )
		fp2 = c2->crd->crd_path;
	else {
		draw = wf_get_resource(c2->wfid);
		if ( draw )
		 	fp2 = get_url_str2(&draw->h.entry);
		else	fp2 = l_string(std_cm,"");
	}
	return l_strcmp(fp1,fp2);
}

AVT_NODE *
get_wf_tree()
{
AVT_NODE * ret;
WF_ID wfid;
AVT_NODE * a;
CRD_LIST * cl;
int no;
unsigned int t;
	ret = 0;
	t = get_xltime();
	for ( no = 0 ; ; no ++ ) {
		wfid = wf_get(no);
		if ( wfid == 0 )
			break;
		cl = d_alloc(sizeof(*cl),1212);
		a = d_alloc(sizeof(*a),1213);
		cl->wfid = wfid;
		cl->crd = 0;
		if ( t - wf_insert_time(wfid) > 10 )
			cl->sts = CLS_REMOVE;
		else	cl->sts = CLS_KEEP;
		a->data = cl;
		avt_insert(&ret,a,cmp_wf_crd);
	}
	return ret;
}

typedef struct keep_work {
	REAL1		sum_surf;
} KEEP_WORK;

int
keep_check(AVT_NODE * a,KEEP_WORK * w)
{
CRD_LIST * cl;
REAL1 s;
GB_RECT r;
RESOURCE * res;
	cl = a->data;
	if ( cl->crd == 0 )
		return 0;
	if ( w->sum_surf > WIN_SURF_RATE_MIN ) {
		switch ( cl->sts ) {
		case CLS_KEEP:
			cl->sts = CLS_REMOVE;
ss_printf("REMOVE 6 ======================\n");
			break;
		case CLS_REMOVE:
			break;
		case CLS_INSERT:
			cl->sts = CLS_NONE;
			break;
		}
	}
	else {
		res = cl->crd->crd_r;
/*
if ( res && res->h.type == RT_COORDINATE )
ss_printf("WEIGHT %ls %f\n",get_url_str2(&res->h.entry),res->c.weight);
*/
		if ( res == 0 )
			w->sum_surf += 1;
		else if ( res->h.type == RT_COORDINATE )
			w->sum_surf += res->c.weight;
		else	w->sum_surf += 1;
	}
	return 0;
}

int
cmp_reso_sort(CRD_LIST * c1,CRD_LIST * c2)
{
	if ( c1->crd->resolution < c2->crd->resolution )
		return -1;
	if ( c1->crd->resolution > c2->crd->resolution )
		return 1;
	return l_strcmp(c1->crd->crd_path,c2->crd->crd_path);
}

int
reso_sort(AVT_NODE * a,AVT_NODE ** tree)
{
AVT_NODE * a1;
CRD_LIST * cl;
	cl = a->data;
	if ( cl->crd == 0 )
		return 0;
	a1 = d_alloc(sizeof(*a1),1234);
	a1->data = cl;
	avt_insert(tree,a1,cmp_reso_sort);
	return 0;
}

void
free_reso_tree(AVT_NODE * a)
{
	if ( a == 0 )
		return;
	free_reso_tree(a->small);
	free_reso_tree(a->large);
	d_f_ree(a);
}

int
_cmp_cache_wf(AVT_NODE ** tree,RADAR_MATRIX_LIST * lst,REAL1 reso,
	GB_RECT * r,KEEP_WORK * kw)
{
RADAR_NODE * n;
RADAR_CRD * c;
AVT_NODE * a;
CRD_LIST cl,* clp;
AVT_NODE * reso_tree;

	for ( ; lst ; lst = lst->next ) {
		_delete_radar_mtx_ring(lst->mx);
		_insert_radar_mtx_ring(lst->mx);
		for ( n = lst->mx->list ; n ; n = n->matrix_next ) {
			c = n->crd;
			c->lock ++;

ss_printf("CMP BEFOR %ls %lf\n",c->crd_path,(double)c->resolution);

			if ( cross_rect_rect(&c->minrect,r) == 0 )
				continue;

			if ( c->resolution > reso )
				continue;
			if ( c->crd_r && (c->crd_r->h.flags & RF_INDICATE) == RF_I_OFF )
				continue;

ss_printf("CMP CACHE %ls %lf\n",c->crd_path,(double)c->resolution);
/*
ss_printf("MINRECT (%f %f) = (%f %f)\n",
c->minrect.tl.x,
c->minrect.tl.y,
c->minrect.br.x,
c->minrect.br.y);
ss_printf("RECT (%f %f) = (%f %f)\n",
r->tl.x,
r->tl.y,
r->br.x,
r->br.y);
*/

			cl.wfid = 0;
			cl.crd = c;
			cl.sts = 0;
			a = avt_search(*tree,&cl,cmp_wf_crd);
			if ( a ) {
				clp = a->data;
				if ( clp->crd == 0 ) {
					clp = a->data;
					clp->crd = c;
					clp->sts = CLS_KEEP;
				}
			}
			else {
				clp = d_alloc(sizeof(*clp),1251);
				clp->wfid = 0;
				clp->crd = c;
				clp->sts = CLS_INSERT;
				a = d_alloc(sizeof(*a),1252);
				a->data = clp;
ss_printf("> %x\n",clp);
				avt_insert(tree,a,cmp_wf_crd);
			}
		}
	}
	kw->sum_surf = 0;
	reso_tree = 0;
	avt_trace_from_small(*tree,reso_sort,&reso_tree);
	avt_trace_from_large(reso_tree,keep_check,kw);
	free_reso_tree(reso_tree);
	if ( kw->sum_surf > WIN_SURF_RATE_MIN )
		return -1;
	return 0;
}

RADAR_MATRIX_LIST * 
get_parent(RADAR_MATRIX_LIST * lst)
{
RADAR_MATRIX_LIST * ret, * lst1;
RADAR_MATRIX * mx;
	ret = 0;

	for ( ; lst ; lst = lst->next ) {
		mx = lst->mx->parent;
		if ( mx == 0 )
			continue;
		for ( lst1 = ret ; lst1 ; lst1 = lst1->next ) {
			if ( lst1->mx == mx )
				break;
		}
		if ( lst1 == 0 ) {
			lst1 = _new_radar_matrix_list(mx);
			lst1->next = ret;
			ret = lst1;
		}
	}
	return ret;
}

void
_free_wf_tree(AVT_NODE * tree)
{
CRD_LIST * c;
	if ( tree == 0 )
		return;
	_free_wf_tree(tree->small);
	_free_wf_tree(tree->large);
	c = tree->data;
	if ( c->crd )
		_flush_radar_crd(c->crd);
	d_f_ree(tree->data);
	d_f_ree(tree);
}


typedef struct win_insert_work {
	int		ses;
	REAL1		reso;
	URL		u;
	WF_ID	 	wfid;
	int		ret;
	REAL1		reso_min;
} WIN_INSERT_WORK;

int
win_insert_func(AVT_NODE * a,WIN_INSERT_WORK * w)
{
CRD_LIST * cl;
WF_ID wfid;
URL u;
RESOURCE * r;
GB_POINT center;
MAP_HISTORY * mh;
MP_ROUTE * mpr;

	cl = a->data;
/*
if ( cl->crd )
ss_printf("WIF ok %ls\n",cl->crd->crd_path);
else
ss_printf("WIF *  %x\n",cl);
*/
	switch ( cl->sts ) {
	case CLS_INSERT:
		if ( cl->crd )
			if ( w->reso_min == -1 || 
					w->reso_min > cl->crd->resolution )
				w->reso_min = cl->crd->resolution; 
		break;
	case CLS_KEEP:
		if ( cl->crd )
			if ( w->reso_min == -1 || 
					w->reso_min > cl->crd->resolution )
				w->reso_min = cl->crd->resolution;
		return 0;
	default:
		return 0;
	}


	get_url2(&u,cl->crd->crd_path,1559);

	r = load_resource(w->ses,&u,Q_PRI_RADAR);
set_cpu_msg(106);
	free_url(&u);
	{
	L_CHAR * tmp;
		tmp = ll_copy_str(rc.base_url,126);
		mpr = resolve_route(tmp,cl->crd->crd_path,RR_WM_INDIRECT);
		d_f_ree(tmp);
	}
set_cpu_msg(107);
	if ( mpr == MP_NO_ROUTE )
		goto end_flush2;
set_cpu_msg(108);
	if ( mpr == 0 )
		goto end_flush;
	mh = get_mh_from_route(w->ses,&w->u,mpr);
set_cpu_msg(109);
	if ( mh == MP_MH_NO_ROUTE )
		goto end_flush;
set_cpu_msg(110);
	center.x = center.y = 0;
printf("+++++++++++++++++++ insert %ls\n",cl->crd->crd_path);
	new_win_flame(
		&wfid,
		cl->crd->resolution,
		r,
		mh,
		center,
		0,
		w->reso);
	free_mh(mh);
set_cpu_msg(112);
	rc.win_delete_lock = 0;
end_flush:
	flush_route(mpr);
end_flush2:
set_cpu_msg(113);

	return 0;
}

int
win_delete_func(AVT_NODE * a,WIN_INSERT_WORK * w)
{
CRD_LIST * cl;
	cl = a->data;
	if ( cl->sts != CLS_REMOVE )
		return 0;
	if ( cl->wfid == w->wfid ) {
		w->ret = 1;
		return 0;
	}
	if ( rc.win_delete_lock )
		return 0;
	if ( wf_check_last(cl->wfid) == 0 )
{ss_printf("DELETE FUNC FREE\n");
		free_win_flame(cl->wfid);
}
	return 0;
}


int
free_crd_lock(AVT_NODE * a)
{
CRD_LIST * cl;
	cl = a->data;
	if ( cl->crd == 0 )
		return 0;
	cl->crd->lock --;
	return 0;
}


typedef struct h_same_meta_work {
	CRD_LIST *	target;
	AVT_NODE *	wf_tree;
} H_SAME_META_WORK;

int
h_same_meta_func2(AVT_NODE * a,H_SAME_META_WORK * w)
{
CRD_LIST * cl;
	cl = a->data;


	if ( cl == w->target )
		return 1;
	if ( cl->sts == CLS_NONE ||
			cl->sts == CLS_REMOVE )
		return 0;
	if ( cl->crd == 0 )
		return 0;
	if ( cmp_bib_list(cl->crd->crd_bib,w->target->crd->crd_bib) )
		goto ok;
	if ( cmp_bib_list(cl->crd->obj_bib,w->target->crd->obj_bib) )
		goto ok;

	if ( cl->wfid && w->target->wfid ) {
		cl->sts = CLS_REMOVE;
ss_printf("REMOVE 1 ======================\n");
		cl->crd = 0;
	}
	else if ( cl->wfid ) {
		w->target->sts = CLS_NONE;
		w->target->crd = 0;
		return 1;
	}
	else if ( w->target->wfid ) {
		cl->sts = CLS_NONE;
		cl->crd = 0;
	}
	else {
		cl->sts = CLS_NONE;
		cl->crd = 0;
	}
ok:
	return 0;
}

int
h_same_meta_func(AVT_NODE * a,H_SAME_META_WORK * w)
{
	w->target = a->data;
	if ( w->target->sts == CLS_NONE ||
			w->target->sts == CLS_REMOVE )
		return 0;
	if ( w->target->crd == 0 )
		return 0;
	if ( w->target->crd->crd_bib == 0 &&
		w->target->crd->obj_bib == 0 ) {
		if ( w->target->wfid ) {
			w->target->sts = CLS_REMOVE;
			w->target->crd = 0;
		}
		else {
			w->target->sts = CLS_NONE;
			w->target->crd = 0;
		}
		return 0;
	}
/*
	avt_trace_from_large(w->wf_tree,h_same_meta_func2,w);
*/
	return 0;
}

void
h_search_same_meta(AVT_NODE * wf_tree)
{
H_SAME_META_WORK w;
	w.wf_tree = wf_tree;
	avt_trace_from_small(wf_tree,h_same_meta_func,&w);
}

typedef struct h_relation_work {
	CRD_LIST *	target;
	AVT_NODE *	wf_tree;
	L_CHAR *	ms;
} H_RELATION_WORK;



int
h_relation_master(AVT_NODE * a,H_RELATION_WORK * w)
{
CRD_LIST * cl;
	cl = a->data;

ss_printf("REL %x %x\n",cl,cl->crd);
	if ( cl == w->target )
		return 0;
	if ( cl->sts == CLS_NONE ||
			cl->sts == CLS_REMOVE )
		return 0;
	if ( cl->crd == 0 )
		return 0;

	if ( l_strcmp(cl->crd->crd_path,w->ms) )
		return 0;

	if ( w->target->wfid ) {
		w->target->sts = CLS_REMOVE;
ss_printf("REMOVE 2 ====================== %ls %ls\n",cl->crd->crd_path,w->target->crd->crd_path);
		return 1;
	}
	w->target->sts = CLS_NONE;
	return 1;
}


int
h_relation_slave(AVT_NODE * a,H_RELATION_WORK * w)
{
CRD_LIST * cl;
	cl = a->data;
	if ( cl == w->target )
		return 0;
	if ( cl->sts == CLS_NONE ||
			cl->sts == CLS_REMOVE )
		return 0;
	if ( cl->crd == 0 )
		return 0;

	if ( l_strcmp(cl->crd->crd_path,w->ms) )
		return 0;

	if ( cl->wfid ) {
		cl->sts = CLS_REMOVE;
ss_printf("REMOVE 3 ======================\n");
		return 1;
	}
	cl->sts = CLS_NONE;
	return 1;
}


int
h_relation_func(AVT_NODE * a,H_RELATION_WORK * w)
{
	w->target = a->data;
	if ( w->target->sts == CLS_NONE ||
			w->target->sts == CLS_REMOVE )
		return 0;
	if ( w->target->crd == 0 )
		return 0;
	if ( w->target->crd->crd_r->c.relation_master ) {
		w->ms = w->target->crd->crd_r->c.relation_master;
		avt_trace_from_large(w->wf_tree,h_relation_master,w);
		return 0;
	}
	if ( w->target->crd->crd_r->c.relation_slave ) {
		w->ms = w->target->crd->crd_r->c.relation_slave;
		avt_trace_from_large(w->wf_tree,h_relation_slave,w);
		return 0;
	}
	return 0;
}

void
h_search_relation(AVT_NODE * wf_tree)
{
H_RELATION_WORK w;
	w.wf_tree = wf_tree;
	avt_trace_from_small(wf_tree,h_relation_func,&w);
}


int
h_limit_reso_func(AVT_NODE * a,HEURISTICS_PARAM * w)
{
CRD_LIST * cl;
RESOURCE * r;
MP_ROUTE * mpr;
MAP_HISTORY * mh;
GB_POINT ptr;
REAL1 reso,r_width,reso2;
REAL1 lrr;
URL u;

	cl = a->data;


	if ( cl->sts == CLS_NONE ||
			cl->sts == CLS_REMOVE )
		return 0;
	if ( cl->crd == 0 )
		return 0;
	r = cl->crd->crd_r;
	if ( r->c.limit_resolution == 0 )
		return 0;
	if ( r->c.flags & CF_FIX_LIMIT_RESO )
		lrr = 1;
	else	lrr = LIMIT_RESOLUTION_RATE;
	if ( r->h.visible_resolution*lrr > 
			r->c.limit_resolution )
		reso = r->h.visible_resolution*lrr;
	else 	reso = r->c.limit_resolution;
	r_width = r->h.visible_resolution
			/r->c.limit_resolution
			*lrr;
	if ( resolution_width < r_width )
		resolution_width = r_width;

	reso = cl->crd->resolution * reso / r->h.visible_resolution;


	if ( reso == -1 )
		return 0;
	if ( reso*lrr >= w->base_resolution )
		return 0;

	if ( cl->wfid == 0 )
		cl->sts = CLS_NONE;
	else	
		cl->sts = CLS_REMOVE;
	return 0;
}

void
h_search_limit_resolution(AVT_NODE * wf_tree,
	HEURISTICS_PARAM * p)
{
	avt_trace_from_small(wf_tree,h_limit_reso_func,p);
}

void
heuristics_search(AVT_NODE * wf_tree,HEURISTICS_PARAM * p)
{

	h_search_limit_resolution(wf_tree,p);
	h_search_same_meta(wf_tree);
	h_search_relation(wf_tree);
}


typedef struct base_pri_work {
	GB_RECT 	r;
	CRD_LIST * 	cl;
	double		bpri;
	double		max_reso;
	double		min_reso;
	int		change_on;
	WF_ID		wfid;
} BASE_PRI_WORK;

int
win_base_reso_cal(AVT_NODE * a,BASE_PRI_WORK * w)
{
CRD_LIST * cl;
double v_rate,h_rate,bpri,d,reso;
double v,h;
GB_RECT * mr;
GB_POINT c;
int adj;

	cl = a->data;
	switch ( cl->sts ) {
	case CLS_NONE:
	case CLS_REMOVE:
		return 0;
	case CLS_KEEP:
	case CLS_INSERT:
		break;
	}
	if ( cl->crd == 0 )
		return 0;
/*
		er_panic("win_base_pri");
*/
	mr = &cl->crd->minrect;
	d = v_rate = h_rate = reso = h = v = 0;
	if ( cross_rect_rect(mr,&w->r) == 0 ) {
		bpri = 0x7fffffff;
		goto end;
	}
	h_rate = (mr->br.x - mr->tl.x) / (h = w->r.br.x - w->r.tl.x);
	v_rate = (mr->br.y - mr->tl.y) / (v = w->r.br.y - w->r.tl.y);

	if ( h_rate < 1 || v_rate < 1 ) {
		bpri = 0x7fffffff;
		goto end;
	}

	if ( w->max_reso == 0 || w->max_reso < cl->crd->resolution )
		w->max_reso = cl->crd->resolution;
	if ( w->min_reso == 0 || w->min_reso > cl->crd->resolution )
		w->min_reso = cl->crd->resolution;

end:
	return 0;
}

int
win_base_pri(AVT_NODE * a,BASE_PRI_WORK * w)
{
CRD_LIST * cl;
double v_rate,h_rate,bpri,d,reso;
double v,h;
GB_RECT * mr;
GB_POINT c;
int adj;

#define ADJ_W 200
#define RESO_W	100
	cl = a->data;
	switch ( cl->sts ) {
	case CLS_NONE:
		return 0;
	case CLS_REMOVE:
		if ( cl->wfid == w->wfid )
			w->change_on = 1;
		return 0;
	case CLS_KEEP:
	case CLS_INSERT:
		break;
	}
	if ( cl->crd == 0 )
		return 0;
/*
		er_panic("win_base_pri");
*/
	mr = &cl->crd->minrect;
	d = v_rate = h_rate = reso = h = v = 0;
	if ( cross_rect_rect(mr,&w->r) == 0 ) {
		bpri = 0x7fffffff;
		if ( cl->wfid == w->wfid )
			w->change_on = 1;
		goto end;
	}
	h_rate = (mr->br.x - mr->tl.x) / (h = w->r.br.x - w->r.tl.x);
	v_rate = (mr->br.y - mr->tl.y) / (v = w->r.br.y - w->r.tl.y);

	if ( h_rate < 1 || v_rate < 1 ) {
		bpri = 0x7fffffff;
		if ( cl->wfid == w->wfid )
			w->change_on = 1;
		goto end;
	}


	c = p_sub(p_add(mr->br,mr->tl),p_add(w->r.br,w->r.tl));

/*
ss_printf("B+ %lf %lf\n",c.x,c.y);
*/
	if ( c.x < 0 )
		c.x = - c.x;
	if ( c.y < 0 )
		c.y = - c.y;

	d = (c.x/h + c.y/v)/2;
	if ( w->max_reso == w->min_reso )
		reso = 0;
	else	reso = RESO_W*(w->max_reso - cl->crd->resolution)
				/(w->max_reso - w->min_reso);
	bpri = reso + d;

	if ( cl->wfid ) {
		bpri += ADJ_W*(adj = get_wf_priadj(cl->wfid));
/*
ss_printf("BBB %i %i - %i\n",cl->wfid,w->wfid,adj);
*/
		if ( adj && cl->wfid == w->wfid )
			w->change_on = 1;
	}
end:
/*
ss_printf("B %ls %lf - %lf %lf %lf %lf %i\n",
cl->crd->crd_path,bpri,
reso,d,h,v,adj);
*/
	if ( cl->wfid && w->bpri > bpri ) {
		w->cl = cl;
		w->bpri = bpri;
	}
	return 0;
}


/***/
WF_ID
win_manage(WF_ID * next,int ses,REAL1 reso,GB_RECT * r)
{
RADAR_MATRIX_LIST * lst1,* lst2;
AVT_NODE * wf_tree;
WIN_INSERT_WORK w;
KEEP_WORK kw;
HEURISTICS_PARAM hw;
BASE_PRI_WORK bw;

	lock_task(radar_lock);
ss_printf("WIN_MANAGE (%f %f)(%f %f) %f - %ls\n",
r->tl.x,
r->tl.y,
r->br.x,
r->br.y,
reso,
rc.base_url
);
ss_printf(">>> %i\n",check_matrix_size());

	_rlock_base_url("win_manage");

retry:
	if ( rc.base_url == 0 ) {
		_unlock_base_url();
		unlock_task(radar_lock,"win_manage(1)");
		return 0;
	}
	wf_tree = get_wf_tree();
	lst1 = _get_radar_matrix(reso,r);

	for ( ; lst1 ; ) {
		if ( _cmp_cache_wf(&wf_tree,lst1,reso,r,&kw) < 0 ) {
			_free_radar_matrix_list(lst1);
			break;
		}
		lst2 = get_parent(lst1);
		_free_radar_matrix_list(lst1);
		lst1 = lst2;
	}
	if ( rc.win_reso_window < resolution_width &&
			kw.sum_surf < WIN_SURF_RATE_MIN ) {
		_free_wf_tree(wf_tree);
		rc.win_reso_window *= 4;
		rc.win_reso_max = reso;
		rc.win_rect = *r;
		rc.win_force = 1;
		goto retry;
	}
	else if ( rc.win_reso_window > WIN_RESO_WINDOW_MIN &&
			kw.sum_surf > WIN_SURF_RATE_MAX )
		rc.win_reso_window /= 2;


	unlock_task(radar_lock,"win_manage(1)");

	hw.ses = ses;
	hw.base_resolution = reso;
	heuristics_search(wf_tree,&hw);
	w.ses = ses;
	w.reso = reso;
	w.wfid = wf_get_current();
	w.ret = 0;
	w.reso_min = -1;
	get_url2(&w.u,rc.base_url,1560);

	avt_trace_from_small(wf_tree,win_insert_func,&w);
	avt_trace_from_small(wf_tree,win_delete_func,&w);

	free_url(&w.u);

	bw.r = *r;
	bw.bpri = 0x7fffffff;
	bw.cl = 0;
	bw.max_reso = bw.min_reso = 0;
	bw.change_on = 0;
	bw.wfid = w.wfid;
/*
ss_printf("BB %f %f - %f %f\n",
bw.r.tl.x,
bw.r.tl.y,
bw.r.br.x,
bw.r.br.y
);
*/
	avt_trace_from_small(wf_tree,win_base_reso_cal,&bw);

	avt_trace_from_small(wf_tree,win_base_pri,&bw);
/*
ss_printf("BB - %x %i\n",bw.cl,bw.change_on);
*/
	if ( bw.cl && bw.change_on )
		*next = bw.cl->wfid;
	else	*next = 0;
/*
if ( bw.cl )
ss_printf("NEXT %ls\n",bw.cl->crd->crd_path);
*/

	lock_task(radar_lock);
	avt_trace_from_small(wf_tree,free_crd_lock,0);


	_free_wf_tree(wf_tree);
	unlock_task(radar_lock,"win_manage(3)");

	lock_task(radar_lock);

	_unlock_base_url();

ss_printf("WIN_MANAGE END\n");

	rc.win_reso_max = reso;
	rc.win_rect = *r;
	unlock_task(radar_lock,"win_manage");
	if ( w.ret )
		return w.wfid;
	else	return 0;
}

int
in_condition(GB_RECT * r,REAL1 window,REAL1 max)
{
	if ( r->tl.x != rc.win_rect.tl.x )
		return -1;
	if ( r->tl.y != rc.win_rect.tl.y )
		return -1;
	if ( r->br.x != rc.win_rect.br.x )
		return -1;
	if ( r->br.y != rc.win_rect.br.y )
		return -1;
	if ( window != rc.win_reso_window )
		return -1;
	if ( max != rc.win_reso_max )
		return -1;
	return 0;
}



void
_empty_radar_matrix(RADAR_MATRIX * mx,int fn_flag)
{
int x,y;
	if ( mx == 0 )
		return;
	if ( fn_flag )
		_free_node_from_matrix(mx);
	mx->loaded_reso = mx->resolution*2;


	for ( x = 0 ; x < 2 ; x ++ )
		for ( y = 0 ; y < 2 ; y ++ )
			_empty_radar_matrix(mx->mx[x][y],fn_flag);
}


XL_SEXP *
gv_radar_status(XLISP_ENV * env,XL_SEXP * s)
{
XL_SEXP * ret;
RADAR_LUMP * rl;

	ret = 0;
	lock_task(radar_lock);
	for ( rl = rc.lump ; rl ; rl = rl->next ) {
		ret = cons(
			List(n_get_symbol("lump"),
				get_string(rl->lumpcrd_path),
				List(n_get_symbol("pmd"),
					get_string(rl->db_path),
					List(
					List(get_floating(rl->sphere.tl.x,
							l_string(std_cm,"m")),
						get_floating(rl->sphere.tl.y,
							l_string(std_cm,"m")),
						-1),
					List(get_floating(rl->sphere.br.x,
							l_string(std_cm,"m")),
						get_floating(rl->sphere.br.y,
							l_string(std_cm,"m")),
						-1),
					-1),
					get_floating(rl->reso_min,
						l_string(std_cm,"dot/m")),
					get_floating(rl->reso_max,
						l_string(std_cm,"dot/m")),
					-1),
				-1),
			ret);
	}
	unlock_task(radar_lock,"gv_status");
	return cons(n_get_symbol("status"),ret);
}

void
_query_trigger(int fn_flag)
{

	lock_task(radar_lock);

	_empty_radar_matrix(rc.matrix,fn_flag);
	rc.win_force = 1;
	rc.win_delete_lock = 1;
	wakeup_task((int)loading_task);

	unlock_task(radar_lock,"query_trigger");
}

void
query_trigger(int fn_flag)
{

	rc_task_lock(TM_TRIG);
	_query_trigger(fn_flag);
	rc_task_unlock(TM_TRIG);
printf("***** query_trigger end\n");
}

void
_query_trigger2()
{

	lock_task(radar_lock);

	rc.win_force = 1;
	rc.win_delete_lock = 1;
	wakeup_task((int)loading_task);

	unlock_task(radar_lock,"query_trigger");
}

void
query_trigger2()
{

printf("***** query_trigger2\n");
	rc_task_lock(TM_TRIG);
	_query_trigger2();
	rc_task_unlock(TM_TRIG);
}

int
__include_query_check(XL_SEXP * rc_q,XL_SEXP * q)
{
int ret;
	ret = gbb_equ(rc_q,q);
	if ( ret )
		return 0;
	return -1;
}

int
_include_query_check(XL_SEXP * rc_q,XL_SEXP * q)
{
XL_SEXP * cmd;
	if ( get_type(rc_q) != XLT_PAIR )
		return __include_query_check(rc_q,q);
	cmd = car(rc_q);
	if ( get_type(cmd) != XLT_SYMBOL )
		return __include_query_check(rc_q,q);
	if ( l_strcmp(cmd->symbol.data,l_string(std_cm,"OR")) )
		return __include_query_check(rc_q,q);
	rc_q = cdr(rc_q);
	for ( ; get_type(rc_q) == XLT_PAIR ; rc_q = cdr(rc_q) ) {
		if ( __include_query_check(car(rc_q),q) == 0 )
			return 0;
	}
	return -1;
}

XL_SEXP *
include_query_check(XL_SEXP * rc_query,XL_SEXP * query)
{
XL_SEXP * cmd;
int ret;
XL_SEXP * _ret;
int len;
	if ( get_type(query) != XLT_PAIR ) {
		ret = _include_query_check(rc_query,query);
		if ( ret )
			return query;
		return 0;
	}
	cmd = car(query);
	if ( get_type(cmd) != XLT_SYMBOL ) {
		ret = _include_query_check(rc_query,query);
		if ( ret )
			return query;
		return 0;
	}
	if ( l_strcmp(cmd->symbol.data,l_string(std_cm,"OR")) ) {
		ret = _include_query_check(rc_query,query);
		if ( ret )
			return query;
		return 0;
	}
	query = cdr(query);
	_ret = 0;
	len = 0;
	for ( ; get_type(query) == XLT_PAIR ; query = cdr(query) ) {
		ret = _include_query_check(rc_query,car(query));
		if ( ret ) {
			_ret = cons(car(query),_ret);
			len ++;
		}
	}
	switch ( len ) {
	case 0:
		return 0;
	case 1:
		return car(_ret);
	default:
		return cons(n_get_symbol("OR"),_ret);
	}
}


XL_SEXP *
gv_is_insert_query(XLISP_ENV * env,XL_SEXP * s,
	XLISP_ENV * a,XL_SYM_FIELD * sf)
{
XL_SEXP * query;
XL_SEXP * cmd;


	query = gb_quote_trace(env,get_el(s,1),
		get_sf_attribute(sf,l_string(std_cm,"type")));
	if ( get_type(query) == XLT_ERROR )
		return query;
	if ( get_type(query) != XLT_PAIR )
		goto type_missmatch;
	cmd = car(query);
	if ( get_type(cmd) != XLT_SYMBOL )
		goto type_missmatch;


	set_opening_state_query();

	lock_task(query_lock);
	query = include_query_check(rc.query,query);

	if ( query == 0 ) {
		unlock_task(query_lock,"insert_query");
		return 0;
	}
	if ( get_type(rc.query) == 0 ) {
		rc.query = query;
	}
	else if ( l_strcmp(cmd->symbol.data,l_string(std_cm,"OR")) == 0 ) {
		cmd = car(rc.query);
		if ( l_strcmp(cmd->symbol.data,
				l_string(std_cm,"OR")) == 0 ) {
			rc.query = cons(n_get_symbol("OR"),
				append(cdr(rc.query),cdr(query)));
		}
		else {
			rc.query = cons(n_get_symbol("OR"),
				cons(rc.query,cdr(query)));
		}
	}
	else {
		cmd = car(rc.query);
		if ( l_strcmp(cmd->symbol.data,l_string(std_cm,"OR")) == 0 ) {
			rc.query = cons(n_get_symbol("OR"),
					append(cdr(rc.query),cons(query,0)));
		}
		else {
			rc.query = cons(n_get_symbol("OR"),
					cons(rc.query,cons(query,0)));
		}
	}
	query = rc.query;

	_set_q_mode();

	unlock_task(query_lock,"insert_query");

	query_trigger(1);

	reset_q_mode();

	return query;

type_missmatch:
	return get_error(
		s->h.file,
		s->h.line,
		XLE_SEMANTICS_TYPE_MISSMATCH,
		l_string(std_cm,"gv-insert-query"),
		List(n_get_string("type missmatch"),
			query,
			-1));
}


XL_SEXP *
gv_is_delete_query(XLISP_ENV * env,XL_SEXP * s)
{
XL_SEXP * no;
int _no;
XL_SEXP * query, * new, * ret;
int i;
XL_SEXP * cmd;

	no = get_el(s,1);
	if ( get_type(no) != XLT_INTEGER )
		goto type_missmatch;
	_no = no->integer.data;

	set_opening_state_query();

	lock_task(query_lock);
	query = rc.query;
	if ( get_type(query) != XLT_PAIR ) {
		ret = query;
		goto end;
	}
	cmd = car(query);
	if ( get_type(cmd) != XLT_SYMBOL ) {
		ret = query;
		goto end;
	}
	if ( l_strcmp(cmd->symbol.data,l_string(std_cm,"OR")) ) {
		ret = query;
		goto end;
	}
	query = cdr(query);
	new = 0;
	for ( i = 0 ; get_type(query) == XLT_PAIR ;
			query = cdr(query) , i ++ ) {
		if ( i == _no )
			continue;
		new = cons(car(query),new);
	}
	if ( list_length(new) == 1 )
		new = car(new);
	else	new = cons(n_get_symbol("OR"),new);
	rc.query = new;
	ret = new;

	_set_q_mode();
	unlock_task(query_lock,"insert_query");

	query_trigger(1);

	reset_q_mode();
	return ret;
end:
	unlock_task(query_lock,"insert_query");
	rc_task_unlock(TM_TRIG);
	return ret;
type_missmatch:
	return get_error(
		s->h.file,
		s->h.line,
		XLE_SEMANTICS_TYPE_MISSMATCH,
		l_string(std_cm,"gv-delete-query"),
		List(n_get_string("type missmatch"),
			-1));
}


XL_SEXP *
gv_is_set_query(XLISP_ENV * env,XL_SEXP * s,XLISP_ENV * a,XL_SYM_FIELD * sf)
{
XL_SEXP * query;
XL_SEXP * cmd;
L_CHAR * action;

	query = gb_quote_trace(env,get_el(s,1),
		get_sf_attribute(sf,l_string(std_cm,"type")));
	if ( get_type(query) == XLT_ERROR )
		return query;
	if ( get_type(query) != XLT_PAIR )
		goto type_missmatch;
	cmd = car(query);
	if ( get_type(cmd) != XLT_SYMBOL )
		goto type_missmatch;

	set_opening_state_query();

	lock_task(query_lock);
	rc.query = query;

	_set_q_mode();
	unlock_task(query_lock,"set_query");
	
	query_trigger(1);

	reset_q_mode();

	return query;
type_missmatch:
	return get_error(
		s->h.file,
		s->h.line,
		XLE_SEMANTICS_TYPE_MISSMATCH,
		l_string(std_cm,"gv-set-query"),
		List(n_get_string("type missmatch"),
			-1));
}

XL_SEXP *
gv_is_get_query(XLISP_ENV * env,XL_SEXP * s)
{
	return rc.query;
}


int
beam_convert(int ses,L_CHAR * burl,RADAR_LUMP * rl,
		GB_RECT * r,REAL1 * min,REAL1 * max)
{
GB_POINT ptr[8];
REAL1 reso[8];
int i;
MAP_HISTORY * mh;
	if ( l_strcmp(burl,rl->lumpcrd_path) == 0 )
		mh = 0;
	else {

		mh = resolve_mappath(ses,burl,rl->lumpcrd_path,RR_WM_INDIRECT);
		if ( mh == MP_MH_NO_ROUTE )
			return -1;
		for ( i = 0 ; i < 8 ; i += 2 ) {
			reso[i] = *min;
			reso[i+1] = *max;
		}
		ptr[0] = r->tl;
		ptr[2].x = r->tl.x;
		ptr[2].y = r->br.y;
		ptr[4] = r->br;
		ptr[6].x = r->br.x;
		ptr[6].y = r->tl.y;

		ptr[1] = p_avg(ptr[0],ptr[2]);
		ptr[3] = p_avg(ptr[2],ptr[4]);
		ptr[5] = p_avg(ptr[4],ptr[6]);
		ptr[7] = p_avg(ptr[6],ptr[0]);


		map_from_flame(mh,ptr,reso,8);

		r->tl.x = r->tl.y = 0;
		r->br.x = r->br.y = -1;
		*min = *max = 0;
		for ( i = 0 ; i < 8 ; i ++ ) {
			insert_rect(r,ptr[i]);
			if ( *min == 0 || *min > reso[i] )
				*min = reso[i];
			if ( *max == 0 || *max < reso[i] )
				*max = reso[i];
		}
	}
	return 0;
}

void
beam_task(TKEY d)
{
RADAR_LUMP * rl, * rl2, * rl3;
XL_SEXP * ret,* result;
XL_SEXP * qq, * qqq;
URL u;
URL target;
GB_RECT conv_r;
REAL1 conv_min,conv_max;
GB_RECT _conv_r;
REAL1 _conv_min,_conv_max;
L_CHAR * base_url;
XL_SEXP * q;
int ses;
XL_INTERPRETER * xli;
SYS_QUEUE * que;
L_CHAR * key;

T_LOAD_TO_BEAM * n;

	que = (SYS_QUEUE *)GET_TKEY(d);
	key = touch_qkey(que);
	if ( key == 0 )
		return;

	xli = new_xl_interpreter();
	xli->a_type = XLA_SELF;
	setup_i(xli);

	ses = open_session(SEST_OPTIMIZE);

	for ( ; ; ) {
		gc_push(0,0,"beam");

		n = delete_queue(que,sq_key_cond,key,0);
		if ( n == 0 ) {
			gc_pop(0,0);
			break;
		}

		rl = n->rl;
change_rl_memtype(rl,1650);
		q = n->query;
		_conv_min = n->min;
		_conv_max = n->max;
		_conv_r = n->r;
		base_url = n->base_url;

		get_url2(&target,rl->lumpcrd_path,1561);
		if ( target.resource )
			d_f_ree(target.resource);
		target.resource = ll_copy_str(rl->db_path,1524);
		qqq = 0;
		for ( rl2 = rl ; rl2 ; ) {
			get_url2(&u,rl2->lumpcrd_path,1562);
			conv_min = _conv_min;
			conv_max = _conv_max;
			conv_r = _conv_r;
			if ( beam_convert(ses,base_url,rl2,
					&conv_r,&conv_min,&conv_max) < 0 )
				goto del;
			if ( cross_rect_rect(&rl2->sphere,&conv_r) == 0 )
				goto del;
			if ( rl2->reso_min > conv_max ||
					rl2->reso_max < conv_min )
				goto del;
			if ( rl2->db_path == 0 )
				goto del;
			if ( u.resource )
				d_f_ree(u.resource);

			u.resource = ll_copy_str(rl2->db_path,1525);
			qq = List(n_get_symbol("pmd-query"),
				get_string(rl2->db_path),
				List(n_get_symbol("quote"),
					List(	List(	
						get_floating(conv_r.tl.x,
							l_string(std_cm,"m")),
						get_floating(conv_r.tl.y,
							l_string(std_cm,"m")),
						-1),
						List(	
						get_floating(conv_r.br.x,
							l_string(std_cm,"m")),
						get_floating(conv_r.br.y,
							l_string(std_cm,"m")),
						-1),
						-1),
					-1),
				get_floating(conv_min,
					l_string(std_cm,"dot/m")),
				get_floating(conv_max,
					l_string(std_cm,"dot/m")),
				n_get_symbol("qr"),
				-1);
			qqq = cons(qq,qqq);

		del:
			free_url(&u);
			rl3 = rl2->next;
			_free_radar_lump(rl2);
			rl2 = rl3;
		}
		qqq = cons(n_get_symbol("List"),qqq);
		qqq = List(n_get_symbol("Sequence"),
			0,
			List(n_get_symbol("Define"),
				n_get_symbol("qr"),
				List(n_get_symbol("quote"),q,-1),
				-1),
			qqq,
			-1);
/*
fflush(stdout);
ss_printf("beam 6 %ls ",target.server);
print_sexp(s_stdout,qqq,0);
ss_printf("\n");
*/
		ret = remote_session(
			gblisp_top_env0,
			ses,
			&target,
			l_string(std_cm,"gbpmd.get"),
			l_string(std_cm,"user"),
			l_string(std_cm,"Get"),
			List(qqq,-1),
			0,0,0);

		if ( get_type(ret) == XLT_ERROR ) {
			printf("access to lump ");
			fflush(stdout);
			print_sexp(s_stdout,ret,0);
			printf("\n");
			result = ret;
		}
		else {
			result = 0;
			for ( ; get_type(ret) == XLT_PAIR ; ret = cdr(ret) )
				result = append(car(ret),result);
		}

		if ( result )
			insert_beam_to_resource(result);		

		gc_pop(0,0);
		free_url(&target);

		n->rl = 0;
		free_load_to_beam(n);
	}

	release_qkey(que,key);
	d_f_ree(key);

	close_session(ses);
	close_self_interpreter();

}


void
beam_to_remote(int ses,GB_RECT * r,REAL1 min,REAL1 max,XL_SEXP * q)
{
RADAR_LUMP * rl, * rl2, ** rlp, * rl3;
XL_SEXP * ret,* result;
XL_SEXP * qq, * qqq;
URL u;
URL target;
GB_RECT conv_r;
REAL1 conv_min,conv_max;
L_CHAR * base_url;
int id;

T_LOAD_TO_BEAM * n;



	_rlock_base_url("base_to_remote");

	rl = _copy_radar_lump(rc.lump);
	base_url = ll_copy_str(rc.base_url,1527);

	_unlock_base_url();

	result = 0;
	gc_push(0,0,"beam_to_remote");


	for ( ; rl ; ) {
		get_url2(&target,rl->lumpcrd_path,1563);
		rl2 = 0;
		for ( rlp = &rl ; *rlp ; ) {
			rl3 = *rlp;
			get_url2(&u,rl3->lumpcrd_path,1564);
			if ( l_strcmp(target.server,u.server) == 0 &&
					target.port == u.port ) {
				*rlp = rl3->next;
				rl3->next = rl2;
				rl2 = rl3;
			}
			else {
				rlp = &rl3->next;
			}
			free_url(&u);
		}
		n = new_queue_node(sizeof(*n),236);
		n->h.key = ll_copy_str(target.server,125);
		n->query = q;
		n->r = *r;
		n->min = min;
		n->max = max;
		n->base_url = ll_copy_str(base_url,125);
		n->rl = rl2;

		insert_queue(&rc.load_to_beam,n,0);
		free_url(&target);
	}
	d_f_ree(base_url);
}


int
insert_check(SYS_QUEUE * q,T_RESOURCE_TO_INSERT * n,L_CHAR * obj_url)
{
	if ( l_strcmp(n->obj_path,obj_url) == 0 )
		return 0;
	return -1;
}

void
beam_load(XL_SEXP * lst)
{
LOAD_RESOURCE_WORK * w;
XL_SEXP * p, * urls, * u, * v, * ret, * q, * r, * s ,* t;
URL url;
int f;
T_RESOURCE_TO_INSERT * n;
L_CHAR * bu;

	ret = 0;
	for ( urls = lst ; get_type(urls) == XLT_PAIR ;
				urls = cdr(urls) ) {
		p = car(urls);
		if ( get_type(p) != XLT_PAIR )
			continue;
		if ( list_length(p) != 2 )
			continue;
		u = get_el(p,0);
		if ( get_type(u) != XLT_STRING )
			continue;
		v = get_el(p,1);
		if ( get_type(v) != XLT_STRING )
			continue;
		f = 0;
		for ( q = cdr(urls) ; get_type(q) ; q = cdr(q) ) {
			r = car(q);
			if ( get_type(r) != XLT_PAIR )
				continue;
			if ( list_length(r) != 2 )
				continue;
			s = get_el(r,0);
			if ( get_type(s) != XLT_STRING )
				continue;
			t = get_el(r,1);
			if ( get_type(t) != XLT_STRING )
				continue;
			if ( l_strcmp(u->string.data,s->string.data) )
				continue;
			if ( l_strcmp(v->string.data,t->string.data) )
				continue;
			f = 1;
			break;
		}
		if ( f == 1 )
			continue;
		ret = cons(p,ret);
	}
	lst = ret;
	w = 0;

	rlock_base_url("beam_load");
	if ( rc.base_url )
		bu = ll_copy_str(rc.base_url,346);
	else	bu = 0;
	unlock_base_url();

	for ( urls = lst ; get_type(urls) == XLT_PAIR ;
				urls = cdr(urls) ) {

		p = car(urls);
		u = get_el(p,0);
		v = get_el(p,1);

		if ( check_queue(
				&rc.resource_to_insert,
				insert_check,
				v->string.data) > 0 ) {
			continue;
		}

		n = new_queue_node(sizeof(*n),125);
		n->h.key = 0;
		n->mappath_loading = 0;

		n->lr_crd = w = new_lrw(w);
		get_url2(&w->url,u->string.data,1556);
		if ( l_strcmp(v->string.data,u->string.data) ) {
			n->lr_obj = w = new_lrw(w);
			get_url2(&w->url,v->string.data,1556);
		}
		else	n->lr_obj = 0;

		n->crd_path = ll_copy_str(u->string.data,125);
		n->obj_path = ll_copy_str(v->string.data,236);


		if ( bu )
			resolve_route(bu,n->crd_path,RR_WM_NO_WAIT);

		insert_queue(&rc.resource_to_insert,n,0);
	}
	if ( bu )
		d_f_ree(bu);
	load_resource_list(w,Q_PRI_RADAR,0);
	dispose_lrw(w,LRWE_COMPLETE);
}

void
beam_load_resource_task()
{
XL_INTERPRETER * xli;
T_BEAM_TO_RESOURCE * n;

	xli = new_xl_interpreter();
	xli->a_type = XLA_SELF;
	setup_i(xli);

	for ( ; ; ) {
		gc_push(0,0,"beam_load_resource_task");
		n = delete_queue(&rc.beam_to_resource,0,0,1);
		if ( n == 0 ) {
			gc_pop(0,0);
			break;
		}
		beam_load(n->urls);
		d_f_ree(n);
		gc_pop(0,0);
	}
}

XL_SEXP *
beam_to_lump(int ses,GB_RECT * r,REAL1 min,REAL1 max)
{
XL_SEXP * q;
XL_SEXP * ret;

/*
ss_printf("beam (%f %f)-(%f %f) %f %f\n",
r->tl.x,
r->tl.y,
r->br.x,
r->br.y,
min,max);
if ( rc.base_url )
ss_printf("---- %ls %x\n",rc.base_url,rc.lump);
*/

	if ( rc.query_mode ) {
ss_printf("beam aboat\n");
		return get_integer(-1,0);
	}
	q = List(n_get_symbol("quote"),rc.query,-1);
	q = eval(gblisp_top_env0,q);
	q = radar_query_regulation(q);

if ( get_type(q) == XLT_ERROR )
{print_sexp(s_stdout,q,0); s_printf(s_stdout,"\n");}

	if ( rc.lump && min != 0 && max != 0 )
		beam_to_remote(ses,r,min,max,q);
	else {
		ret = virtual_lump(r,min,max,q);
		if ( ret )
			insert_beam_to_resource(ret);
	}
	return 0;
}

void
get_center_reso(GB_POINT * p,REAL1 * reso,GB_RECT * r)
{
REAL1 ww,hh;
REAL1 reso_h,reso_w;
	p->x = (r->tl.x + r->br.x)/2;
	p->y = (r->tl.y + r->br.y)/2;
	ww = r->br.x - r->tl.x;
	hh = r->br.y - r->tl.y;
	reso_h = env.win_height/hh;
	reso_w = env.win_width/ww;
	if ( reso_h < reso_w )
		*reso = reso_h;
	else	*reso = reso_w;
}


int
goto_zoom(int ses,L_CHAR * target)
{
URL u;
RESOURCE * c;
REAL1 reso;
GB_POINT p;

	get_url2(&u,target,1565);

	c = load_resource(ses,&u,Q_PRI_RADAR);
set_cpu_msg(107);


	free_url(&u);
	if ( c == 0 )
		return -1;
	get_center_reso(&p,&reso,&c->h.minrect);
	if ( c->h.visible_resolution > reso )
		reso = c->h.visible_resolution*1.1;


	wf_goto_point(target,p,0,reso);

	wlock_base_url("goto_zoom");

	if ( rc.base_url )
		d_f_ree(rc.base_url);

	rc.base_url = ll_copy_str(target,1528);

	unlock_base_url();

	return 0;
}


XL_SEXP *
gv_zoom(XLISP_ENV * env,XL_SEXP * s)
{
XL_SEXP * crd;
L_CHAR * _crd;
XL_SEXP * r;
GB_RECT _r;
XL_SEXP * rot;
REAL1 _rot;
REAL1 reso;
GB_POINT p;
GB_POINT ptr[4];
REAL1 reso_list[4];
int ses;
URL u;
MAP_HISTORY * mh;
MP_ROUTE * mpr;
int i;
RESOURCE * c;

	crd = get_el(s,1);
	if ( get_type(crd) != XLT_STRING )
		goto type_missmatch;
	_crd = crd->string.data;
	c = 0;

	ses = open_session(SEST_OPTIMIZE);

	if ( list_length(s) == 3 ) {

		get_url2(&u,_crd,1565);
	
		c = load_resource(ses,&u,Q_PRI_RADAR);
		free_url(&u);
		if ( c == 0 )
			goto cannot_jmp;

		r = get_el(s,2);
		if ( get_minrect(&c->h.cu,&_r,r) < 0 )
			goto type_missmatch;
		_rot = 0;
	}
	else if ( list_length(s) == 4 ) {

		get_url2(&u,_crd,1565);

		c = load_resource(ses,&u,Q_PRI_RADAR);
		free_url(&u);
		if ( c == 0 )
			goto cannot_jmp;

		r = get_el(s,2);
		if ( get_minrect(&c->h.cu,&_r,r) < 0 )
			goto type_missmatch;

		rot = get_el(s,3);
		switch ( get_type(rot) ) {
		case XLT_ERROR :
			return rot;
		case XLT_FLOAT :
			_rot = rot->floating.data;
			break;
		case XLT_INTEGER :
			_rot = rot->integer.data;
			break;
		default :
			goto type_missmatch;
		}
	}
	else {

		_rot = 0;
		get_url2(&u,_crd,1565);
	
		c = load_resource(ses,&u,Q_PRI_RADAR);
set_cpu_msg(108);


		free_url(&u);
		if ( c == 0 )
			goto cannot_jmp;
		_r = c->h.minrect;
	}

	rlock_base_url("gv_zoom");

	if ( rc.base_url == 0 )
		goto individual;
	if ( l_strcmp(_crd,rc.base_url) == 0 ) {
		get_center_reso(&p,&reso,&_r);
		if ( c && c->h.visible_resolution > reso )
			reso = c->h.visible_resolution*1.1;
		if ( rc.win_reso_max == 0 )
			rc.win_reso_max = reso;
		wf_goto_point(_crd,p,_rot,reso);
		wakeup_task((int)win_manage_task);

		unlock_base_url();

		close_session(ses);

		return 0;
	}

	ptr[0] = _r.tl;
	ptr[1] = _r.br;
	ptr[2].x = _r.tl.x;
	ptr[2].y = _r.br.y;
	ptr[3].x = _r.br.x;
	ptr[3].y = _r.tl.y;
	for ( i = 0 ; i < 4 ; i ++ )
		reso_list[i] = 1;

	{
	L_CHAR * tmp;
		tmp = ll_copy_str(rc.base_url,128);
		mpr = resolve_route(_crd,tmp,RR_WM_INDIRECT);
		d_f_ree(tmp);
	}

	if ( mpr == 0 || mpr == MP_NO_ROUTE )
		goto individual;
	get_url2(&u,_crd,1566);
	mh = get_mh_from_route(ses,&u,mpr);

	free_url(&u);
	if ( mh == 0 )
		goto individual;
	map_from_flame(mh,ptr,reso_list,4);
	close_session(ses);

	_r.tl.x = _r.tl.y = 0;
	_r.br.x = _r.br.y = -1;
	for ( i = 0 ; i < 4 ; i ++ )
		insert_rect(&_r,ptr[i]);
	get_center_reso(&p,&reso,&_r);
	if ( c && c->h.visible_resolution > reso )
		reso = c->h.visible_resolution*1.1;
	if ( rc.win_reso_max == 0 )
		rc.win_reso_max = reso;

	wf_goto_point(rc.base_url,p,_rot,reso);
	wakeup_task((int)win_manage_task);

	unlock_base_url();

	return 0;

individual:

	close_session(ses);
	lock_task(radar_lock);
	if ( rc.base_url )
		d_f_ree(rc.base_url);
	_free_radar_matrix(rc.matrix);
ss_printf("INDIVI\n");
	rc.matrix = 0;
	rc.base_url = ll_copy_str(_crd,1529);
	get_center_reso(&p,&reso,&_r);
	if ( c && c->h.visible_resolution > reso )
		reso = c->h.visible_resolution*1.1;
	if ( rc.win_reso_max == 0 )
		rc.win_reso_max = reso;
	wf_goto_point(_crd,p,_rot,reso);

	unlock_task(radar_lock,"zoom");

	set_q_mode();

	query_trigger2();
	wakeup_task((int)win_manage_task);

	reset_q_mode();

	unlock_base_url();
	close_session(ses);
	return 0;
type_missmatch:
	close_session(ses);
	return get_error(
		s->h.file,
		s->h.line,
		XLE_SEMANTICS_TYPE_MISSMATCH,
		l_string(std_cm,"gv-zoom"),
		List(n_get_string("type missmatch"),
			-1));
cannot_jmp:
	close_session(ses);
	return get_error(
		s->h.file,
		s->h.line,
		XLE_PROTO_INV_PARAM,
		l_string(std_cm,"gv-zoom"),
		List(n_get_string("cannot jmp"),
			-1));
}

REAL1
get_win_rect(GB_RECT * rp)
{
SURP_SET surp;
REAL1 ret_reso;
int i;
GB_RECT ret;


	lock_task(env.wf_lock);
	ret.tl.x = ret.tl.y = 0;
	ret.br.x = env.win_width;
	ret.br.y = env.win_height;
	set_surp(&surp,&ret,env.flame_base_resolution);
	map_from_flame(&env.flame_base_display_map,
			surp.ptr,
			surp.reso,
			SURP_NOS);
	ret = get_surp_rect(&surp,env.flame_base->draw);
	ret_reso = surp.reso[SURP_NOS-1];
	unlock_task(env.wf_lock,"get_win_rect");
	*rp = ret;
	return ret_reso;
}


typedef struct cr_work {
	int		count[CRT_MAX+1];
	char		flags[CRT_MAX+1];
	L_CHAR *	base_url;
	int		loading_cnt;
} CR_WORK;

int
check_routing(SYS_QUEUE * q,T_RESOURCE_TO_INSERT * n,CR_WORK * w)
{
int c;
int ret;


	ret = 0;
	if ( w->base_url == 0 ) {
		ret = -1;
		goto end;
	}
	if ( n->lr_crd->err == LRWE_HANDLING ) {
		ret = -1;
		goto end;
	}
	if ( n->lr_crd->err == LRWE_OK &&
		(n->lr_crd->result->h.flags & RF_COMPLETE) == 0 ) {
		ret = -1;
		goto end;
	}
	set_lrw_err(n->lr_crd,LRWE_COMPLETE);
	if ( n->lr_obj ) {
		if ( n->lr_obj->err == LRWE_HANDLING ) {
			ret = -1;
			goto end;
		}
		if ( n->lr_obj->err == LRWE_OK &&
			(n->lr_obj->result->h.flags & RF_COMPLETE) == 0 ) {
			ret = -1;
			goto end;
		}
		set_lrw_err(n->lr_obj,LRWE_COMPLETE);
	}
end:
	switch ( n->mappath_loading ) {
	case 0:
		c = check_mappath(w->base_url,n->crd_path,0);
		break;
	case 1:
		c = check_mappath(w->base_url,n->crd_path,1);
		n->mappath_loading = 2;
		w->loading_cnt --;
	case 2:
		c = check_mappath(w->base_url,n->crd_path,0);
		if ( c == CRT_LOADING_RES )
			c = CRT_LOADING_RES_RESOLVE;
		else	n->mappath_loading = 0;
		break;
	}
/*
ss_printf("ret %i %i %ls : %x\n",ret,c,n->crd_path,w->flags[c]);
*/
	if ( ret == 0 ) {
		w->count[c] ++;
		if ( w->flags[c] )
			return ret;
		return -1;
	}
	else if ( c != CRT_EXIST ) {
		w->count[c] ++;
		if ( w->flags[c] )
			return ret;
		return -1;
	}
	return -1;
}

void
reset_cr_work(CR_WORK * w)
{
int i;
	for ( i = 0 ; i < CRT_MAX+1 ; i ++ ){
		w->count[i] = 0;
		w->flags[i] = 0;
	}
	rlock_base_url("reset_cr_work");
	if ( w->base_url )
		d_f_ree(w->base_url);
	if ( rc.base_url )
		w->base_url = ll_copy_str(rc.base_url,234);
	else	w->base_url = 0;
	unlock_base_url();
}

L_CHAR * test_path;

void
beam_insert_task()
{
GB_RECT r;
REAL1 reso;
T_RESOURCE_TO_INSERT * n;
XL_INTERPRETER * xli;
int ses;
CR_WORK cr;
int ret;

	cr.base_url = 0;

	xli = new_xl_interpreter();
	xli->a_type = XLA_SELF;
	setup_i(xli);

	ses = open_session(SEST_OPTIMIZE);

	cr.loading_cnt = 0;
	for ( ; ; ) {
		gc_push(0,0,"beam_insert_task");
		reset_cr_work(&cr);
		if ( cr.base_url ) {
			ret = check_queue(&rc.resource_to_insert,
					check_routing,&cr);
			if ( cr.count[CRT_EXIST] ) {
				cr.flags[CRT_EXIST] = 1;
				n = delete_queue(&rc.resource_to_insert,
					check_routing,&cr,0);
				if ( n == 0 )
					goto loading;
				goto ok;
			}
			if ( cr.count[CRT_LOADING_RES] ) {
				if ( cr.loading_cnt > 2 )
					goto loading;
				cr.flags[CRT_LOADING_RES] = 1;
				n = delete_queue(&rc.resource_to_insert,
					check_routing,&cr,0);
				if ( n == 0 )
					goto loading;
				n->mappath_loading = 1;
				cr.loading_cnt ++;
				insert_queue(&rc.resource_to_insert,n,1);
				goto loading;
			}
			if ( cr.count[CRT_NOTHING] ) {
				cr.flags[CRT_NOTHING] = 1;
				n = delete_queue(&rc.resource_to_insert,
					check_routing,&cr,0);
				if ( n == 0 )
					goto loading;
				resolve_route(
					cr.base_url,
					n->crd_path,
					RR_WM_NO_WAIT);
				insert_queue(&rc.resource_to_insert,n,1);
				goto loading;
			}
			if ( cr.count[CRT_ERROR] ) {
				cr.flags[CRT_ERROR] = 1;
				n = delete_queue(&rc.resource_to_insert,
					check_routing,&cr,1);
				goto err;
			}
			goto loading;
		}
		else {
			n = delete_queue(&rc.resource_to_insert,
					0,0,0);
			if ( n == 0 )
				goto loading;
		}
	ok:
/*
printf("insert_task del %i\n",get_tid());
*/
		wlock_base_url("beam_insert_task");

		if ( rc.base_url == 0 ) {
			if ( goto_zoom(ses,n->crd_path) >= 0 ) {
				if ( rc.base_url )
					d_f_ree(rc.base_url);
				rc.base_url = 
					ll_copy_str(n->crd_path,1530);
				reso = get_win_rect(&r);
				lock_task(radar_lock);
				rc.first_max = rc.win_reso_max = reso;
				rc.first_r = rc.win_rect = r;
				wakeup_task((int)&rc.first_max);
				unlock_task(radar_lock,
					"beam_insert_task");
			}
		}
		unlock_base_url();

		rc_task_lock(TM_INS);


		_insert_radar_url(ses,n->crd_path,n->obj_path);

		rc_task_unlock(TM_INS);


		wakeup_win_manage();

		gc_pop(0,0);

		free_resource_to_insert(n);

		lock_task(radar_lock);
		rc.retrieve_flag = 1;
		wakeup_task((int)&rc.retrieve_flag);
		unlock_task(radar_lock,"beam_insert_task");
		continue;
	err:
		gc_pop(0,0);

		free_resource_to_insert(n);
		continue;

	loading:
		gc_pop(0,0);
		sleep_sec(1);
	}
}

int
loading_first(GB_RECT * last_r,REAL1 * last_max,int ses)
{
XL_SEXP * urls;
GB_RECT r;
REAL1 reso;
XL_SEXP * u,* p, * v;

	r.tl.x = r.tl.y = 0;
	r.br.x = r.br.y = -1;
	gc_push(0,0,"loading_first");
	beam_to_lump(ses,&r,0,0);
	gc_pop(0,0);
	rc.first_max = 0;
	if ( rc.query_mode )
		return -1;
	*last_r = rc.first_r;
	*last_max = rc.first_max;
	return 0;
}

int
_loading_lump(
	int ses,
	GB_RECT * r,
	REAL1 min,
	REAL1 max)
{

	gc_push(0,0,"loading_lump");
	beam_to_lump(ses,r,min,max);
	gc_pop(0,0);
	return 0;
}

void
_turning_loaded_reso(RADAR_MATRIX * mx,REAL1 lr)
{
int x,y;
	for ( x = 0 ; x < 2 ; x ++ )
		for ( y = 0 ; y < 2 ; y ++ ) {
			if ( mx->mx[x][y] == 0 )
				continue;
			if ( mx->mx[x][y]->loaded_reso 
					== mx->mx[x][y]->resolution*2 )
				continue;
			if ( mx->mx[x][y]->loaded_reso > lr ) {
				mx->loaded_reso = lr;
				_turning_loaded_reso(mx->mx[x][y],lr);
			}
		}
}

void
turning_loaded_reso(RADAR_MATRIX * mx)
{
RADAR_MATRIX * p, * c;
REAL1 lr;
int x,y;

	for ( p = mx->parent ; p ; p = p->parent ) {
		lr = 0;
		for ( x = 0 ; x < 2 ; x ++ )
			for ( y = 0 ; y < 2 ; y ++ ) {
				if ( p->mx[x][y] == 0 )
					goto next;
				if ( lr < p->mx[x][y]->loaded_reso )
					lr = p->mx[x][y]->loaded_reso;
			}
		if ( lr < p->loaded_reso )
			p->loaded_reso = lr;
	next:	{}
	}
	lr = mx->loaded_reso;
	_turning_loaded_reso(mx,lr);
}

int
_loading_cube(int ses,RADAR_MATRIX * mx,REAL1 min,REAL1 max)
{
RADAR_MATRIX * p;
GB_RECT r;

/*
if ( rc.matrix && check_fnan(rc.matrix->resolution) < 0 )
er_panic("fnan(1)");
*/

	if ( mx->resolution*2 != max )
		er_panic("loading_cube(1)");
	if ( mx->loaded_reso <= min )
		return 0;
	r.tl = mx->rect[0][0].tl;
	r.br = mx->rect[1][1].br;
	if ( mx->parent == 0 )
		goto no_parent;
	for ( p = mx->parent ;
		p &&
		p->loaded_reso == p->resolution*2 ;
		p = p->parent );
	if ( p == 0 )
		goto no_parent;
exist_parent:

	if ( p->loaded_reso <= min ) {
set_cpu_msg(1120);
		if ( _loading_lump(ses,&r,p->resolution*2,mx->loaded_reso)
				< 0 )
			return -1;
set_cpu_msg(1121);
		mx->loaded_reso = p->loaded_reso;
	}
	else {
set_cpu_msg(1122);
		if ( _loading_lump(ses,&r,min,mx->loaded_reso) < 0 )
			return -1;
set_cpu_msg(1123);
		mx->loaded_reso = min;
	}
set_cpu_msg(1124);
	turning_loaded_reso(mx);
set_cpu_msg(1125);
	return 0;
no_parent:

set_cpu_msg(1126);
	_loading_lump(ses,&r,min,mx->loaded_reso);
set_cpu_msg(1127);
	mx->loaded_reso = min;
	turning_loaded_reso(mx);
set_cpu_msg(1128);
	return 0;
}

int
loading_matrix(GB_RECT * last_r,
	REAL1 * last_window,REAL1 * last_max,int ses)
{
GB_RECT r,rr;
REAL1 max,min,reso;
RADAR_MATRIX_LIST * lst, * lst2;
RADAR_MATRIX * mx;
XL_SEXP * urls;
XL_SEXP * u, * v,* p;
int f;
REAL1 window,_max,_min;

/*
if ( rc.matrix && check_fnan(rc.matrix->resolution) < 0 )
er_panic("fnan(1)");
*/


	lock_task(radar_lock);
	if ( rc.matrix == 0 ) {

		if ( loading_first(last_r,last_max,ses) < 0 ) {
			unlock_task(radar_lock,"loading_matrix");
			return -1;
		}

		*last_window = rc.win_reso_window;
		if ( rc.matrix == 0 ) {
			unlock_task(radar_lock,"loading_matrix");
			return 0;
		}
	}
retry_search:


	r = rc.win_rect;
	window = rc.win_reso_window;
	max = rc.win_reso_max;
	lst = _get_radar_matrix(max,&r);


	if ( lst == 0 )
		er_panic("load_matrix(1)");
	min = max/window;
	for ( reso = lst->mx->resolution;
			reso >= min ; reso = reso / 2 );
	_max = lst->mx->resolution*2;
	_min = reso;
/*
if ( check_fnan(_max) < 0 )
er_panic("lm(1)");
if ( check_fnan(_min) < 0 )
er_panic("lm(2)");
*/


	for ( lst2 = lst ; lst2 ; lst2 = lst2->next )
		if ( _loading_cube(ses,lst2->mx,_min,_max) < 0 ) {
			unlock_task(radar_lock,"loading_matrix");
			return -1;
		}


	*last_r = r;
	*last_window = window;
	*last_max = max;

	unlock_task(radar_lock,"loading_matrix");

	return 0;

}


int
min_route_radar_pre_handle()
{
int ret;
RADAR_CRD * c;
L_CHAR * b_url,*c_path;

	c = 0;
	lock_task(radar_lock);
	_rlock_base_url("min_route_radar");
retry:
	if ( c == 0 )
		c = rc.crd[0].next;
	else 	c = c->next;
	if ( c == &rc.crd[0] ) {
		_unlock_base_url();
		unlock_task(radar_lock,"min_route");
		return 0;
	}
	if ( c->lock )
		goto retry;
	if ( c->resolution == 0 ) {
		goto retry;
	}
	if ( c->base_url == 0 )
		goto do_ptr;
	if ( l_strcmp(c->base_url,rc.base_url) == 0 ) {
		goto retry;
	}
do_ptr:

	b_url = ll_copy_str(rc.base_url,236);
	c_path = ll_copy_str(c->crd_path,356);
	
	_unlock_base_url();
	unlock_task(radar_lock,"min_route_radar");

	resolve_route(b_url,c_path,RR_WM_DIRECT);

	d_f_ree(b_url);
	d_f_ree(c_path);
	return 1;
}

int
min_route_radar(int ses)
{
int ret;
RADAR_CRD * c, *cc;
L_CHAR * url;
GB_RECT mr;
int i;
RADAR_NODE ** np1, ** np2, * n;
RADAR_MATRIX * mx;
GB_RECT r;
int f;
RADAR_MATRIX_LIST * lst,* lst2;

	c = 0;
set_cpu_msg(700);
	lock_task(radar_lock);
set_cpu_msg(701);
	_rlock_base_url("min_route_radar");
retry:
set_cpu_msg(702);
	if ( c == 0 )
		c = rc.crd[0].next;
	else 	c = c->next;
retry2:
set_cpu_msg(703);
	if ( c == &rc.crd[0] ) {
		_unlock_base_url();
		unlock_task(radar_lock,"min_route");
set_cpu_msg(704);
		return 0;
	}
set_cpu_msg(705);
	if ( c->lock )
		goto retry;
set_cpu_msg(706);
	if ( c->resolution == 0 ) {
		cc = c->next;
		_delete_node_from_crd(c);
		_free_radar_crd(c);
		c = cc;
		goto retry2;
	}
set_cpu_msg(707);
	c->lock = -1;
	if ( c->base_url == 0 )
		goto do_ptr;
set_cpu_msg(708);
	if ( l_strcmp(c->base_url,rc.base_url) == 0 ) {
		_flush_radar_crd(c);
		goto retry;
	}
do_ptr:

	unlock_task(radar_lock,"min_route");
	ret = set_ptr_list(ses,c);
set_cpu_msg(200);
	lock_task(radar_lock);
set_cpu_msg(201);
	if ( ret < 0 ) {
		cc = c->next;
		_delete_node_from_crd(c);
		_free_radar_crd(c);
		c = cc;
		goto retry2;
	}
set_cpu_msg(202);
	f = 0;
	for ( np1 = &c->list ; *np1 ; ) {
		mx = (*np1)->matrix;
		n = *np1;
		for ( np2 = &mx->list ; *np2 ;
				np2 = &(*np2)->matrix_next )
			if ( *np2 == n )
				break;
		if ( *np2 == 0 )
			er_panic("min_route_radar");
		*np1 = n->crd_next;
		*np2 = n->matrix_next;
		d_f_ree(n);
		f = 1;
		mx->loaded_reso = mx->resolution*2;
	}
set_cpu_msg(203);
	if ( f ) {
		lst = _get_radar_matrix(c->resolution,&c->minrect);
		for ( lst2 = lst ; lst2 ; lst2 = lst2->next )
			_insert_radar_matrix(lst2->mx,c);
		_free_radar_matrix_list(lst);
	}
set_cpu_msg(204);
	_unlock_base_url();
	unlock_task(radar_lock,"min_route_radar");
set_cpu_msg(205);
	flush_radar_crd(c);
set_cpu_msg(206);
	return 1;
}

void
opening_timer()
{
	set_opening_state(OS_RUN);
}

/***/
void
loading_task()
{
XL_INTERPRETER * xli;
int ses;
GB_RECT r,gr;
REAL1 g_reso_max,reso_max;
REAL1 g_reso_window,reso_window;

	set_cpu_thr_type(1); 

	xli = new_xl_interpreter();
	xli->a_type = XLA_SELF;
	setup_i(xli);

	ses = open_session(SEST_OPTIMIZE);

	r.tl.x = r.tl.y = 0;
	r.br.x = r.br.y = -1;
	reso_window = 0;
	reso_max = 0;

set_cpu_msg(1);

	lock_task(radar_lock);
	new_tick(opening_timer,-OPENING_TIMEOUT,0);
	for ( ; opening_state < OS_RUN ; ) {
		_set_opening_state(OS_STANBY);
		sleep_task((int)&opening_state,radar_lock);
		lock_task(radar_lock);
	}
/*
ss_printf("START !!\n");
*/
	for ( ; ; ) {

set_cpu_msg(2);

/*
printf("START Loaindg\n");
*/
		g_reso_max = rc.win_reso_max;
		g_reso_window = rc.win_reso_window;
		gr = rc.win_rect;
		if ( rc.win_force ) {
			rc.win_force = 0;
			goto start;
		}
		if ( g_reso_max == 0 )
			goto sleep;
		if ( g_reso_window != reso_window )
			goto start;
		if ( g_reso_max != reso_max )
			goto start;
		if ( r.tl.x != gr.tl.x )
			goto start;
		if ( r.tl.y != gr.tl.y )
			goto start;
		if ( r.br.x != gr.br.x )
			goto start;
		if ( r.br.y != gr.br.y )
			goto start;
	sleep:
		rc.win_delete_lock = 0;
		wakeup_task((int)win_manage_task);
set_cpu_msg(3);

/*
printf("sleep load task %i %x\n",get_tid(),rc.base_url);
*/
		_rc_task_unlock(TM_LOAD);

/*
if ( rc.matrix && check_fnan(rc.matrix->resolution) < 0 )
er_panic("fnan(1)");
*/

		sleep_task((int)loading_task,radar_lock);
/*
printf("wakeup load task %x\n",rc.base_url);
*/
/*
if ( rc.matrix && check_fnan(rc.matrix->resolution) < 0 )
er_panic("fnan(1)");
*/

set_cpu_msg(4);
		lock_task(radar_lock);
		continue;
	start:
set_cpu_msg(5);

		unlock_task(radar_lock,"loading_task");

	loading_loop:
set_cpu_msg(1110);
/*
if ( rc.matrix && check_fnan(rc.matrix->resolution) < 0 )
er_panic("fnan(1)");
*/

		set_l_mode();
		rc_task_lock(TM_LOAD);
		if ( rc.remake_req )
			goto next;
/*
if ( rc.matrix && check_fnan(rc.matrix->resolution) < 0 )
er_panic("fnan(1)");
*/


		if ( loading_matrix(&r,&reso_window,&reso_max,ses)
				< 0 ) {

			rc_task_unlock(TM_LOAD);
			reset_l_mode();
/*
if ( rc.matrix && check_fnan(rc.matrix->resolution) < 0 )
er_panic("fnan(1)");
*/

			goto loading_loop;
		}
	next:
/*
if ( rc.matrix && check_fnan(rc.matrix->resolution) < 0 )
er_panic("fnan(1)");
*/


		rc_task_unlock(TM_LOAD);
		reset_l_mode();
/*
printf("load_task trigger win_manage\n");
*/
		if ( rc.remake_req )
			sleep_sec(1);

		lock_task(radar_lock);
		rc.win_load = 1;
		rc.win_delete_lock = 0;
		wakeup_task((int)win_manage_task);

	}
}

/***/
void
min_route_task()
{
XL_INTERPRETER * xli;
int ses;
GB_RECT r,gr;
REAL1 g_reso,reso;
int ret;
int min_ret;

	set_cpu_thr_type(2);

/*
printf("min_route task\n");
*/
	xli = new_xl_interpreter();
	xli->a_type = XLA_SELF;
	setup_i(xli);

	ses = open_session(SEST_OPTIMIZE);

	for ( ; ; ) {

		min_ret = 0;
		lock_task(radar_lock);
	remake:
		if ( rc.win_remake || min_ret ) {
			rc.win_remake = 0;

/*
			_rc_task_lock(TM_MIN);
*/
			unlock_task(radar_lock,"min_route_task");
			min_ret = min_route_wf(ses);

printf("min_ret = %i\n",min_ret);

			lock_task(radar_lock);
/*
			_rc_task_unlock(TM_MIN);
*/
		}
		unlock_task(radar_lock,"min_route");

		for ( ; ; ) {
			lock_task(radar_lock);
			if ( rc.win_remake )
				goto remake;
			unlock_task(radar_lock,"min_route");

			min_route_radar_pre_handle();

			rc_task_lock(TM_MIN);
			ret = min_route_radar(ses);
			rc_task_unlock(TM_MIN);
			lock_task(radar_lock);
			if ( rc.win_remake )
				goto remake;
			if ( ret == 0 ) {
				break;
			}
			unlock_task(radar_lock,"min_route");
			sleep_sec(2);

			lock_task(radar_lock);
			if ( min_ret )
				goto remake;
			unlock_task(radar_lock,"min_route");
		}

/*
printf("minroute %i\n",get_tid());
if ( rc.matrix ) {
printf("(%f %f)-(%f %f)\n",
rc.matrix->rect[0][0].tl.x,
rc.matrix->rect[0][0].tl.y,
rc.matrix->rect[1][1].br.x,
rc.matrix->rect[1][1].br.y);
}
*/
set_cpu_msg(11);

		sleep_task((int)min_route_task,radar_lock);
set_cpu_msg(12);
	}
}

/***/
void
wakeup_win_manage()
{
	wakeup_task((int)win_manage_task);
}

/***/
void
win_manage_task()
{
XL_INTERPRETER * xli;
int ses;
GB_RECT r,gr;
REAL1 g_reso,reso;
WF_ID ret,next;
extern int interface_flag;
int rr;

	set_cpu_thr_type(3);

	xli = new_xl_interpreter();
	xli->a_type = XLA_SELF;
	setup_i(xli);

	ses = open_session(SEST_OPTIMIZE);

	r.tl.x = r.tl.y = 0;
	r.br.x = r.br.y = -1;
	reso = -1;

set_cpu_msg(10);
	for ( ; ; ) {
set_cpu_msg(11);

		if ( interface_flag )
			sleep_task((int)&interface_flag,0);
		lock_task(radar_lock);
set_cpu_msg(12);
		if ( wf_get_current() == 0 ) {
			goto sleep;
		}
set_cpu_msg(13);
		if ( rc.win_load ) {
			rc.win_load = 0;
			g_reso = get_win_rect(&gr);
			goto start;
		}
set_cpu_msg(14);
		g_reso = get_win_rect(&gr);
		if ( g_reso != reso )
			goto start;
		if ( r.tl.x != gr.tl.x )
			goto start;
		if ( r.tl.y != gr.tl.y )
			goto start;
		if ( r.br.x != gr.br.x )
			goto start;
		if ( r.br.y != gr.br.y )
			goto start;
	sleep:
set_cpu_msg(15);
/*
		clean_radar_matrix();
*/
/*
printf("sleep win_manage %i\n",get_tid());
*/
set_cpu_msg(16);

		_rc_task_unlock(TM_WMAN);
		sleep_task((int)win_manage_task,radar_lock);
/*
printf("wakeup win_manage\n");
*/
set_cpu_msg(17);
		continue;
	start:
/*
printf("win_manage start!!\n");
*/
set_cpu_msg(18);
		_rc_task_lock(TM_WMAN);
set_cpu_msg(19);
		unlock_task(radar_lock,"win_manage_task");
		r = gr;
		reso = g_reso;
set_cpu_msg(22);
/*
ss_printf("win_manage (%f %f)-(%f %f) %f\n",
r.tl.x,
r.tl.y,
r.br.x,
r.br.y,
reso);
*/
		if ( r.tl.x != r.br.x && r.tl.y != r.br.y )
			ret = win_manage(&next,ses,reso,&r);
		else {
			ret = 0;
			next = 0;
		}

/*
printf("** win_manage %i\n",ret);
*/

set_cpu_msg(23);

		rc_task_unlock(TM_WMAN);

		if ( ret <= 0 ) {
			if ( rc_task_lock_check(TM_REMK) == 0 ) {
				rc_task_lock(TM_REMK);
				rr = remake_cache(ses,RCT_CHANGE,ret,next);

				lock_task(radar_lock);
				_rc_task_unlock(TM_REMK);

				if ( rr ) {
					rc.win_remake = 1;
					wakeup_task((int)min_route_task);
				}
				unlock_task(radar_lock,"remake");
			}
			rc.remake_req = 0;
			wakeup_task((int)loading_task);
set_cpu_msg(24);
			continue;
		}
		else {
			rc.remake_req = 1;

			if ( rc_task_lock_check(TM_REMK) )
				continue;

		}
set_cpu_msg(25);


		rc_task_lock(TM_REMK);
		remake_cache(ses,RCT_DELETE,ret,next);
		rc.remake_req = 0;

set_cpu_msg(26);
		lock_task(radar_lock);
		_rc_task_unlock(TM_REMK);

		rc.win_remake = 1;
		unlock_task(radar_lock,"remake");
		wakeup_task((int)loading_task);
		wakeup_task((int)min_route_task);
set_cpu_msg(27);
	}
}
