/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit : Icon library                                                */
/*    Fichier : icnParse.c (icn's VTI (compass) parser)                     */
/*                                                                          */
/*    (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI                 */
/*    Tous droits reserves                                                  */
/*    Support : e-mail cao-vlsi@masi.ibp.fr                                 */
/*                                                                          */
/*    Auteur(s) : Vincent POUILLEY                      le : 13/09/1992     */
/*                                                                          */
/*    Modifie par : Vincent POUILLEY                    le : 07/12/1992     */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*                                                                          */
/*    $Id: icnParse.c,v 2.1.1.1 1993/09/23 16:04:30 sax Exp sax $               */
/*                                                                          */
/****************************************************************************/

#include <stdio.h>
#include <ctype.h>
#include <malloc.h>
#include "IconConst.h"
#include MUT_H
#include ICN_H
#include IAC_H
#include ICU_H
#include "ConvMacro.h"
#include <math.h>

#ident "@(#)Parser Compass icon v2.00 06/08/93 by Vincent POUILLEY"

char _init_xyminmax;
long _xmin, _xmax, _ymin, _ymax, xhot, yhot;

/*****************************************************************/
/*               Misc Function.                                  */
/*****************************************************************/

#ifdef __STDC__
void icncalc_width_height (long x, long y)
#else
void icncalc_width_height (x, y)
long x;
long y;
#endif
{
	if (_init_xyminmax)
	{
		_xmin = _xmax = x;
		_ymin = _ymax = y;
		_init_xyminmax = 0;
	}
	else
	{
		_xmin = min (_xmin, x);
		_ymin = min (_ymin, y);
		_xmax = max (_xmax, x);
		_ymax = max (_ymax, y);
	}
}

#ifdef __STDC__
void icntranslate_arc (IconArc_list* arc,
					long x1, long y1,
					long x2, long y2,
					long r, long sens)
#else
void icntranslate_arc (arc, x1, y1, x2, y2, r, sens)
IconArc_list* arc;
long x1;
long y1;
long x2;
long y2;
long r;
long sens;
#endif
{
	double  a, b, t, t4, D, R, Xc, Yc;
	double Alpha1, Alpha2, X1, Y1, X2, Y2;

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923
#endif

	X1 = (double)x1;
	X2 = (double)x2;
	Y1 = (double)y1;
	Y2 = (double)y2;
	R = (double)r;
	a = (X2 - X1) * (X2 - X1);
	b = (Y2 - Y1) * (Y2 - Y1);
	t = a + b;
	t4 = 4. * t;
	D = fabs ((4 * R * R) - t);
	/* Cas du segment horizontal */
	if ( Y1 == Y2 )
		Xc = ( X1 + X2 ) / 2. ;
	else
		if (Y1 < Y2)
			Xc = ((X1 + X2) / 2.) - sqrt((D * b) / t4);
		else
			Xc = ((X1 + X2) / 2.) + sqrt((D * b) / t4);
	/* Cas du segment vertical */
	if ( X1 == X2 )
		Yc = ( Y1 + Y2 ) / 2 ;
	else
		if (X1 < X2)
			Yc = ((Y1 + Y2) / 2.) + sqrt((D * a) / t4);
		else
			Yc = ((Y1 + Y2) / 2.) - sqrt((D * a) / t4);
	Xc = (double)ROUND(Xc);
	Yc = (double)ROUND(Yc);
	ICONARC_X0 (arc) = ROUND((Xc - R) * (double)(SCALE_X));
	ICONARC_Y0 (arc) = ROUND((Yc + R) * (double)(SCALE_X));
	ICONARC_WIDTH (arc) = ICONARC_HEIGHT (arc) = r * 2 * SCALE_X;
	
	/* Calcul des angles Angle1 et Angle2 */

    if (Xc == X1)
		Alpha1 = ( Yc < Y1 ) ? M_PI_2 :  - M_PI_2;
    else
		Alpha1 = atan2(Y1 - Yc, X1 - Xc);

    if (Xc == X2)
		Alpha2 = ( Yc < Y2 ) ? M_PI_2 : - M_PI_2;
    else
		Alpha2 = atan2(Y2 - Yc, X2 - Xc);

    if ( sens != 0 )
    {
		a = Alpha1;
		Alpha1 = Alpha2;
		Alpha2 = a;
    }
	ICONARC_ANGLE1 (arc) = ROUND(((Alpha1 >= 0) && (Alpha1 <= M_PI)) ?
								 ((180. * Alpha1 * (double)(SCALE_X)) / M_PI) :
								 (360. * (double)(SCALE_X) * (1. + Alpha1 / (2. * M_PI))));
	ICONARC_ANGLE2 (arc) = ROUND(((Alpha2 >= 0) && (Alpha2 <= M_PI)) ?
								 ((180. * Alpha2 * (double)(SCALE_X)) / M_PI) :
								 (360. * (double)(SCALE_X) * (1. + Alpha2 / (2. * M_PI))));
	ICONARC_ANGLE2 (arc) = (360 * SCALE_X) - ICONARC_ANGLE1 (arc) + ICONARC_ANGLE2 (arc);
	if (ICONARC_ANGLE2 (arc) > (360 * SCALE_X))
	{
		ICONARC_ANGLE2 (arc) -= (360 * SCALE_X);
	}
}

#ifdef __STDC__
char icnConvHAlign (char align)
#else
char icnConvHAlign (align)
char align;
#endif
{
    switch(align)
    {
		case 'R':
			return(SAX_RIGHT);
		case 'C' :
			return(SAX_CENTER);
		default  :
			return(SAX_LEFT);
    }
}

#ifdef __STDC__
char icnConvVAlign (char align)
#else
char icnConvVAlign (align)
char align;
#endif
{
    switch(align)
    {
		case 'T':
			return(SAX_UP);
		case 'C' :
			return(SAX_CENTER);
		default  :
			return(SAX_DOWN);
	}
}

#ifdef __STDC__
char icnConvDirection (char direction)
#else
char icnConvDirection (direction)
char direction;
#endif
{
    if (direction == 'H')
		return (SAX_HORIZONTAL);
    else
		return(SAX_VERTICAL);
}

/*****************************************************************/
/*               read_icn_icon_* Functions.                          */
/*****************************************************************/

#ifdef __STDC__
int read_icn_icon_model (FILE * in, char * buf, int * i, IconGate_list * icon_gate)
#else
int read_icn_icon_model (in, buf, i, icon_gate)
FILE * in;
char * buf;
int * i;
IconGate_list * icon_gate;
#endif
{
	long x, y;
	int p, q;
	int status = OK;

	/* read hot point and store it */
	p = 2;
	while (isspace(buf[p]))
		p ++;
	xhot = atoi(&buf[p]) * SCALE_X;
	p++;
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;
	yhot = atoi(&buf[p]) * SCALE_X;

	icncalc_width_height(xhot, yhot);
	
	for (q = 0; q < 3; q++)
	{
		/* first time, skip hot point (then first line of I paragraph) */
		if (fgets(buf, ICON_BUFSIZE, in) == NULL)
		{
			fprintf(stderr, "\n*** Icon Error *** loadicon (icn) impossible : Syntax error line %d\n", *i);
			return PROBLEM;
		}
		(*i) ++;

		p = 0;

		/* read geometry of name */
		while (isspace(buf[p]))
			p ++;
		x = atoi(&buf[p]) * SCALE_X;
		p++;
		while (!isspace(buf[p]))
			p++;
		while (isspace(buf[p]))
			p ++;
		y = atoi(&buf[p]) * SCALE_X;
		p++;
		while (!isspace(buf[p]))
			p++;
		while (isspace(buf[p]))
			p ++;
	
		icncalc_width_height(x, y);

		if (buf[p] != '\"')
		{
			fprintf (stderr, "\n*** Icon Error *** loadicon (icn) impossible : Syntax error line %d\n", *i);
			status = PROBLEM;
			break;
		}
		p++;
		switch (buf[p])
		{
			case 'C' :
				while (buf[p] != '\"' && buf[p] != '\0')
					p++;
				if (buf[p] == '\0')
				{
					fprintf (stderr, "\n*** Icon Error *** loadicon (icn) impossible : Syntax error line %d\n", *i);
					status = PROBLEM;
					break;
				}
				p++;
				while (isspace(buf[p]))
					p ++;
				/* skip Font definition */
				while (!isspace(buf[p]))
					p++;
				while (isspace(buf[p]))
					p ++;
				/* read alignement */
				ICONGATE_HALIGN_MODELNAME(icon_gate) = icnConvHAlign(buf[p++]);
				ICONGATE_VALIGN_MODELNAME(icon_gate) = icnConvVAlign(buf[p++]);
				while (isspace(buf[p]))
					p ++;
				/* read direction */
				ICONGATE_DIRECTION_MODELNAME(icon_gate)   = icnConvDirection(buf[p]);
				/* affect coordinate temporarly stored in x, y */
				ICONGATE_X_MODELNAME(icon_gate)   = x;
				ICONGATE_Y_MODELNAME(icon_gate)   = y;
				break;
			case 'L' :
				while (buf[p] != '\"' && buf[p] != '\0')
					p++;
				if (buf[p] == '\0')
				{
					fprintf (stderr, "\n*** Icon Error *** loadicon (icn) impossible : Syntax error line %d\n", *i);
					status = PROBLEM;
					break;
				}
				p++;
				while (isspace(buf[p]))
					p ++;
				/* skip Font definition */
				while (!isspace(buf[p]))
					p++;
				while (isspace(buf[p]))
					p ++;
				/* read alignement */
				ICONGATE_HALIGN_LABEL(icon_gate) = icnConvHAlign(buf[p++]);
				ICONGATE_VALIGN_LABEL(icon_gate) = icnConvVAlign(buf[p++]);
				while (isspace(buf[p]))
					p ++;
				/* read direction */
				ICONGATE_DIRECTION_LABEL(icon_gate)   = icnConvDirection(buf[p]);
				/* affect coordinate temporarly stored in x, y */
				ICONGATE_X_LABEL(icon_gate)   = x;
				ICONGATE_Y_LABEL(icon_gate)   = y;
				break;
			case 'I' :
				while (buf[p] != '\"' && buf[p] != '\0')
					p++;
				if (buf[p] == '\0')
				{
					fprintf (stderr, "\n*** Icon Error *** loadicon (icn) impossible : Syntax error line %d\n", *i);
					status = PROBLEM;
					break;
				}
				p++;
				while (isspace(buf[p]))
					p ++;
				/* skip Font definition */
				while (!isspace(buf[p]))
					p++;
				while (isspace(buf[p]))
					p ++;
				/* read alignement */
				ICONGATE_HALIGN_INSNAME(icon_gate) = icnConvHAlign(buf[p++]);
				ICONGATE_VALIGN_INSNAME(icon_gate) = icnConvVAlign(buf[p++]);
				while (isspace(buf[p]))
					p ++;
				/* read direction */
				ICONGATE_DIRECTION_INSNAME(icon_gate)   = icnConvDirection(buf[p]);
				/* affect coordinate temporarly stored in x, y */
				ICONGATE_X_INSNAME(icon_gate)   = x;
				ICONGATE_Y_INSNAME(icon_gate)   = y;
				break;
		}
	}
	
	return status;
}

#ifdef __STDC__
int read_icn_icon_line (char * buf, IconGate_list * icon_gate)
#else
int read_icn_icon_line (buf, icon_gate)
char * buf;
IconGate_list * icon_gate;
#endif
{
	long x1, x2, y1, y2;
	int p;
	IconLine_list*	icon_line;
	
	p = 2;
	while (isspace(buf[p]))
		p ++;
	x1 = atoi(&buf[p]) * SCALE_X;
	p++;
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;
	y1 = atoi(&buf[p]) * SCALE_X;
	p++;
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;
	x2 = atoi(&buf[p]) * SCALE_X;
	p++;
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;
	y2 = atoi(&buf[p]) * SCALE_X;

	icncalc_width_height(x1, y1);
	icncalc_width_height(x2, y2);

	icon_line = addiconline(icon_gate, x1, y1, x2, y2);

	if (icon_line == NULL)
		return PROBLEM;
	else
		return OK;
}

#ifdef __STDC__
int read_icn_icon_arc (char * buf, IconGate_list * icon_gate)
#else
int read_icn_icon_arc (buf, icon_gate)
char * buf;
IconGate_list * icon_gate;
#endif
{
	long x1, x2, y1, y2, r, sens;
	int p;
	IconArc_list*	icon_arc;
	
	p = 2;
	while (isspace(buf[p]))
		p ++;
	x1 = atoi(&buf[p]);
	p++;
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;
	y1 = atoi(&buf[p]);
	p++;
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;
	x2 = atoi(&buf[p]);
	p++;
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;
	y2 = atoi(&buf[p]);
	p++;
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;
	r = atoi(&buf[p]);
	p++;
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;
	/* skip number */
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;
	sens = atoi(&buf[p]);

	icncalc_width_height(x1 * SCALE_X, y1 * SCALE_X);
	icncalc_width_height(x2 * SCALE_X, y2 * SCALE_X);

	icon_arc = addiconarc(icon_gate,0,0,0,0,0,0);

	if (icon_arc == NULL)
		return PROBLEM;
	
	icntranslate_arc(icon_arc, x1, y1, x2, y2, r, sens);
	
	return OK;
}

#ifdef __STDC__
int read_icn_icon_circle (char * buf, IconGate_list * icon_gate)
#else
int read_icn_icon_circle (buf, icon_gate)
char * buf;
IconGate_list * icon_gate;
#endif
{
	long x, y, r;
	int p;
	IconCircle_list*	icon_circle;
	
	p = 2;
	while (isspace(buf[p]))
		p ++;
	x = atoi(&buf[p]) * SCALE_X;
	p++;
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;
	y = atoi(&buf[p]) * SCALE_X;
	p++;
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;
	r = atoi(&buf[p]) * SCALE_X;

	icon_circle = addiconcircle(icon_gate, x - r, y + r, r * 2, r * 2);

	if (icon_circle == NULL)
		return PROBLEM;
	
	icncalc_width_height(ICONCIRCLE_X0(icon_circle), ICONCIRCLE_Y0(icon_circle));
	icncalc_width_height(ICONCIRCLE_X1(icon_circle), ICONCIRCLE_Y1(icon_circle));

	return OK;
}

#ifdef __STDC__
int read_icn_icon_connector (char * buf, int i, IconGate_list * icon_gate)
#else
int read_icn_icon_connector (buf, i, icon_gate)
char * buf;
int i;
IconGate_list * icon_gate;
#endif
{
	long x, y, xname, yname;
	int p;
	char * name;
	char halign, valign, direction;
	IconCon_list*	icon_con;

	p = 2;
	while (isspace(buf[p]))
		p ++;
	/* skip Id */
	p++;
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;
	x = atoi(&buf[p]) * SCALE_X;
	p++;
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;
	y = atoi(&buf[p]) * SCALE_X;
	p++;
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;
	xname = atoi(&buf[p]) * SCALE_X;
	p++;
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;
	yname = atoi(&buf[p]) * SCALE_X;
	p++;
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;

	icncalc_width_height(x, y);
	icncalc_width_height(xname, yname);

	/* read name, skip two \" */
	if (buf[p] != '\"')
		return PROBLEM;
	p++;
	name = &buf[p];
	while (buf[p] != '\"' && buf[p] != '\0')
		p++;
	if (buf[p] == '\0')
	{
		fprintf (stderr, "\n*** Icon Error *** loadicon (icn) impossible : Syntax error line %d\n", i);
		return PROBLEM;
	}
	buf[p] = '\0';
	p++;
	while (isspace(buf[p]))
		p ++;
	
	/* skip Font */
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;

	/* read alignement */
	halign = icnConvHAlign(buf[p++]);
	valign = icnConvVAlign(buf[p++]);

	/* read direction */
	while (isspace(buf[p]))
		p ++;
	direction = icnConvDirection(buf[p]);

	icon_con = addiconcon(icon_gate, name, x, y, SAX_EAST, UNKNOWN, halign, valign, direction, xname, yname);
	
	if (icon_con == NULL)
		return PROBLEM;
	else
		return OK;
}

#ifdef __STDC__
int read_icn_icon_box (char * buf, IconGate_list * icon_gate)
#else
int read_icn_icon_box (buf, icon_gate)
char * buf;
IconGate_list * icon_gate;
#endif
{
	long x1, x2, y1, y2;
	int p;
	IconShape_list*	icon_shape;
	IconComp_list*	comp;

	/* read box */
	p = 2;
	while (isspace(buf[p]))
		p ++;
	x1 = atoi(&buf[p]) * SCALE_X;
	p++;
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;
	y1 = atoi(&buf[p]) * SCALE_X;
	p++;
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;
	x2 = atoi(&buf[p]) * SCALE_X;
	p++;
	while (!isspace(buf[p]))
		p++;
	while (isspace(buf[p]))
		p ++;
	y2 = atoi(&buf[p]) * SCALE_X;
	icncalc_width_height(x1, y1);
	icncalc_width_height(x2, y2);

	comp = NULL;
	comp = addiconcomp(comp, COMP_ISLINE, x1, y2);
	if (comp == NULL)
		return PROBLEM;
	comp = addiconcomp(comp, COMP_ISLINE, x2, y2);
	if (comp == NULL)
		return PROBLEM;
	comp = addiconcomp(comp, COMP_ISLINE, x2, y1);
	if (comp == NULL)
		return PROBLEM;
	comp = addiconcomp(comp, COMP_ISLINE, x1, y1);
	if (comp == NULL)
		return PROBLEM;

	icon_shape = addiconshape(icon_gate, comp);
	
	if (icon_shape == NULL)
		return PROBLEM;
	else
		return OK;
}

/*****************************************************************/
/*               Misc Function.                                  */
/*****************************************************************/

#ifdef __STDC__
void icnchange_repere (IconGate_list * icon_gate)
#else
void icnchange_repere (icon_gate)
IconGate_list * icon_gate;
#endif
{
	ICONGATE_X (icon_gate) = _xmin - xhot;
	ICONGATE_Y (icon_gate) = yhot - _ymax;
	ICONGATE_WIDTH (icon_gate) = _xmax - _xmin;/* + SCALE_X;*/
	ICONGATE_HEIGHT (icon_gate) = _ymax - _ymin;/* + SCALE_X;*/

	/* Change gate coordinates */
	ICONGATE_X_MODELNAME (icon_gate) -= xhot;
	ICONGATE_Y_MODELNAME (icon_gate) = yhot - ICONGATE_Y_MODELNAME (icon_gate);

	ICONGATE_X_INSNAME (icon_gate) -= xhot;
	ICONGATE_Y_INSNAME (icon_gate) = yhot - ICONGATE_Y_INSNAME (icon_gate);

	ICONGATE_X_LABEL (icon_gate) -= xhot;
	ICONGATE_Y_LABEL (icon_gate) = yhot - ICONGATE_Y_LABEL (icon_gate);

	/* Change Lines coordinates */
	{
		IconLine_list*	line;
		
		for (line = ICONGATE_LINES (icon_gate); line; line = ICONLINE_NEXT (line))
		{
			ICONLINE_X0 (line) -= xhot;
			ICONLINE_Y0 (line) = yhot - ICONLINE_Y0 (line);
			ICONLINE_X1 (line) -= xhot;
			ICONLINE_Y1 (line) = yhot - ICONLINE_Y1 (line);
		}
	}

	/* Change Shapes coordinates */
	{
		IconShape_list*	shape;
		IconComp_list*	comp;
		
		for (shape = ICONGATE_SHAPES (icon_gate); shape; shape = ICONSHAPE_NEXT (shape))
		{
			for (comp = ICONSHAPE_FIRSTCOMP (shape); comp; comp = ICONSHAPE_NEXTCOMP (comp))
			{
				ICONSHAPE_X_COMP (comp) -= xhot;
				ICONSHAPE_Y_COMP (comp) = yhot - ICONSHAPE_Y_COMP (comp);
			}
		}
	}
		
	/* Change Circles coordinates */
	{
		IconCircle_list*	circle;
		
		for (circle = ICONGATE_CIRCLES (icon_gate); circle; circle = ICONCIRCLE_NEXT (circle))
		{
			ICONCIRCLE_X0 (circle) -= xhot;
			ICONCIRCLE_Y0 (circle) = yhot - ICONCIRCLE_Y0 (circle);
		}
	}
	
	/* Change Arcs coordinates */
	{
		IconArc_list*	arc;
		
		for (arc = ICONGATE_ARCS (icon_gate); arc; arc = ICONARC_NEXT (arc))
		{
			ICONARC_X0 (arc) -= xhot;
			ICONARC_Y0 (arc) = yhot - ICONARC_Y0 (arc);
		}
	}
	
	/* Change connectors coordinates and init side */
	{
		IconCon_list*	con;
		long dl, du, dd, dr; /* distance left, distance up, distance down, distance right */
		
		for (con = ICONGATE_CONNECTORS (icon_gate); con; con = ICONCON_NEXT (con))
		{
			ICONCON_X (con) -= xhot;
			ICONCON_Y (con) = yhot - ICONCON_Y (con);
			ICONCON_X_NAME (con) -= xhot;
			ICONCON_Y_NAME (con) = yhot - ICONCON_Y_NAME (con);

			dl = ICONCON_X (con) - ICONGATE_X (icon_gate);
			dr = ICONGATE_X (icon_gate) + ICONGATE_WIDTH (icon_gate) - ICONCON_X (con);
			du = ICONCON_Y (con) - ICONGATE_Y (icon_gate);
			dd = ICONGATE_Y (icon_gate) + ICONGATE_HEIGHT (icon_gate) - ICONCON_Y (con);
		
			if ((dl <= dr) && (dl <= du) && (dl <= dd))
			{
				ICONCON_SIDE (con) = SAX_WEST;
			}
			else
				if ((dr <= du) && (dr <= dd))
				{
					ICONCON_SIDE (con) = SAX_EAST;
				}
				else
					if (du <= dd)
					{
						ICONCON_SIDE (con) = SAX_NORTH;
					}
					else
					{
						ICONCON_SIDE (con) = SAX_SOUTH;
					}
		}
	}
}

/*****************************************************************/
/*               IconGate.                                       */
/*****************************************************************/

#ifdef __STDC__
int read_icn_icon (char * name, IconGate_list * icon_gate)
#else
int read_icn_icon (name, icon_gate)
char * name;
IconGate_list * icon_gate;
#endif
{
	FILE * input_file = NULL;
	char buf[ICON_BUFSIZE];
	int i, status = OK, error = OK;

	_init_xyminmax = 1;

	ICONGATE_ISDEFAULT(icon_gate) = 0; /* This icon is not a default icon. */
	ICONGATE_SCALE(icon_gate) = 1.;
	ICONGATE_BITMAP(icon_gate) = (char *) 0;
	ICONGATE_NEXT (icon_gate) = (IconGate_list*) 0;
	ICONGATE_USER (icon_gate) = (struct ptype*) 0;
	ICONGATE_MODELNAME (icon_gate) = (char *) 0;
	ICONGATE_CONNECTORS (icon_gate) = (IconCon_list*) 0;
	ICONGATE_LINES(icon_gate) = (IconLine_list*) 0;
	ICONGATE_SHAPES(icon_gate) = (IconShape_list*) 0;
	ICONGATE_CIRCLES(icon_gate) = (IconCircle_list*) 0;
	ICONGATE_ARCS(icon_gate) = (IconArc_list*) 0;

	if ((input_file = mbkfopen(name, ICON_IN, READ_TEXT)) == NULL)
	{
		(void)fprintf(stderr,"\n*** Icon Error *** loadicon (icn) impossible : Unable to load file %s.%s\n",
					  name, ICON_IN);
		return PROBLEM;
	}
	
	for (i = 1;; i++)
	{
		if (fgets(buf, ICON_BUFSIZE, input_file) == NULL)
		{
			fprintf(stderr, "\n*** Icon Error *** loadicon (icn) impossible : Syntax error line %d\n", i);
			fclose (input_file);
			return PROBLEM;
		}
		/* skip comments */
		if (buf[0] == '#')
			continue;
		/* End of file */
		if (buf[0] == 'E')
			break;
		/* analyse other ligne */
		switch (buf[0])
		{
			case 'V' :
				break;
			case 'I' :
				if (read_icn_icon_model(input_file, buf, &i, icon_gate) == PROBLEM)
					error = PROBLEM;
				break;
			case 'L' :
				if (read_icn_icon_line(buf, icon_gate) == PROBLEM)
					error = PROBLEM;
				break;
			case 'A' :
				if (read_icn_icon_arc(buf, icon_gate) == PROBLEM)
					error = PROBLEM;
				break;
			case 'R' :
				if (read_icn_icon_circle(buf, icon_gate) == PROBLEM)
					error = PROBLEM;
				break;
			case 'C' :
				if (read_icn_icon_connector(buf, i, icon_gate) == PROBLEM)
					error = PROBLEM;
				break;
			case 'B' :
				if (read_icn_icon_box(buf, icon_gate) == PROBLEM)
					error = PROBLEM;
				break;
			default :
				error = PROBLEM;
				break;
		}
		if (error == PROBLEM)
		{
			fprintf (stderr, "\n*** Icon Error *** loadicon (icn) impossible : Syntax error line %d\n", i);
			error = OK;
			status = PROBLEM;
		}
	}
	
	ICONGATE_MODELNAME (icon_gate) = name;
  
	icnchange_repere (icon_gate);

	restoredirvbe_icon (icon_gate);
	
	fclose (input_file);
	return status;
}

#ifdef __STDC__
IconGate_list * loadicnicon(char * name)
#else
IconGate_list * loadicnicon(name)
char * name;
#endif
{
	IconGate_list * newicon;
	char * iconname;
	
	/* verify if icon allready exist */
	iconname = namealloc(name);
	if (iconname == NULL)
	{
		fprintf(stderr, "*** Icon Error *** loadicon (icn) impossible : Unable to allocate icon name \"%s\"\n", name);
		return NULL;
	}
	for(newicon = HEAD_ICON; newicon; newicon = ICONGATE_NEXT(newicon))
		if (iconname == ICONGATE_MODELNAME(newicon))
			return NULL;
	
	/* create icon */
	newicon = (IconGate_list*)malloc(sizeof(IconGate_list));
	if (newicon == NULL)
	{
		fprintf(stderr, "*** Icon Error *** loadicon (icn) impossible : Unable to allocate icon \"%s\"\n", name);
		return NULL;
	}
	if (read_icn_icon(iconname, newicon) == PROBLEM)
	{
		IconCon_list * iconcon;
		IconLine_list * iconline;
		IconShape_list * iconshape;
		IconComp_list * iconcomp;
		IconCircle_list * iconcircle;
		IconArc_list * iconarc;

		while (ICONGATE_CONNECTORS(newicon))
		{
			iconcon = ICONGATE_CONNECTORS(newicon);
			ICONGATE_CONNECTORS(newicon) = ICONCON_NEXT(iconcon);
			free(iconcon);
		}
		while (ICONGATE_LINES(newicon))
		{
			iconline = ICONGATE_LINES(newicon);
			ICONGATE_LINES(newicon) = ICONLINE_NEXT(iconline);
			free(iconline);
		}
		while (ICONGATE_SHAPES(newicon))
		{
			iconshape = ICONGATE_SHAPES(newicon);
			ICONGATE_SHAPES(newicon) = ICONSHAPE_NEXT(iconshape);
			while(ICONSHAPE_FIRSTCOMP(iconshape))
			{
				iconcomp = ICONSHAPE_FIRSTCOMP(iconshape);
				ICONSHAPE_FIRSTCOMP(iconshape) = ICONSHAPE_NEXTCOMP(iconcomp);
				free(iconcomp);
			}
			free(iconshape);
		}
		while (ICONGATE_CIRCLES(newicon))
		{
			iconcircle = ICONGATE_CIRCLES(newicon);
			ICONGATE_CIRCLES(newicon) = ICONCIRCLE_NEXT(iconcircle);
			free(iconcircle);
		}
		while (ICONGATE_ARCS(newicon))
		{
			iconarc = ICONGATE_ARCS(newicon);
			ICONGATE_ARCS(newicon) = ICONARC_NEXT(iconarc);
			free(iconarc);
		}
		free(newicon);
		return NULL;
	}
	
	ICONGATE_NEXT(newicon) = HEAD_ICON;
	HEAD_ICON = newicon;
	return newicon;
}

