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

AVT_NODE *mark_avt=0;

XL_SEXP * xl_mark();


void gc_pdb_mark_tags()
{
	PDB_MARK_TAGS *tag;
	for(tag = pdb_mark_tags; tag; tag = tag->next){
		gc_gb_sexp(tag->info);
		gc_gb_sexp(tag->sexp);
	}
}

int
cmp_mark(PDB_MARK_TAGS * p1, PDB_MARK_TAGS * p2)
{
int ret;
	ret = l_strcmp(p1->name, p2->name);
	if ( ret )
		return ret;
	return l_strcmp(p1->subname, p2->subname);
}

void
insert_mark_avt(PDB_MARK_TAGS * p)
{
AVT_NODE * n;

	n = d_alloc(sizeof(*n));
	n->data = p;
	avt_insert((AVT_NODE**)&mark_avt, n, cmp_mark);
}


void
init_mark(XLISP_ENV * env)
{
	set_env(
			env,
			l_string(std_cm,"mark"),
			get_func_prim(xl_mark, FO_NORMAL, gblisp_top_env0, 2, 3)
			);
}

int path_cnt;


XL_SEXP *
xl_mark(XLISP_ENV * env,XL_SEXP * s,
	XLISP_ENV * a,XL_SYM_FIELD * _sf)
{
PDB_MARK_TAGS *new_mark;
L_CHAR *code;
XL_SEXP *sym;
XL_SYM_FIELD *sf;

	code = 0;
	sym = car(s);
	get_sym_field(&sf, env, sym);
	for(;sf;sf=sf->next){
		if(l_strcmp(sf->name, l_string(std_cm,"code")) == 0){
			code = ll_copy_str(sf->data);
		}
	}
	if(code == 0){
		er_panic("\"code\" attribute not found in mark element. ");
	}

	new_mark = d_alloc(sizeof(PDB_MARK_TAGS));
	memset(new_mark, 0, sizeof(PDB_MARK_TAGS));
	new_mark->sexp = s;
	new_mark->subname = ll_copy_str(l_string(std_cm,"0"));
	new_mark->name = code;
	new_mark->next = pdb_mark_tags;
	pdb_mark_tags = new_mark;
	
	insert_mark_avt(new_mark);
	
	return 0;
}





PDB_MARK_TAGS *
search_mark_avt(L_CHAR * name,L_CHAR * subname)
{
PDB_MARK_TAGS p;
AVT_NODE * a;
	if ( subname == 0 )
		subname = l_string(std_cm,"0");
	p.name = name;
	p.subname = subname;
	a = avt_search(mark_avt, &p, cmp_mark);
	if ( a == 0 )
		return 0;
	return a->data;
}

PDB_MARK_TAGS *
get_mark(XL_SEXP ** retp,XL_SYM_FIELD * sf,XL_FILE * file,int line)
{
L_CHAR * name;
L_CHAR * subname;

	name = 0;
	subname = 0;
	*retp = 0;
	for ( ; sf ; sf = sf->next ) {
		if ( l_strcmp(sf->name,l_string(std_cm,"name")) == 0 )
			name = sf->data;
		else if ( l_strcmp(sf->name,l_string(std_cm,"subname"))
				== 0 )
			subname = sf->name;
	}
	if ( name == 0 )  {
		*retp = get_error(
			file,
			line,
			XLE_PROTO_INV_PARAM,
			l_string(std_cm,"get_mark"),
				List(n_get_string("required name attribute"),
					-1));
		return 0;
	}
	if ( subname == 0 )
		subname = l_string(std_cm,"0");
	return search_mark_avt(name,subname);
}
