/**********************************************************************
 
	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 "v/VScrollView.h"
#include "v/vobj_utils.h"

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

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


XL_SEXP *
vobj_VScrollView(XLISP_ENV *env, XL_SEXP *arg, XLISP_ENV *a, XL_SYM_FIELD *sf)
{
XL_SEXP * _ref;
VObjectStatus _sts;
VScrollView * obj;

	_ref = get_refered_object<VScrollView>
			(&obj,env,arg,sf,VO_RADB,"VScrollView",&_sts,0,0);
	if ( get_type(_ref) == XLT_ERROR )
		return _ref;

	L_CHAR *internal_size = get_sf_attribute(sf, l_string(std_cm, "internal_size"));
	if ( internal_size ) {
		short w, h;
		int n = sscanf(n_string(std_cm,internal_size),"%hd,%hd",&w,&h);
		if ( n == 1 )
			h = w;
		if ( n == 1 || n == 2 ) {
			VSize s = {w,h};
			obj->set_internal_size(s);
		}
		else
			return get_error(
				arg->h.file,
				arg->h.line,
				XLE_PROTO_INV_PARAM,
				l_string(std_cm,"VScrollView"),
				n_get_string("invalid internal_size"));
	}

	L_CHAR * ch = get_sf_attribute(sf,l_string(std_cm,"children"));
	if ( ch && l_strcmp(ch,l_string(std_cm,"clear")) == 0 )
		vobj_delete_children(env,obj);
	
	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);
}

XL_SEXP *
vobj_SetInternalSize(XLISP_ENV *env, XL_SEXP *arg, XLISP_ENV *a, XL_SYM_FIELD *sf)
{
	VObject *obj;
	VScrollView *scv;
	
	XL_SEXP *t = get_el(arg, 1);
	XL_SEXP *w = get_el(arg, 2);
	XL_SEXP *h = get_el(arg, 3);
	if ( get_type(t) != XLT_INTEGER )
		goto type_missmatch;
	if ( get_type(w) != XLT_INTEGER )
		goto type_missmatch;
	if ( get_type(h) != XLT_INTEGER )
		goto type_missmatch;
	
	obj = VObject::get_object_by_id(t->integer.data);
	if ( obj == 0 )
		return vobj_get_error(initial_VExError(V_ER_NOT_FOUND,0,0), arg);
	
	scv = dynamic_cast<VScrollView*>(obj);
	if ( scv == 0 )
		goto object_type_missmatch;
	{
		VSize s = {w->integer.data,h->integer.data};
		scv->set_internal_size(s);
	}
	return 0;

type_missmatch:
	return get_error(
		arg->h.file,
		arg->h.line,
		XLE_SEMANTICS_TYPE_MISSMATCH,
		l_string(std_cm,"SetInternalSize"),
		n_get_string("type missmatch"));
object_type_missmatch:
	return get_error(
		arg->h.file,
		arg->h.line,
		XLE_PROTO_INV_PARAM,
		l_string(std_cm,"SetInternalSize"),
		n_get_string("object type missmatch"));
}


void
init_VScrollView(XLISP_ENV *env)
{
	set_env(env,l_string(std_cm,"VScrollView"),
		get_func_prim((XL_SEXP*(*)())vobj_VScrollView,FO_NORMAL,0,2,2));

	set_env(env,l_string(std_cm,"SetInternalSize"),
		get_func_prim((XL_SEXP*(*)())vobj_SetInternalSize,FO_APPLICATIVE,0,4,4));
}


} // extern "C"
