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

XL_SEXP * xl_gv_flame_radar_get_query();
XL_SEXP * xl_gv_flame_radar_set_query();
XL_SEXP * xl_gv_flame_radar_insert_query();
XL_SEXP * xl_gv_flame_radar_delete_query();
XL_SEXP * xl_gv_flame_radar_replace_query();
XL_SEXP * xl_gv_flame_radar_warp();

void
init_gv_flame_radar(XLISP_ENV * env)
{
	set_env(env, l_string(std_cm,"gv-flame-radar-get-query"),
			get_func_prim(xl_gv_flame_radar_get_query,FO_APPLICATIVE,0,1,1));
	set_env(env, l_string(std_cm,"gv-flame-radar-set-query"),
			get_func_prim(xl_gv_flame_radar_set_query,FO_APPLICATIVE,0,2,2));
	set_env(env, l_string(std_cm,"gv-flame-radar-insert-query"),
			get_func_prim(xl_gv_flame_radar_insert_query,FO_APPLICATIVE,0,2,2));
	set_env(env, l_string(std_cm,"gv-flame-radar-delete-query"),
			get_func_prim(xl_gv_flame_radar_delete_query,FO_APPLICATIVE,0,2,2));
	set_env(env, l_string(std_cm,"gv-flame-radar-replace-query"),
			get_func_prim(xl_gv_flame_radar_replace_query,FO_APPLICATIVE,0,2,2));

	set_env(env, l_string(std_cm,"gv-flame-radar-warp"),
			get_func_prim(xl_gv_flame_radar_warp,FO_APPLICATIVE,0,7,7));
}

XL_SEXP *
xl_gv_flame_radar_get_query(
		XLISP_ENV * e,
		XL_SEXP * s,
		XLISP_ENV * a,
		XL_SYM_FIELD * sf)
{
GBVIEW_FLAME * gf;
QUERY_THREAD * _ret;
XL_SEXP * ret;
	gf = get_gf_from_sf(sf);
	_ret = rc_get_q_thread((RADAR_CACHE*)gf->radar_ptr);
	ret = q_thread_to_sexp(_ret,QTH_MAXIMUM_INFO);
	free_query_thread(_ret);
	return ret;
}

XL_SEXP *
xl_gv_flame_radar_set_query(
		XLISP_ENV * e,
		XL_SEXP * s,
		XLISP_ENV * a,
		XL_SYM_FIELD * sf)
{
GBVIEW_FLAME * gf;
int _ret;
QUERY_THREAD * qt;
	gf = get_gf_from_sf(sf);
	qt = sexp_to_q_thread(get_el(s,1));
	_ret = rc_set_q_thread((RADAR_CACHE*)gf->radar_ptr, qt);
	free_query_thread(qt);
	return get_integer(_ret,0);
}

XL_SEXP *
xl_gv_flame_radar_insert_query(
		XLISP_ENV * e,
		XL_SEXP * s,
		XLISP_ENV * a,
		XL_SYM_FIELD * sf)
{
GBVIEW_FLAME * gf;
int _ret;
QUERY_THREAD * qt, * q;
XL_SEXP * ret;
	gf = get_gf_from_sf(sf);
	qt = sexp_to_q_thread(get_el(s,1));
	_ret = rc_insert_q_thread((RADAR_CACHE*)gf->radar_ptr,qt);
	ret = cons(get_integer(_ret,0),0);
	for ( q = qt ; q ; q = q->next )
		ret = cons(get_integer(q->id,0),ret);
	free_query_thread(qt);
	return reverse(ret);
}

XL_SEXP *
xl_gv_flame_radar_delete_query(
		XLISP_ENV * e,
		XL_SEXP * s,
		XLISP_ENV * a,
		XL_SYM_FIELD * sf)
{
GBVIEW_FLAME * gf;
XL_SEXP * no;
int _ret;
	gf = get_gf_from_sf(sf);

	no = get_el(s,1);	
	if ( get_type(no) != XLT_INTEGER )
		goto type_mismatch;

	_ret = rc_delete_q_thread((RADAR_CACHE*)gf->radar_ptr,
		no->integer.data);
	return get_integer(_ret,0);
type_mismatch:
	return get_error(
		s->h.file,
		s->h.line,
		XLE_SEMANTICS_TYPE_MISSMATCH,
		l_string(std_cm,"gv-flame-radar-delete-query"),
		List(n_get_string("type missmatch"),
			-1));	
}

XL_SEXP *
xl_gv_flame_radar_replace_query(
		XLISP_ENV * e,
		XL_SEXP * s,
		XLISP_ENV * a,
		XL_SYM_FIELD * sf)
{
GBVIEW_FLAME * gf;
int _ret;
QUERY_THREAD * qt;
	gf = get_gf_from_sf(sf);
	qt = sexp_to_q_thread(get_el(s,1));
	_ret = rc_replace_q_thread((RADAR_CACHE*)gf->radar_ptr,qt);
	free_query_thread(qt);
	return get_integer(_ret,0);
}


void
gv_flame_radar_indicate_event(RADAR_INDICATE * ri, void * fid)
{
int id, i;
XL_SEXP *loading = 0, *ready = 0, *arg, *ret, *cmd;
char buf[20];
XL_INTERPRETER * xli;

	xli = get_my_xli(); 

	if ( xli == 0 ) {
		xli = new_xl_interpreter();
		xli->a_type = XLA_SELF;
		setup_i(xli);
	}

	id = (int)fid;

	gc_push(0,0,"call_gv_flame_event");
	for ( i = CRT_MAX ; i >= 0 ; i-- ) {
		loading = cons(get_integer(ri->d.loading_res[i],0), loading);
		ready   = cons(get_integer(ri->d.ready_res  [i],0), ready);
	} 
	arg = List(n_get_symbol("quote"), List(get_integer(ri->d.beam, 0), loading, ready, -1), -1);
	
	cmd = n_get_symbol("gv-flame-radar-indicate-event");
	sprintf(buf,"%d", id);
	set_attribute(cmd,l_string(std_cm,"flame-id"),l_string(std_cm,buf));

	ret = eval(gblisp_top_env0, List(cmd, arg, -1));

	if ( get_type(ret) == XLT_ERROR ) {
		fflush(stdout);
		s_printf(s_stdout,"RADAR INDICATE EVENT ");
		print_sexp(s_stdout,cmd,0);
		s_printf(s_stdout," error response -> ");
		print_sexp(s_stdout,ret,0);
		s_printf(s_stdout,"\n");
	}
	gc_pop(0,0);	
}

XL_SEXP *
xl_gv_flame_radar_warp(
		XLISP_ENV * e,
		XL_SEXP * s,
		XLISP_ENV * a,
		XL_SYM_FIELD * sf)
{
GBVIEW_FLAME * gf;
XL_SEXP * ret;
XL_SEXP * type_s, * rect_s, * center_s, * reso_s, * rot_s, * target_s;
int       type;
GB_RECT	  rect;
GB_POINT  center;
REAL1     resolution;
REAL1     rotate;
L_CHAR *  target;
	
	type_s = get_el(s,1);
	rect_s = get_el(s,2);
	center_s = get_el(s,3);
	reso_s = get_el(s,4);
	rot_s = get_el(s,5);
	target_s = get_el(s,6);	
	if ( get_type(type_s) != XLT_INTEGER || get_type(reso_s) != XLT_FLOAT ||
		 get_type(rot_s) != XLT_FLOAT || get_type(target_s) != XLT_STRING )
		goto type_mismatch;
	
	type = type_s->integer.data;
	resolution = reso_s->floating.data;
	rotate = rot_s->floating.data;
	target = target_s->string.data;
	
	if ( get_type(rect_s) ) {
		if ( xl_to_gb_rect(&rect, rect_s) )
			goto type_mismatch;
	}
	else
		rect_s = 0;

	if ( get_type(center_s) ) {
		if ( xl_to_gb_point(&center, center_s) )
			goto type_mismatch;
	}
	else
		center_s = 0;
		
	gf = get_gf_from_sf(sf);
	ret = get_integer(rc_warp(
		(RADAR_CACHE*)gf->radar_ptr,
		type, rect_s?&rect:0, center_s?&center:0, resolution, rotate, target), 0);
	return ret;

type_mismatch:
	return get_error(
		s->h.file,
		s->h.line,
		XLE_SEMANTICS_TYPE_MISSMATCH,
		l_string(std_cm,"gv-flame-radar-warp"),
		List(n_get_string("type missmatch"),
			-1));	
}
