/**********************************************************************
 
	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	"gbgraph.h"
#include	"xl.h"
#include	"radar.h"

XL_SEXP * get_url_pair(XL_SEXP *,XL_SEXP *);

XL_SEXP *
get_url_pair_URL(XL_SEXP * result,XL_SEXP * q)
{
XL_SEXP * cmd;
L_CHAR * cond;
XL_SEXP * c;
int len;
	cmd = car(q);
	cond = get_sf_attribute(cmd->symbol.field,l_string(std_cm,"cond"));
	if ( cond == 0 )
		goto next;
	if ( l_strcmp(cond,l_string(std_cm,"full")) == 0 )
		goto next;
	if ( l_strcmp(cond,l_string(std_cm,"crd.full")) == 0 )
		goto next;
	return result;
next:
	c = get_el(q,1);
	if ( get_type(c) != XLT_STRING )
		return result;
	len = l_strlen(c->string.data);
	if ( l_strcmp(&c->string.data[len-4],l_string(std_cm,".crd")) )
		return result;
	return cons(List(c,c,-1),result);
}

XL_SEXP *
get_url_pair_list(XL_SEXP * result,XL_SEXP * q)
{
XL_SEXP * r;
	for ( q = cdr(q) ; get_type(q) == XLT_PAIR ; q = cdr(q) )
		result = get_url_pair(result,car(q));
	return result;
}

XL_SEXP *
get_url_pair_pair(XL_SEXP * result,XL_SEXP * q)
{
XL_SEXP * cmd;
	cmd = car(q);
	if ( get_type(cmd) != XLT_SYMBOL )
		return result;
	if ( l_strcmp(cmd->symbol.data,l_string(std_cm,"URL")) == 0 )
		return get_url_pair_URL(result,q);
	if ( l_strcmp(cmd->symbol.data,l_string(std_cm,"AND")) == 0 )
		return get_url_pair_list(result,q);
	if ( l_strcmp(cmd->symbol.data,l_string(std_cm,"OR")) == 0 )
		return get_url_pair_list(result,q);
	if ( l_strcmp(cmd->symbol.data,l_string(std_cm,"NOT")) == 0 )
		return get_url_pair_list(result,q);
	else {
		return result;
	}
}

XL_SEXP *
get_url_pair(XL_SEXP * result,XL_SEXP * query)
{
	switch ( get_type(query) ) {
	case XLT_INTEGER:
		return result;
	case XLT_PAIR:
		return get_url_pair_pair(result,query);
	default:
		return result;
	}
}

int
check_filter_query(L_CHAR *,L_CHAR *,XL_SEXP * q);

int
check_filter_query_AND(
	L_CHAR * crd,
	L_CHAR * obj,
	XL_SEXP * q)
{
int ret,r;
	q = cdr(q);
	if ( list_length(q) < 2 )
		return -1;
	ret = 1;
	for ( ; get_type(q) == XLT_PAIR ; q = cdr(q) ) {
		r = check_filter_query(crd,obj,car(q));
		switch ( r ) {
		case 2:
			break;
		case 0:
			ret = 0;
			break;
		case -1:
			return -1;
		}
	}
	return ret;
}


int
check_filter_query_OR(
	L_CHAR * crd,
	L_CHAR * obj,
	XL_SEXP * q)
{
int ret,r;
	q = cdr(q);
	if ( list_length(q) < 2 )
		return -1;
	ret = 0;
	for ( ; get_type(q) == XLT_PAIR ; q = cdr(q) ) {
		r = check_filter_query(crd,obj,car(q));
		switch ( r ) {
		case 2:
			break;
		case 1:
			ret = 1;
			break;
		case -1:
			return -1;
		}
	}
	return ret;
}

int
check_filter_query_NOT(
	L_CHAR * crd,
	L_CHAR * obj,
	XL_SEXP * q)
{
int r;
	q = cdr(q);
	if ( list_length(q) != 1 )
		return -1;
	r = check_filter_query(crd,obj,car(q));
	switch ( r ) {
	case 2:
		return 2;
	case 1:
		return 0;
	case 0:
		return 1;
	default:
		return r;
	}
}



int
check_filter_query_URL(
	L_CHAR * crd,
	L_CHAR * obj,
	XL_SEXP * q)
{
XL_SEXP * cmd;
L_CHAR * cond;
XL_SEXP * c;
L_CHAR * _c;
	cmd = car(q);
	if ( list_length(q) != 2 )
		return -1;
	cond = get_sf_attribute(cmd->symbol.field,l_string(std_cm,"cond"));
	c = get_el(q,1);
	if ( get_type(c) != XLT_STRING )
		return -1;
	_c = c->string.data;
	if ( cond == 0 )
		goto full;
	else if ( l_strcmp(cond,l_string(std_cm,"full")) == 0 )
		goto full;
	else if ( l_strcmp(cond,l_string(std_cm,"part")) == 0 )
		return cmp_part(obj,_c);
	else if ( l_strcmp(cond,l_string(std_cm,"crd.full")) == 0 ) {
		if ( l_strcmp(crd,_c) == 0 )
			return 1;
		return 0;
	}
	else if ( l_strcmp(cond,l_string(std_cm,"crd.part")) == 0 )
		return cmp_part(crd,_c);

full:
	if ( l_strcmp(obj,_c) == 0 )
		return 1;
	return 0;
}

int
check_filter_query_qualifier(crd,obj,q)
{
	return 2;
}


int
check_filter_query_pair(
	L_CHAR * crd,
	L_CHAR * obj,
	XL_SEXP * q)
{
XL_SEXP * cmd;
	cmd = car(q);
	if ( get_type(cmd) != XLT_SYMBOL )
		return -1;
	if ( l_strcmp(cmd->symbol.data,l_string(std_cm,"AND")) == 0 )
		return check_filter_query_AND(crd,obj,q);
	if ( l_strcmp(cmd->symbol.data,l_string(std_cm,"OR")) == 0 )
		return check_filter_query_OR(crd,obj,q);
	if ( l_strcmp(cmd->symbol.data,l_string(std_cm,"NOT")) == 0 )
		return check_filter_query_NOT(crd,obj,q);
	if ( l_strcmp(cmd->symbol.data,l_string(std_cm,"qualifier")) == 0 )
		return check_filter_query_qualifier(crd,obj,q);
	if ( l_strcmp(cmd->symbol.data,l_string(std_cm,"URL")) == 0 )
		return check_filter_query_URL(crd,obj,q);
	return -1;
}

int
check_filter_query(
	L_CHAR * crd,
	L_CHAR * obj,
	XL_SEXP * q)
{
	switch ( get_type(q) ) {
	case XLT_INTEGER:
		if ( q->integer.data )
			return 1;
		return 0;
	case XLT_PAIR:
		return check_filter_query_pair(crd,obj,q);
	default:
		return -1;
	}
}

XL_SEXP *
virtual_lump(
	GB_RECT * rect,
	REAL1	reso_min,
	REAL1	reso_max,
	XL_SEXP * query)
{
XL_SEXP * up, * ret, * p, * crd, * obj;

	up = get_url_pair(0,query);
	ret = 0;
	for ( ; get_type(up) == XLT_PAIR ; up = cdr(up) ) {
		p = car(up);
		if ( get_type(p) != XLT_PAIR )
			er_panic("virtual_lump");
		crd = get_el(p,0);
		obj = get_el(p,1);
		if ( get_type(crd) != XLT_STRING )
			er_panic("virtual_lump(2)");
		if ( get_type(obj) != XLT_STRING )
			er_panic("virutal_lump(3)");
		switch ( check_filter_query(
				crd->string.data,
				obj->string.data,
				query) ) {
		case 2:
			ret = cons(p,ret);
			break;
		case 1:
			ret = cons(p,ret);
			break;
		case -1:
			return 0;
		}
	}
	return ret;
}
