/**********************************************************************
 
	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.

**********************************************************************/



#ifndef ___GBVIEW_H___
#define ___GBVIEW_H___

#include	"task.h"
#include	"v.h"
#include	"resource.h"

#define MODE_GRAB	0
#define MODE_ROTATE	1
#define MODE_NOS	2



typedef struct select_indicate {
	struct select_indicate *	next;
	int		x;
	int		y;
	int		w;
	int		h;
	unsigned long *	pixels;
	REAL1		t;
	REAL1		rev_t;
} SELECT_INDICATE;

typedef struct select_work {
	OBJ *			select_obj;
	MAP_HISTORY *		mh;
	MAP *			map;
	GB_COLOR_INT		color;
	SELECT_INDICATE *	si;
	int			width;
	int			height;
} SELECT_WORK;

typedef struct indicate {
	struct indicate *	next;
	URL			url;
	int			flags;
#define IF_COORDINATE		0x00000001
#define IF_OBJECT		0x00000002
	int			status;
#define IS_COORDINATE		0x00000001
#define IS_OBJECT		0x00000002
	GB_POINT		result;
	RESOURCE *		res_object;
} INDICATE;

typedef struct symbol_indicate {
	struct symbol_indicate * next;
	int			rno;
	int			code;
	int			sub;
	int			flags;
#define SIF_DRAW		0x00000001
#define SIF_NEW			0x00000002
#define SIF_ANCOR		0x00000004
	GB_RECT			rect;
	unsigned int *		data;
	unsigned char *		alpha;
	L_CHAR *		ref;
} SYMBOL_INDICATE;

/* cmd for wf_insert_si */
#define ISI_INSERT		1
#define ISI_INFO		2

typedef struct info_list {
	struct info_list *	next;
	RESOURCE * 		r;
	OBJ *			obj;
	int			code;
	int			flags;
	XL_SEXP *		info;
	void 			(*func)();
	void *			func_work;
} INFO_LIST;


typedef struct gbview_layer_status {
	struct gbview_layer_status *	next;
	WF_ID				id;
	L_CHAR * 			entry_url;
	L_CHAR *			target_url;
} GBVIEW_LAYER_STATUS;

typedef struct gbview_status {
	int		flags;
#define SF_LAYER_NOS	0x00000001
#define SF_WIDTH	0x00000002
#define SF_HEIGHT	0x00000004
#define SF_INDICATE	0x00000008
#define SF_INFOLIST	0x00000010
#define SF_EVENT	0x00000020
#define SF_DISPLAY	0x00000040
#define SF_CURRENT	0x00000080
#define SF_LAYERS	0x00000100
#define SF_STATUS	0x00000200

#define SF_ERROR	0x80000000
#define SF_RESOLUTION	0x40000000
#define SF_UNIT		0x20000000
#define SF_MAP_TYPE	0x10000000
#define SF_PP_RADIUS	0x08000000
#define SF_REFERENCE	0x04000000
#define SF_RADAR	0x02000000

#define SF_BASE		0x000003ff
#define SF_ALL		0xfc0003ff

	int		status;
	int		layer_nos;
	int		width;
	int		height;
	REAL1		flame_base_resolution;
	L_CHAR *	flame_base_unit;
	int		flame_base_display_map_type;
	INDICATE *	indicate;
	INFO_LIST *	infolist;
	void		(*event)();
	WF_ID		current;

	GBVIEW_LAYER_STATUS *	layers;

	/* option */

	REAL1		pp_radius;
	L_CHAR *	reference;

} GBVIEW_STATUS;


typedef struct lock_d {
	char *		file;
	int		line;
	int		tid;
} LOCK_D;

typedef struct gbview_flame {
	int		id;
	int		status;
#define GVFS_IDLE	1
#define GVFS_ACTIVE	2
#define GVFS_ZONBIE	4
#define GVFS_ZONBIE_2	8
#define GVFS_ZONBIE_3	0x10

#define GVFM_LIVE	(GVFS_IDLE|GVFS_ACTIVE)
#define GVFM_ZONBIE	(GVFS_ZONBIE|GVFS_ZONBIE_2|GVFS_ZONBIE_3)

#define ZONBIE_CHECK(gf,func,ret)	\
	if ( (gf)->status & GVFM_ZONBIE ) {	\
		func(gf);			\
		return (ret);			\
	}
#define ZONBIE_CHECK_VOID(gf,func)	\
	if ( (gf)->status & GVFM_ZONBIE ) {	\
		(func);				\
		return;				\
	}
#define ZONBIE_CHECK_BREAK(gf,func)	\
	if ( (gf)->status & GVFM_ZONBIE ) {	\
		(func);				\
		break;				\
	}

	int		seq;

	LOCK_D		_ls_lock;

	LOCK_D		_wf_lock;

	LOCK_D		indicate_lock;

	int		ex_lock;
	int		req_task_nos;
	int		run_req_task_nos;
	struct win_flame *	flame;
	struct win_flame *	flame_base;
	GB_POINT		flame_base_center;
	REAL1			flame_base_rotate;
	REAL1			flame_base_resolution;
	MAP_HISTORY		flame_base_display_map;
	SELECT_INDICATE * si;
	char *		redraw;
#define RP_REDRAW		1
#define RP_DIRTY		2
	unsigned long *	redraw_plane;
	int		redraw_flag;
	VRECT		redraw_r;


	int		ls_flags;
#define LSF_ZOOM	0x00000001
#define LSF_MOVE	0x00000002
#define LSF_CURRENT	0x00000004
#define LSF_BASE_FREE	0x00000008
#define LSF_ASSERT	0x0000000f
	int		ls_task_cnt;


	INDICATE *	indicate;
	INFO_LIST *	infolist;

	int		win_width;
	int		win_height;

	INFO_LIST *	click_op_list;

	void		(*event)();
#define ET_REDRAW	1	/* no additional info */
#define ET_CLICK	2	/* GBVIEW_PLANE * */
#define ET_INFO		3	/* GBVIEW_STATUS */

	void *		radar_ptr;

	char		exit_task_wp;
	char		redraw_wp;

	int		zonbie_timeout;
	struct gbview_flame *	next;
} GBVIEW_FLAME;

typedef struct gbview_header {
	int		type;
	int		seq;
} GBVIEW_HEADER;


typedef struct gbview_redraw {
	GBVIEW_HEADER	h;
#define GPT_REDRAW	1
	VRECT		r;
	unsigned long *	plane;
} GBVIEW_REDRAW;

typedef struct gbview_zoom {
	GBVIEW_HEADER	h;
#define GPT_ZOOM	2
	int *		index_x;
	int *		index_y;
} GBVIEW_ZOOM;


typedef union gbview_plane{
	GBVIEW_HEADER	h;
	GBVIEW_REDRAW	r;
	GBVIEW_ZOOM	z;
} GBVIEW_PLANE;

typedef struct pic_element {
	struct pic_element *	next;
	V_STRING_PIC		p;
	unsigned int * 		data;
	unsigned char *		alpha;
	int			line;
	int			flags;
	L_CHAR *		ref;
} PIC_ELEMENT;

typedef struct pic {
	GB_RECT		rect;
	PIC_ELEMENT *	list;
} PIC;

typedef struct pic_list {
	unsigned int	color;
	int		flags;
#define PLF_CENTER	0x00000001
#define PLF_ANCOR	0x00000002
	L_CHAR * 	ref;
	int		ceil;
	GB_POINT	cursol;
	int		line;
	PIC		pic;
} PIC_LIST;

typedef struct si_gbview {
	char		dm_sched_type;
#define DMST_FIFO	1
#define DMST_SIZE	2
} SI_GBVIEW;

typedef struct wfid_include_resource {
	struct wfid_include_resource *	next;
	WF_ID				id;
	GBVIEW_FLAME * 			gf;
} WFID_INCLUDE_RESOURCE;

typedef struct info_req_queue {
	Q_HEADER		h;
	int			cmd;
#define IRQ_ONLY_FETCH		1
#define IRQ_INDICATE_CARD	2
#define IRQ_INDICATE_ONMAP	3
	int			code;
	RESOURCE *		r;
	GBVIEW_FLAME *		gf;
	WF_ID			wfid;
} INFO_REQ_QUEUE;



#define SIG_DM_SCHED_TYPE	0x00000001

extern XL_SEXP * setup_initial_query;

INDICATE * search_indicate(GBVIEW_FLAME *,URL *);
INDICATE * _search_indicate(GBVIEW_FLAME *,URL *);
INDICATE * _copy_indicate(GBVIEW_FLAME *);
void free_indicate(INDICATE *);

void wakeup_wf(GBVIEW_FLAME * gf,WF_ID wfid);
RESOURCE * wf_get_resource(GBVIEW_FLAME * gf,WF_ID id);
void free_win_flame(GBVIEW_FLAME * gf,WF_ID wfid);
void wakeup_wf(GBVIEW_FLAME * gf,WF_ID wfid);
int
wf_space_check_si(
	GBVIEW_FLAME * 	gf,
	WF_ID		wfid,
	int 		rno,
	int		code,
	int		sub,
	GB_RECT * 	rect,
	int		percent);

WF_ID wf_get_current();
void _calc_pitch(GBVIEW_FLAME *,int);
void calc_pitch(GBVIEW_FLAME *,int);
int cache_image(
	GBVIEW_FLAME * gf,
	WF_ID wf_id,
	RESOURCE * c,
	GB_POINT * pt_list,
	REAL1 * pt_reso,
	unsigned long * buf,
	int size,
	GB_RECT * r,
	MAP_HISTORY *mh,
	SURP_SET * surp,
	int methd,
	int flags);


int wf_redraw(GBVIEW_FLAME * gf,GBVIEW_PLANE * p,int x,int y,int w,int h);
int wf_select(GBVIEW_PLANE * p,OBJ *);
void wf_allredraw(WF_ID);
GBVIEW_FLAME * wf_search(WF_ID * ret_id,RESOURCE *);
int new_win_flame(
	WF_ID*		ret_wf,
	GBVIEW_FLAME *	gf,
	REAL1		v_reso,
	RESOURCE * 	draw,
	MAP_HISTORY * 	mh,
	GB_POINT	center,
	REAL1		rotate,
	REAL1		resolution);
int wf_zoom(GBVIEW_FLAME * ,GBVIEW_PLANE* ,REAL1);
void wf_redraw_buffer(WF_ID wfid,int mode);
int wf_rotate(GBVIEW_FLAME * gf,GB_POINT from,GB_POINT to);



extern char http_hostname[100];
extern int http_port;

int wf_goto_point(
	GBVIEW_FLAME * gf,
	L_CHAR * url,
	GB_POINT ptr,
	REAL1 rotate,
	REAL1 reso);



int read_pixelmap(unsigned char col[3],int,int);
int draw_image(
	VOBJECT * obj,
	int ix,
	int iy,
	int w,
	int h);
int draw_resource(GBVIEW_FLAME *,RESOURCE*,DRAW_WORK *);
int check_resource(RESOURCE*,CHECK_WORK*);
int get_point_resource(GBVIEW_FLAME * ,RESOURCE*,GET_POINT_WORK *);
int get_point_object(GBVIEW_FLAME *,RESOURCE *,OBJ*,GET_POINT_WORK *);
int draw_object(GBVIEW_FLAME * gf,OBJ *,DRAW_WORK *);

DRAW_MATRIX * new_draw_matrix(WF_ID,
	RESOURCE*,DRAW_MATRIX *,int,int);
void digging_matrix(WF_ID,RESOURCE *,GB_RECT * r,int lev);
DRAW_MATRIX * get_dm_of_position(RESOURCE * r,int lod,GB_POINT pt);

void * get_ri(int *,int *,GBVIEW_FLAME * gf,WF_ID,L_CHAR * );

int free_object(RESOURCE*,OBJ*);
void free_object_list(RESOURCE*);
XL_SEXP * get_card_info(RESOURCE * r,XL_SEXP * org);
XL_SEXP * get_onmap_info(RESOURCE * r,XL_SEXP * org,REAL1 * reso);
PIC get_onmap_string_pic(XL_SEXP*);

void
wf_indicate(GBVIEW_FLAME * gf,GBVIEW_STATUS *,int,int,int);
int wf_click(GBVIEW_FLAME * gf,GBVIEW_STATUS * ,GBVIEW_PLANE *,int,int);

int
wf_insert_si(
	GBVIEW_FLAME * gf,
	int	cmd,
	WF_ID wf,
	int rno,
	int	code,
	int	sub,
	GB_RECT * rect,
	unsigned int * data,
	unsigned char * alpha,
	int flags,
	L_CHAR * ref);
WF_ID wf_get(GBVIEW_FLAME * gf,int);
void
indicate_onmap(GBVIEW_FLAME *,int,WF_ID wf,RESOURCE * r,OBJ * o,GB_POINT ind_ptr);
INFO_LIST * copy_infolist();
void free_infolist(INFO_LIST *);
WFID_INCLUDE_RESOURCE * wf_search_wfid_include_resource(RESOURCE * r);
void free_wfid_include_resource(WFID_INCLUDE_RESOURCE * wir);
int min_route_wf(GBVIEW_FLAME * gf,int ses);

void
insert_ic(L_CHAR * url,int type);
#define ICT_OVERWRAP	0
#define ICT_ZOOM	1

int insert_point(
	RESOURCE *,
	OBJ *,
	RING_TYPE *,int,REAL1,REAL1,int,int,GB_POINT*,GB_POINT*,
	unsigned int code);

XL_SEXP * _dgb_p2d_trailer(RESOURCE * r,XL_SEXP * data);

void
wf_insert_dirty_rect(RESOURCE * r,GB_RECT * d_rect,int flags,
		     int ofs_w,int ofs_h);


void * search_ri_org(int *,L_CHAR * path);

unsigned long put_color(unsigned long a,GB_COLOR_INT * col);

int set_si_gbview(char * server,int active_flags,SI_GBVIEW * data);

int
wf_button_action(GBVIEW_FLAME * gf,OBJ * o,char * type);
void wf_status(GBVIEW_FLAME * gf,GBVIEW_STATUS *);
void wf_free_status(GBVIEW_STATUS *);
int wf_set_status(GBVIEW_FLAME * gf,GBVIEW_STATUS *);
void wf_free_plane(GBVIEW_PLANE * p);

int list2gvstatus(XL_SEXP * list, GBVIEW_STATUS *gs);
XL_SEXP * gvstatus2list(GBVIEW_STATUS * gs);

int list2gbp(XL_SEXP * list, GBVIEW_PLANE * gbp);
XL_SEXP * gbp2list(GBVIEW_PLANE * gbp, XL_SYM_FIELD * sf);


void _sleep_at_exit_task_wp(GBVIEW_FLAME*,int);
void _wakeup_at_exit_task_wp(GBVIEW_FLAME*);
void sleep_at_exit_task_wp(GBVIEW_FLAME*);
void wakeup_at_exit_task_wp(GBVIEW_FLAME*);

void _sleep_at_redraw_wp(GBVIEW_FLAME*,int);
void _wakeup_at_redraw_wp(GBVIEW_FLAME*);
void sleep_at_redraw_wp(GBVIEW_FLAME*);
void wakeup_at_redraw_wp(GBVIEW_FLAME*);

void xx_wf_lock(GBVIEW_FLAME * gf,char *,int);
#define wf_lock(gf)	xx_wf_lock(gf,__FILE__,__LINE__)
void wf_unlock(GBVIEW_FLAME * gf);
void wf_sleep_task(GBVIEW_FLAME * gf,int key);
void ch_lock(LOCK_D *,char * file,int line);
void ch_unlock(LOCK_D *);
void ch_sleep_task(int key,LOCK_D * bit);
int _ch_locked(LOCK_D * d);

void assert_ls(GBVIEW_FLAME *,int flags);
void assert_ls_all(int flags);

GBVIEW_FLAME * wf_get_gf_from_id(int);
void wf_apply_all_gf(int (*func)(),void * work,int status,int lock_flag);
void
set_pointer_indicate(GBVIEW_FLAME * gf,int flags,URL * u);

#endif

