/**********************************************************************
 
	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	"acrp.h"

int
get_acrp_entry_dir(ACRP_DIR * d,XL_SEXP * s)
{
XL_SEXP * t;
	d->flags = 0;
	s = cdr(s);
	t = car(s);
	if ( get_type(t) != XLT_INTEGER )
		return -1;
	d->hops = t->integer.data;
	s = cdr(s);
	t = car(s);
	if ( get_type(t) != XLT_STRING )
		return -1;
	d->map = ll_copy_str(t->string.data);
	s = cdr(s);
	t = car(s);
	if ( get_type(t) != XLT_STRING )
		return -1;
	d->crd = ll_copy_str(t->string.data);
	if ( d->hops == 0 ) {
		if ( d->map )
			d_f_ree(d->map);
		if ( d->crd )
			d_f_ree(d->crd);
		d->map = nl_copy_str(std_cm,"");
		d->crd = nl_copy_str(std_cm,"");
	}
	return 0;
}

void
init_entry_dir(ACRP_DIR * d)
{
	d->hops = -1;
	d->map = 0;
	d->crd = 0;
}

int
get_acrp_entry(int * id,ACRP_ENTRY * e,XL_SEXP * s)
{
XL_SEXP * t;
int i;
	s = cdr(s);
	t = car(s);
	if ( get_type(t) != XLT_INTEGER )
		return -1;
	*id = t->integer.data;
	s = cdr(s);
	t = car(s);
	if ( get_type(t) != XLT_STRING )
		return -1;
	e->pri = ll_copy_str(t->string.data);
	s = cdr(s);
	t = car(s);
	if ( get_type(t) != XLT_INTEGER )
		return -1;
	e->sum = t->integer.data;

	s = cdr(s);

	for ( i = 0 ; i < ACRP_DIR_NOS ; i ++ )
		init_entry_dir(&e->dir[i]);
	i = 0;
	for ( ; get_type(s) == XLT_PAIR 
			&& i < ACRP_DIR_NOS ; s = cdr(s) , i ++ ) {
		if ( get_acrp_entry_dir(&e->dir[i],car(s)) < 0 )
			return -1;
	}
	return 0;
}


MAP_PATH_TABLE *
get_one_mpt(XL_SEXP * s)
{
MAP_PATH_TABLE * m;
int i,j;
ACRP_ENTRY e;
int id;
XL_SEXP * t;
	m = new_mpt(); 
	s = cdr(s);
	t = car(s);
	if ( get_type(t) != XLT_INTEGER ) {
		d_f_ree(m);
		return 0;
	}
	m->level = t->integer.data;
	s = cdr(s);
	for ( ; get_type(s) == XLT_PAIR ; s = cdr(s) ) {
		if ( get_acrp_entry(&id,&e,car(s)) < 0 ) {
			free_mpt(m);
			return 0;
		}
		m->ent[id] = e;
		if ( e.dir[0].hops == 0 )
			m->id = id;
	}
	return m;
}


MAP_PATH_TABLE *
get_mpt(unsigned int * reg,int * cid_flag,XL_SEXP * s)
{
MAP_PATH_TABLE * mpt;
MAP_PATH_TABLE ** mp;
MAP_PATH_TABLE * m1;
XL_SEXP * t, * sym;
XL_SEXP * r;
	mpt = 0;
	s = cdr(s);
	*reg = 0;
	*cid_flag = 1;
set_cpu_msg(731201);
	for ( ; get_type(s) == XLT_PAIR ; s = cdr(s) ) {
set_cpu_msg(731202);
		t = car(s);
set_cpu_msg(731203);
		if ( get_type(t) != XLT_PAIR )
			continue;
		sym = car(t);
set_cpu_msg(731204);
		if ( get_type(sym) != XLT_SYMBOL )
			continue;
set_cpu_msg(731205);
		if ( l_strcmp(sym->symbol.data,l_string(std_cm,"regulation"))
				== 0 ) {
set_cpu_msg(731206);
			r = get_el(t,1);
			if ( get_type(r) != XLT_INTEGER )
				goto err;
			*reg = r->integer.data;
		}
		else if ( l_strcmp(sym->symbol.data,l_string(std_cm,"level"))
				== 0 ) {
set_cpu_msg(731207);
			m1 = get_one_mpt(t);
set_cpu_msg(731208);
			if ( m1 == 0 )
				goto err;
			m1->next = 0;
			for ( mp = &mpt ; *mp ; mp = &(*mp)->next ) {
				if ( (*mp)->level < m1->level )
					continue;
				m1->next = *mp;
				*mp = m1;
				goto next;
			}
			*mp = m1;
		next:
			{}
		}
		else if ( l_strcmp(sym->symbol.data,l_string(std_cm,"cid"))
				== 0 ) {
set_cpu_msg(731209);
			*cid_flag = 0;
		}
set_cpu_msg(731210);
	}
set_cpu_msg(731211);
	return mpt;
err:

set_cpu_msg(731212);
	free_mpt(mpt);
set_cpu_msg(731203);
	return 0;
}
