/**********************************************************************
 
	Copyright (C) 2003-2004
	Hirohisa MORI <joshua@nichibun.ac.jp>
	Tomoki SEKIYAMA <sekiyama@yahoo.co.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 <stdlib.h>
#include <string.h>

#include "v/VWindow.h"
#include "v/vobj_utils.h"

extern "C" {
#include "xl.h"
#include "memory_debug.h"

XL_SEXP *
vobj_VWindow(XLISP_ENV *env, XL_SEXP *arg, XLISP_ENV *a, XL_SYM_FIELD *sf);

XL_SEXP *
vobj_VWindow(XLISP_ENV *env, XL_SEXP *arg, XLISP_ENV *a, XL_SYM_FIELD *sf)
{
	VObjectStatus sts;
//	VObject::FreeList *free_list;
//	int flags = get_sts_from_sf(env,&sts,0, sf, &free_list);
	int category = 0;
	int flags;

	VWindow * obj;
	XL_SEXP * _ref;
	

	L_CHAR *attr;
	flags = 0;
	sts.attr = 0;
	if ( ( attr = get_sf_attribute(sf, l_string(std_cm, "attr")) ) ) {
		flags |= VSF_ATTR;
		if ( l_strcmp(attr, l_string(std_cm, "floating")) == 0 )
			sts.attr = VWindow::floating;
		else if ( l_strcmp(attr, l_string(std_cm, "modal")) == 0 )
			sts.attr = VWindow::modal;
	}
	if ( ( attr = get_sf_attribute(sf, l_string(std_cm, "resizable")) ) ) {
		flags |= VSF_ATTR;
		if ( atoi(n_string(std_cm,attr)) )
			sts.attr |= VWindow::resizable;
	}
	
	if ( ( attr = get_sf_attribute(sf, l_string(std_cm, "category")) ) ) {
		category = atoi(n_string(std_cm,attr));
	}
	

	_ref = get_refered_object<VWindow>
		(&obj,env,arg,sf,VO_WIND,"VWindow",&sts,flags,(void*)&category);
	if ( get_type(_ref) == XLT_ERROR )
		return _ref;
/*
	VExError err;
	VWindow *obj = VWindow::create(&sts, flags, category, &err);
	if ( err.code != V_ER_NO_ERR )
		return vobj_get_error(err, arg);
*/
	if ( ( attr = get_sf_attribute(sf, l_string(std_cm, "close_event_handler")) ) ) {
		L_CHAR *func, * e;
		XL_SEXP * _e;
		XLISP_ENV * _ee;
		VSysArgTranslator * vsat;
		if ( attr[0] == 'e' && attr[1] == '/' ) {
			get_sf_v(&e,&func,attr);
			if ( e ) {
				_e = eval(env,get_symbol(e));
				if ( get_type(_e) != XLT_ENV )
					_ee = env;
				else	_ee = _e->env.data;
				d_f_ree(e);
			}
			else	_ee = env;
			if ( func == 0 )
				func = nl_copy_str(std_cm,"close_event_handler");
			vsat = (VSysArgTranslator*)d_alloc(sizeof(*vsat));
			memset(vsat,0,sizeof(*vsat));
			vsat->env = _ee;
			vsat->func = func;
			obj->free_on_release(vsat,free_VSysArgTranslator);
			obj->set_window_close_handler(
					vobj_callback_glue, vsat);
		}
		else {
			func = ll_copy_str(attr);
			obj->set_window_close_handler(
				vobj_callback_glue, func);
			obj->free_on_release(func);
		}
	}

//	obj->free_on_release_list(free_list);
//	obj->get_status(&sts, VSF_ID);

	obj->get_status(&sts,VSF_ID);
	XL_SEXP *ret = vobj_eval_child(sts.id, env, arg);
	if ( get_type(ret) == XLT_ERROR )
		return ret;
	if ( get_type(_ref) == XLT_INTEGER )
		return vobj_get_id_list(_ref->integer.data, ret, sf, 0);
	else	return vobj_get_id_list(sts.id, ret, sf,0);
}

void
init_VWindow(XLISP_ENV *env)
{
	set_env(env,l_string(std_cm,"VWindow"),
		get_func_prim((XL_SEXP*(*)())vobj_VWindow,FO_NORMAL,0,1,2));
	
}


} // extern "C"
