/**********************************************************************
 
	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	<fcntl.h>
#include	"memory_routine.h"
#include	"memory_debug.h"
#include	"xlerror.h"
#include	"xl.h"
#include	"gbgraph.h"
#include	"r64.h"
#include	"search.h"

XL_SEXP * pdbp_Get();
void gc_text();

XL_SEXP * search_pdbp();
XL_SEXP * search_pdbp_t();

void
init_pdbp_Get(XLISP_ENV * env)
{
	set_env(env,l_string(std_cm,"Get"),
		get_func_prim(pdbp_Get,FO_APPLICATIVE,0,4,4));
}


XL_SEXP *
load_pdbp(XLISP_ENV * env,XL_SEXP * s,L_CHAR * file)
{
XL_SEXP * rec;
XL_SEXP * lev;
GB_RECT r;
int fd;
XL_SEXP * ret;

	lev = get_el(s,2);
	if ( get_type(lev) != XLT_INTEGER )
		goto type_missmatch;
	rec = get_el(s,3);
	if ( rect_type(rec) )
		goto type_missmatch;
	get_minrect(0,&r,rec);
	ret = search_pdbp_t(n_string(std_cm,file),
		&r,
		lev->integer.data,
		s->h.file,
		s->h.line);
	return ret;
type_missmatch:
	return get_error(
		s->h.file,
		s->h.line,
		XLE_SEMANTICS_TYPE_MISSMATCH,
		l_string(std_cm,"Get"),
		n_get_string("type missmatch"));
}

XL_SEXP *
pdbp_Get(XLISP_ENV * env,XL_SEXP * s,
	XLISP_ENV * a,XL_SYM_FIELD * sf)
{
XL_SEXP * filename;
XL_SEXP * ret;
int i;
CALL_LOCK_DESCRIPTER lr;
L_CHAR * target[2];
L_CHAR * fn;
L_CHAR * _f;
XL_GETFILE * gf;


	filename = get_el(s,1);
	if ( get_type(filename) != XLT_STRING )
		goto type_missmatch;
	fn = nl_copy_str(std_cm,"Get");
	target[0] = target[1] = 0;
	ret = get_path(target,&gf,filename->string.data,s,fn);
	if ( get_type(ret) == XLT_ERROR )
		goto end;
	d_f_ree(fn);
	if ( l_strcmp(gf->mode,l_string(std_cm,"lod")) )
		return get_error(
			s->h.file,
			s->h.line,
			XLE_PROTO_UNSUPPORT_MODE,
			l_string(std_cm,"Get"),
			n_get_string("unsupport Get mode"));

	for ( i = 0 ; i < 2 ; i ++ ) {
		if ( target[i] == 0 )
			break;

		switch ( gf->flags & XLGFM_LOCK ) {
		case XLGF_FULL_PATH:
			_f = target[i];
			lr = call_lock(target[i],CLT_READ_LOCK);
			if ( cl_error_check(lr) ) {
				ret = get_cl_error(s,"Get");
				goto end;
			}
			break;
		case XLGF_URL_PATH:
			_f = filename->string.data;
			lr = call_lock(
				filename->string.data,CLT_READ_LOCK);
			if ( cl_error_check(lr) ) {
				ret = get_cl_error(s,"Get");
				goto end;
			}
			break;
		default:
			_f = 0;
		}

		ret = load_pdbp(env,s,target[i]);
		call_unlock(lr);

		if ( get_type(ret) != XLT_ERROR )
			i = 2;
		else if ( ret->err.code != XLE_PROTO_OPEN_FILE )
				i = 2;
	}
end:
	if ( target[0] )
		d_f_ree(target[0]);
	if ( target[1] )
		d_f_ree(target[1]);


	return ret;
type_missmatch:


	return get_error(
		s->h.file,
		s->h.line,
		XLE_SEMANTICS_TYPE_MISSMATCH,
		l_string(std_cm,"Get"),
		n_get_string("type missmatch"));
}

