/**********************************************************************
 
	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 ___ROUTING_H___
#define ___ROUTING_H___

#include	"queue.h"

#define MP_ROUTE_CACHE_SIZE	1000
#define ERR_ROUTE_TIMEOUT	120

typedef struct mp_path {
	struct mp_path *	next;
	L_CHAR *		url;
} MP_PATH;


typedef struct mp_route {
	struct mp_route *	next;
	struct mp_route *	prev;
	short			sts;
#define RS_LOADING		0
#define RS_OK			1
#define RS_ERR			2
#define RS_COPY			3
	short			flags;
#define RF_DIRTY	0x0001
	int			lock;
	int			lwait;
	MP_PATH * 		head;
	MP_PATH *		tail;
	unsigned int		modify;
	unsigned int		update;
} MP_ROUTE;


typedef struct mp_cache {
	MP_ROUTE *		cache;
	MP_ROUTE *		root;
	MP_ROUTE *		free_list;
} MP_CACHE;

typedef struct mp_err_route {
	struct mp_err_route *	next;
	unsigned int		err_time;
	L_CHAR *		head;
	L_CHAR * 		tail;
} MP_ERR_ROUTE;

typedef struct mp_route_t {
	Q_HEADER		h;
	L_CHAR *		start;
	L_CHAR *		target;
	int			flags;
#define RQT_LOCK_MASK		0x00000001
#define RQT_RESULT_MASK		0x00000010

#define RQT_UNLOCK		0x00000000
#define RQT_LOCK		0x00000001

#define RQT_ROUTE		0x00000000
#define RQT_MAPHISTORY		0x00000010

#define RQT_ROUTE_RES_MASK	0x00000f00
#define RQT_MH_RES_MASK		0x0000f000
#define RQT_ROUTE_OK		0x00000100
#define RQT_ROUTE_ERR		0x00000200
#define RQT_MH_OK		0x00001000
#define RQT_MH_ERR		0x00002000

#define RQT_ROUTE_REVERSE	0x00010000
	int			wait_mode;
	MP_ROUTE *		route;
	MAP_HISTORY *		mh;

	/* work erea */

	XL_SEXP *		get;

	L_CHAR * 		handle1_start;
	L_CHAR * 		handle1_target;

	L_CHAR * 		handle2_start;
	L_CHAR * 		handle2_target;

	struct mp_route_t *	next;
} MP_ROUTE_T;

#define MP_NO_ROUTE	((MP_ROUTE*)-1)
#define MP_MH_NO_ROUTE	((MAP_HISTORY*)-1)

MP_ROUTE * resolve_route(L_CHAR * start,L_CHAR * target,int wait_flag);
#define RR_WM_NO_WAIT		0
#define RR_WM_DIRECT		3
#define RR_WM_DIRECT_NO_WAIT	4
#define RR_WM_INDIRECT		5
#define RR_WM_INDIRECT_NO_WAIT	6

#define RI_DIRECT	0
#define RI_INDIRECT	1
#define RI_LOADING	2
#define RI_UNRESOLVE	3
#define RI_ERR		4

void flush_route(MP_ROUTE * r);
MAP_HISTORY * get_mh_from_route(int ses,URL * u,MP_ROUTE * mpr);

int check_routing_table(L_CHAR * start,L_CHAR * target);
int
check_mappath(L_CHAR * org,L_CHAR * target,int);

#define CRT_NOTHING		0
#define CRT_LOADING		1
#define CRT_LOADING_RES		2
#define CRT_EXIST		3
#define CRT_ERROR		5
#define CRT_MAX			6

#endif

