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

extern int lock_pdb_lock_p;

int point_nos;


XL_SEXP *
dgb_point(XLISP_ENV * e,XL_SEXP * s,
	XLISP_ENV * a,
	XL_SYM_FIELD * sf)
{
L_CHAR * num;
XL_SEXP * point;
XL_SEXP * pp;
RESOURCE * r;
XLISP_ENV * ee;
int _num;
REAL1 p1,p2;
OBJ * o;
int er;
XL_SEXP * ret;
GB_POINT pt;
int lod_min,lod_max;
L_CHAR * lod;
char * buf1,* buf2;
L_CHAR * code;
int _code;

	r = get_resource_ptr(&ret,e,s->h.file,s->h.line);
	if ( r == 0 )
		return ret;
	if ( r->h.type != RT_DRAW_GB )
		er_panic("dgb_point(2)");
	code = get_sf_attribute(sf,l_string(std_cm,"code"));
	if ( code == 0 )
		goto undef_code;
	sscanf(n_string(std_cm,code),"%i",&_code);
	num = get_sf_attribute(sf,l_string(std_cm,"no"));
	if ( num == 0 )
		goto undef_no;
	sscanf(n_string(std_cm,num),"%i",&_num);
	lod = get_sf_attribute(sf,l_string(std_cm,"lod"));
	if ( lod == 0 ) {
		lod_min = lod_max = 0;
	}
	else {
		buf1 = ln_copy_str(std_cm,lod);
		buf2 = buf1;
		for ( ; *buf2 && *buf2 != '-' ; buf2 ++ );
		if ( *buf2 == 0) {
			sscanf(buf1,"%i",&lod_min);
			lod_max = lod_min;
		}
		else {
			*buf2 = 0;
			buf2 ++;
			sscanf(buf1,"%i",&lod_min);
			sscanf(buf2,"%i",&lod_max);
		}
	}
	d_f_ree(buf1);

	if ( list_length(s) == 2 )
		point = get_el(s,1);
	else	point = cdr(s);
	if ( get_type(point) == XLT_ERROR )
		return point;
	if ( list_length(point) != 2 ) {
		goto typemissmatch;
	}
	pp = get_el(point,0);
	switch ( get_type(pp) ) {
	case XLT_ERROR:
		return pp;
	case XLT_INTEGER:
		p1 = conv_unit(
			&er,
			get_uenv(gblisp_top_env0),
			pp->integer.data,
			pp->integer.unit,
			l_string(std_cm,"m"));
		break;
	case XLT_FLOAT:
		p1 = conv_unit(
			&er,
			get_uenv(gblisp_top_env0),
			pp->floating.data,
			pp->floating.unit,
			l_string(std_cm,"m"));
		break;
	default:
		goto typemissmatch;
	}
	pp = get_el(point,1);
	switch ( get_type(pp) ) {
	case XLT_ERROR:
		return pp;
	case XLT_INTEGER:
		p2 = conv_unit(
			&er,
			get_uenv(gblisp_top_env0),
			pp->integer.data,
			pp->integer.unit,
			l_string(std_cm,"m"));
		break;
	case XLT_FLOAT:
		p2 = conv_unit(
			&er,
			get_uenv(gblisp_top_env0),
			pp->floating.data,
			pp->floating.unit,
			l_string(std_cm,"m"));
		break;
	default:
		goto typemissmatch;
	}

	lock_pdb_lock(r,0);

	o = search_obj(r,_code);
	if ( o == 0 ) {
	XL_SEXP * ret;
		ret = get_error(
			s->h.file,
			s->h.line,
			XLE_PROTO_UNDEF_NAME,
			l_string(std_cm,"point"),
			List(n_get_string("no exist code"),
				get_integer(_code,0),
				-1));
		unlock_pdb_lock(r);
		return ret;
	}
	if ( o->h.type != OT_POLYGON2D ) {
	XL_SEXP * ret;
		ret = get_error(
			s->h.file,
			s->h.line,
			XLE_PROTO_INV_OBJECT,
			l_string(std_cm,"point"),
			List(n_get_string("invalid type object code"),
				get_integer(_code,0),
				-1));
		unlock_pdb_lock(r);
		return ret;
	}
	insert_point(r,o,&o->polygon2d.point_list,
		_num,p1,p2,lod_min,lod_max,0,0,
		o->h.code);
	pt.x = p1;
	pt.y = p2;
	insert_rect(&o->h.minrect,pt);
	unlock_pdb_lock(r);
	return 0;
typemissmatch:
	return get_error(
		s->h.file,
		s->h.line,
		XLE_SEMANTICS_TYPE_MISSMATCH,
		l_string(std_cm,"point"),
		List(n_get_string("type missmatch"),
			-1));
undef_code:
	return get_error(
		s->h.file,
		s->h.line,
		XLE_PROTO_UNDEF_NAME,
		l_string(std_cm,"point"),
		List(n_get_string("attribute \"code\" is required"),-1));
undef_no:
	return get_error(
		s->h.file,
		s->h.line,
		XLE_PROTO_UNDEF_NAME,
		l_string(std_cm,"point"),
		List(n_get_string("attribute \"no\" is required"),-1));
}
