/**********************************************************************
 
	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	<math.h>
#include	"xl.h"
#include	"task.h"
#include	"lock_level.h"
#include	"win_flame.h"

#define BW_LOAD_MAX	100


void load_structure_tick();
void load_structure_task();

void
init_load_structure()
{
	new_tick(load_structure_tick,1,0);
}

void
xx_lock_ls_lock(GBVIEW_FLAME * gf,char * file,int line)
{
	ch_lock(&gf->_ls_lock,file,line);
}
#define lock_ls_lock(gf)	xx_lock_ls_lock(gf,__FILE__,__LINE__)


void
unlock_ls_lock(GBVIEW_FLAME * gf)
{
	ch_unlock(&gf->_ls_lock);
}

void
sleep_ls_lock(GBVIEW_FLAME * gf,int key)
{
	ch_sleep_task(key,&gf->_ls_lock);
}

void
assert_ls(GBVIEW_FLAME * gf,int flags)
{
	lock_ls_lock(gf);
	gf->ls_flags |= flags;
	wakeup_task((int)&gf->ls_flags);
	unlock_ls_lock(gf);
}

int
check_assert(GBVIEW_FLAME * gf,int flags)
{
int ret;
	lock_ls_lock(gf);
	ret = gf->ls_flags & flags;
	unlock_ls_lock(gf);
	return ret;
}

int
_assert_ls(GBVIEW_FLAME * gf,int * flags_p)
{
	assert_ls(gf,*flags_p);
	return 0;
}

void
assert_ls_all(int flags)
{
	wf_apply_all_gf(_assert_ls,&flags,GVFS_ACTIVE,0);
}


int
_load_structure_tick(GBVIEW_FLAME * gf)
{
	if ( gf->ls_task_cnt == 0 ) {
printf("TICK_CREATE\n");
		create_task(load_structure_task,(int)gf,0);
	}
	return 0;
}

void
load_structure_tick()
{
	wf_apply_all_gf(_load_structure_tick,0,GVFS_ACTIVE,1);
}

void
load_structure_task(TKEY d)
{
BROWSE_WORK bw;
RESOURCE * c;
WIN_FLAME * wf;
GB_POINT pp;
REAL1 reso;
REAL1 n_reso,p_reso;
int retry;
int b_ret,bb_ret;
int ses;
XL_INTERPRETER * xli;
int no;
RESOURCE * draw;
WF_ID wfid;
GB_RECT win_r;
GBVIEW_FLAME * gf;

/*
printf("load structure %i\n",get_tid());
*/
	gf = (GBVIEW_FLAME *)GET_TKEY(d);

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

	ses = open_session(SEST_OPTIMIZE);

	for ( ; ; ) {
		lock_ls_lock(gf);
		if ( (gf->ls_flags & LSF_ASSERT) || bb_ret ) {
			gf->ls_flags &= ~LSF_ASSERT;
			wakeup_task((int)&gf->ls_flags);
			unlock_ls_lock(gf);
		}
		else {
/*
printf("ls sleep %i\n",get_tid());
*/
			if  ( gf->ls_task_cnt > 2 ) {
				unlock_ls_lock(gf);
				return;
			}
			gf->ls_task_cnt ++;
			sleep_ls_lock(gf,(int)&gf->ls_flags);
/*
printf("ls wakeup %i\n",get_tid());
*/
			lock_ls_lock(gf);
			gf->ls_task_cnt --;
			gf->ls_flags &= ~LSF_ASSERT;
			unlock_ls_lock(gf);

		}

		bb_ret = 0;

		for ( wfid = get_next_wfid(gf,0) ; wfid ; 
				wfid = get_next_wfid(gf,wfid)  ) {
			wf_lock(gf);
			ZONBIE_CHECK_BREAK(gf,wf_unlock)
			wf = _get_wf_ptr(gf,wfid);
			if ( wf == 0 ) {
				wf_unlock(gf);
				continue;
			}
			if ( wf->browse ) {
				wf_unlock(gf);
				continue;
			}
			if ( _win_lock(gf,wf) < 0 ) {
				wf_unlock(gf);
				continue;
			}
			wf->browse = 1;
			wf_unlock(gf);
			bw.type = BWT_CHILDREN;
			bw.mh = 0;
			bw.base = wfid;
			bw.ses = ses;
			bw.load_max = BW_LOAD_MAX;

			win_r.tl.x = win_r.tl.y = 0;
			win_r.br.x = gf->win_width;
			win_r.br.y = gf->win_height;

			wf_lock(gf);
			ZONBIE_CHECK_BREAK(gf,wf_unlock)

			set_surp(&bw.surp,&win_r,gf->flame_base_resolution);
			map_from_flame(
				&gf->flame_base_display_map,
				bw.surp.ptr,
				bw.surp.reso,
				SURP_NOS);
			if ( wf->mh ) {
				map_from_flame(wf->mh,bw.surp.ptr,bw.surp.reso,
						SURP_NOS);
			}
			draw = wf->draw;

			_win_unlock(gf,wf);
			wf_unlock(gf);



			browse_resource(draw,&bw);


			wf_check_resource(gf);

			if ( bw.load_max != BW_LOAD_MAX )
				win_flame_dirty(gf,wfid,0,WFF_DIRTY,0);

			if ( bw.load_max == 0 )
				bb_ret = 1;

			wf_lock(gf);
			ZONBIE_CHECK_BREAK(gf,wf_unlock)
			if ( _get_wf_ptr(gf,wfid) == wf ) {
				_win_lock(gf,wf);
				wf->browse = 0;

				_win_unlock(gf,wf);
			}
			wf_unlock(gf);
		}
		wf_wakeup(gf);
	}

	close_session(ses);
	close_self_interpreter();
}
