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

#define _ICON_C_

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <ctype.h>
#include "IconConst.h"
#include MUT_H
#include ICN_H
#include IAC_H

#ident "@(#)Icon library v2.00 06/08/93 by Vincent POUILLEY"

/******************************/
/* Global declaration         */
/******************************/

IconGate_list * HEAD_ICON = NULL;
char ICON_IN[5] = { 0, 0, 0, 0, 0 };
char ICON_OUT[5] = { 0, 0, 0, 0, 0 };

/******************************/
/* Connector functions        */
/******************************/

#ifdef __STDC__
IconCon_list * addiconcon(IconGate_list * pticon,
						  char * name,
						  long x,
						  long y,
						  char side,
						  char direction,
						  char halign,
						  char valign,
						  char direction_name,
						  long x_name,
						  long y_name)
#else
IconCon_list * addiconcon(pticon, name, x, y, side, direction, halign, valign, direction_name, x_name, y_name)
IconGate_list * pticon;
char * name;
long x;
long y;
char side;
char direction;
char halign;
char valign;
char direction_name;
long x_name;
long y_name;
#endif
{
	IconCon_list * iconcon;
	char * conname;

	/* verify if connector allready exist */
	conname = namealloc(name);
	if (conname == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** addiconcon impossible : Unable to allocate connector name \"%s\"\n", name);
		return NULL;
	}
	if (pticon == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** addiconcon impossible : Invalid Icon\n");
		return NULL;
	}
	for (iconcon = ICONGATE_CONNECTORS(pticon); iconcon; iconcon = ICONCON_NEXT(iconcon))
		if (conname == ICONCON_NAME(iconcon))
			return NULL;
	/* some basic verification */
	if ((side != SAX_NORTH) && (side != SAX_SOUTH) &&
		(side != SAX_WEST)  && (side != SAX_EAST))
	{
		(void)fprintf(stderr, "*** Icon Error *** addiconcon impossible : Invalid Side : %d\n", side);
		return NULL;
	}
	if ((direction != IN) && (direction != OUT) && (direction != INOUT) &&
		(direction != UNKNOWN) && (direction != TRISTATE) && (direction != TRANSCV))
	{
		(void)fprintf(stderr, "*** Icon Error *** addiconcon impossible : Invalid Direction : %c\n", direction);
		return NULL;
	}		
	if ((halign != SAX_LEFT) && (halign != SAX_CENTER) &&
		(halign != SAX_RIGHT))
	{
		(void)fprintf(stderr, "*** Icon Error *** addiconcon impossible : Invalid Horizontal Alignment : %d\n", halign);
		return NULL;
	}
	if ((valign != SAX_UP) && (valign != SAX_CENTER) &&
		(valign != SAX_DOWN))
	{
		(void)fprintf(stderr, "*** Icon Error *** addiconcon impossible : Invalid Vertical Alignment : %d\n", valign);
		return NULL;
	}
	if ((direction_name != SAX_HORIZONTAL) && (direction_name != SAX_VERTICAL))
	{
		(void)fprintf(stderr, "*** Icon Error *** addiconcon impossible : Invalid direction of the name : %d\n", direction_name);
		return NULL;
	}
	/* create connector */
	iconcon = (IconCon_list*)malloc(sizeof(IconCon_list));
	if (iconcon == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** addiconcon impossible : Unable to allocate connector \"%s\"\n", name);
		return NULL;
	}
	ICONCON_NEXT(iconcon) = ICONGATE_CONNECTORS(pticon);
	ICONGATE_CONNECTORS(pticon) = iconcon;
	/* init coordinates and side */
	ICONCON_X(iconcon) = x;
	ICONCON_Y(iconcon) = y;
	ICONCON_SIDE(iconcon) = side;
	ICONCON_DIRECTION(iconcon) = direction;
	/* init connector name */
	ICONCON_NAME(iconcon) = conname;
	ICONCON_X_NAME(iconcon) = x_name;
	ICONCON_Y_NAME(iconcon) = y_name;
	ICONCON_HALIGN_NAME(iconcon) = halign;
	ICONCON_VALIGN_NAME(iconcon) = valign;
	ICONCON_DIRECTION_NAME(iconcon) = direction_name;
	/* reset USER field to NULL */
	ICONCON_USER(iconcon) = (ptype_list*)0;
	return iconcon;
} /* addiconcon */

#ifdef __STDC__
int deliconcon(IconGate_list * pticon, IconCon_list * ptcon)
#else
int deliconcon(pticon, ptcon)
IconGate_list * pticon;
IconCon_list * ptcon;
#endif
{
	IconCon_list * iconcon;
	
	/* some basic verification */
	if (pticon == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** deliconcon impossible : Invalid Icon\n");
		return PROBLEM;
	}
	if (ptcon == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** deliconcon impossible : Invalid Connector\n");
		return PROBLEM;
	}
	if (ptcon == ICONGATE_CONNECTORS(pticon))
	{
		ICONGATE_CONNECTORS(pticon) = ICONCON_NEXT(ptcon);
		free(ptcon);
		return OK;
	}
	for (iconcon = ICONGATE_CONNECTORS(pticon); ICONCON_NEXT(iconcon); iconcon = ICONCON_NEXT(iconcon))
		if (ICONCON_NEXT(iconcon) == ptcon)
			break;
	if (ICONCON_NEXT(iconcon) != ptcon)
		return PROBLEM;
	ICONCON_NEXT(iconcon) = ICONCON_NEXT(ptcon);
	free(ptcon);
	return OK;
} /* deliconcon */

#ifdef __STDC__
IconCon_list * geticoncon(IconGate_list * pticon, char * name)
#else
IconCon_list * geticoncon(pticon, name)
IconGate_list * pticon;
char * name;
#endif
{
	char * conname, * tmp;
	IconCon_list * iconcon;

	conname = namealloc(name);
	if (conname == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** geticoncon impossible : Unable to allocate connector name \"%s\"\n", name);
		return NULL;
	}
	if (pticon == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** geticoncon impossible : Invalid Icon\n");
		return NULL;
	}
	/* search icon in the connector list pointed to by pticon */
	if ((tmp = strchr(conname, ' ')) != NULL)
	{ /* this is a vector name */
		int nbcar;
		
		nbcar = tmp - conname;
		for (iconcon = ICONGATE_CONNECTORS(pticon); iconcon; iconcon = ICONCON_NEXT(iconcon))
			if (strncmp(conname, ICONCON_NAME(iconcon), nbcar) == 0)
				if (ICONCON_NAME(iconcon)[nbcar] == '[')
					break;
		if (iconcon == NULL)
		{ /* perhaps the icon is not vectorized */
			for (iconcon = ICONGATE_CONNECTORS(pticon); iconcon; iconcon = ICONCON_NEXT(iconcon))
				if (conname == ICONCON_NAME(iconcon))
					break;
		}
	}
	else
	{
		for (iconcon = ICONGATE_CONNECTORS(pticon); iconcon; iconcon = ICONCON_NEXT(iconcon))
			if (conname == ICONCON_NAME(iconcon))
				break;
	}

	if (iconcon == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** geticoncon impossible : Unable to find connector \"%s\"\n", name);
	}
	
	return iconcon;
} /* geticoncon */

#ifdef __STDC__
void viewiconcon(IconCon_list * ptcon)
#else
void viewiconcon(ptcon)
IconCon_list * ptcon;
#endif
{
	if (ptcon == NULL)
	{
		(void)printf("!!! invalid icon connector (null pointer) !!!\n");
		return;
	}
	if (ICONCON_NAME(ptcon))
		(void)printf("   |---connector : %s\n", ICONCON_NAME(ptcon));
	else
		(void)printf("   |--- !!! anonym connector !!!\n");
	(void)printf("   |      |---x : %ld\n", ICONCON_X(ptcon));
	(void)printf("   |      |---y : %ld\n", ICONCON_Y(ptcon));
	(void)printf("   |      |---side : %d (0:North,1:south,2:west,3:east)\n", ICONCON_SIDE(ptcon));
	(void)printf("   |      |---direction : %c (I:IN,O:OUT,B:INOUT,X:UNKNOWN,Z:TRISTATE,T:TRANSCV)\n",
				 ICONCON_DIRECTION(ptcon));
	(void)printf("   |      |---connector name geometry :\n");
	(void)printf("   |      |      |---x : %ld\n", ICONCON_X_NAME(ptcon));
	(void)printf("   |      |      |---y : %ld\n", ICONCON_Y_NAME(ptcon));
	(void)printf("   |      |      |---horizontal alignment : %d (0:LEFT,1:CENTER,2:RIGHT)\n",
				 ICONCON_HALIGN_NAME(ptcon));
	(void)printf("   |      |      |---vertical alignment : %d (0:UP,1:CENTER,2:DOWN)\n",
				 ICONCON_VALIGN_NAME(ptcon));
	(void)printf("   |      |      |---text direction : %d (0:HORIZONTAL,1:VERTICAL)\n",
				 ICONCON_DIRECTION_NAME(ptcon));
	if (ICONCON_USER(ptcon))
		(void)printf("   |      |---USER field not empty\n");
	else
		(void)printf("   |      |---USER field empty\n");
} /* viewiconcon */
	
/******************************/
/* Line functions             */
/******************************/

#ifdef __STDC__
IconLine_list * addiconline(IconGate_list * pticon,
							long x0,
							long y0,
							long x1,
							long y1)
#else
IconLine_list * addiconline(pticon, x0, y0, x1, y1)
IconGate_list * pticon;
long x0;
long y0;
long x1;
long y1;
#endif
{
	IconLine_list * iconline;
	
	if (pticon == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** addiconline impossible : Invalid Icon\n");
		return NULL;
	}
	iconline = (IconLine_list*)malloc(sizeof(IconLine_list));
	if (iconline == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** addiconline impossible : Unable to allocate line : %ld, %ld, %ld, %ld\n",
				x0, y0, x1, y1);
		return NULL;
	}
	ICONLINE_NEXT(iconline) = ICONGATE_LINES(pticon);
	ICONGATE_LINES(pticon) = iconline;
	ICONLINE_X0(iconline) = x0;
	ICONLINE_Y0(iconline) = y0;
	ICONLINE_X1(iconline) = x1;
	ICONLINE_Y1(iconline) = y1;
	return iconline;
} /* addiconline */

#ifdef __STDC__
int deliconline(IconGate_list * pticon, IconLine_list * ptline)
#else
int deliconline(pticon, ptline)
IconGate_list * pticon;
IconLine_list * ptline;
#endif
{
	IconLine_list * iconline;
	
	/* some basic verification */
	if (pticon == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** deliconline impossible : Invalid Icon\n");
		return PROBLEM;
	}
	if (ptline == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** deliconline impossible : Invalid Line\n");
		return PROBLEM;
	}
	if (ptline == ICONGATE_LINES(pticon))
	{
		ICONGATE_LINES(pticon) = ICONLINE_NEXT(ptline);
		free(ptline);
		return OK;
	}
	for (iconline = ICONGATE_LINES(pticon); ICONLINE_NEXT(iconline); iconline = ICONLINE_NEXT(iconline))
		if (ICONLINE_NEXT(iconline) == ptline)
			break;
	if (ICONLINE_NEXT(iconline) != ptline)
		return PROBLEM;
	ICONLINE_NEXT(iconline) = ICONLINE_NEXT(ptline);
	free(ptline);
	return OK;
} /* deliconline */

#ifdef __STDC__
void viewiconline (IconLine_list * ptline)
#else
void viewiconline (ptline)
IconLine_list * ptline;
#endif
{
	if (ptline == NULL)
	{
		(void)printf("!!! invalid icon line (null pointer) !!!\n");
		return;
	}
	(void)printf("   |---line : (%ld, %ld)-(%ld, %ld)\n",
		   ICONLINE_X0(ptline),
		   ICONLINE_Y0(ptline),
		   ICONLINE_X1(ptline),
		   ICONLINE_Y1(ptline));
} /* viewiconline */
	
/******************************/
/* Component functions        */
/******************************/

#ifdef __STDC__
IconComp_list * addiconcomp(IconComp_list * ptcomp,
							char type,
							long x,
							long y)
#else
IconComp_list * addiconcomp(ptcomp, type, x, y)
IconComp_list * ptcomp;
char type;
long x;
long y;
#endif
{
	IconComp_list * iconcomp;
	
	if ((type != COMP_ISLINE) && (type != COMP_ISARCSTART) &&
		(type != COMP_ISARCEND) && (type != COMP_ISARCCOMP) &&
		(type != (COMP_ISARCSTART | COMP_ISARCEND)))
	{
		(void)fprintf(stderr, "*** Icon Error *** addiconcomp impossible : Invalid Component type : %d\n", type);
		return NULL;
	}
	iconcomp = (IconComp_list*)malloc(sizeof(IconComp_list));
	if (iconcomp == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** addiconcomp impossible : Unable to allocate component : %d, %ld, %ld\n",
				type, x, y);
		return NULL;
	}
	ICONSHAPE_NEXTCOMP(iconcomp) = ptcomp;
	ICONSHAPE_X_COMP(iconcomp) = x;
	ICONSHAPE_Y_COMP(iconcomp) = y;
	ICONSHAPE_TYPE_COMP(iconcomp) = type;
	return iconcomp;
} /* addiconcomp */

#ifdef __STDC__
IconComp_list * deliconcomp(IconComp_list * pthead, IconComp_list * ptcomp)
#else
IconComp_list * deliconcomp(pthead, ptcomp)
IconComp_list * pthead;
IconComp_list * ptcomp;
#endif
{
	IconComp_list * iconcomp;
	
	/* some basic verification */
	if (pthead == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** deliconcomp impossible : Invalid Component head\n");
		return pthead;
	}
	if (ptcomp == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** deliconcomp impossible : Invalid Component\n");
		return pthead;
	}
	if (ptcomp == pthead)
	{
		pthead = ICONSHAPE_NEXTCOMP(ptcomp);
		free(ptcomp);
		return pthead;
	}
	for (iconcomp = pthead; ICONSHAPE_NEXTCOMP(iconcomp); iconcomp = ICONSHAPE_NEXTCOMP(iconcomp))
		if (ICONSHAPE_NEXTCOMP(iconcomp) == ptcomp)
			break;
	if (ICONSHAPE_NEXTCOMP(iconcomp) != ptcomp)
		return pthead;
	ICONSHAPE_NEXTCOMP(iconcomp) = ICONSHAPE_NEXTCOMP(ptcomp);
	free(ptcomp);
	return pthead;
} /* deliconcomp */

#ifdef __STDC__
void viewiconcomp (IconComp_list * ptcomp)
#else
void viewiconcomp (ptcomp)
IconComp_list * ptcomp;
#endif
{
	char comptype[30];
	
	if (ptcomp == NULL)
	{
		(void)printf("!!! invalid icon component of shape (null pointer) !!!\n");
		return;
	}
	comptype[0] = '\0';
	if (ICONSHAPE_COMP_ISLINE(ptcomp))
		strcat(comptype, "Line ");
	if (ICONSHAPE_COMP_ISARCSTART(ptcomp))
		strcat(comptype, "ArcStart ");
	if (ICONSHAPE_COMP_ISARCCOMP(ptcomp))
		strcat(comptype, "ArcComp ");
	if (ICONSHAPE_COMP_ISARCEND(ptcomp))
		strcat(comptype, "ArcEnd ");
	(void)printf("   |      |----component : (%ld, %ld) type : %s\n",
		   ICONSHAPE_X_COMP(ptcomp),
		   ICONSHAPE_Y_COMP(ptcomp),
		   comptype);
} /* viewiconcomp */

/******************************/
/* Shape functions            */
/******************************/

#ifdef __STDC__
IconShape_list * addiconshape(IconGate_list * pticon, IconComp_list * ptcomp)
#else
IconShape_list * addiconshape(pticon, ptcomp)
IconGate_list * pticon;
IconComp_list * ptcomp;
#endif
{
	IconShape_list * iconshape;
	IconComp_list * iconcomp;
	
	if (pticon == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** addiconshape impossible : Invalid Icon\n");
		return NULL;
	}
	if (ptcomp == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** addiconshape impossible : Invalid Component list\n");
		return NULL;
	}
	iconshape = (IconShape_list*)malloc(sizeof(IconShape_list));
	if (iconshape == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** addiconshape impossible : Unable to allocate shape\n");
		return NULL;
	}
	ICONSHAPE_NEXT(iconshape) = ICONGATE_SHAPES(pticon);
	ICONGATE_SHAPES(pticon) = iconshape;
	ICONSHAPE_FIRSTCOMP(iconshape) = ptcomp;
	for (iconcomp = ptcomp, ICONSHAPE_NBCOMP(iconshape) = 0; iconcomp; iconcomp = ICONSHAPE_NEXTCOMP(iconcomp))
	{
		ICONSHAPE_NBCOMP(iconshape) += 1;
	}
	return iconshape;
} /* addiconshape */

#ifdef __STDC__
int deliconshape(IconGate_list * pticon, IconShape_list * ptshape)
#else
int deliconshape(pticon, ptshape)
IconGate_list * pticon;
IconShape_list * ptshape;
#endif
{
	IconShape_list * iconshape;
	IconComp_list * iconcomp;
	
	/* some basic verification */
	if (pticon == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** deliconshape impossible : Invalid Icon\n");
		return PROBLEM;
	}
	if (ptshape == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** deliconshape impossible : Invalid Shape\n");
		return PROBLEM;
	}
	while (ICONSHAPE_FIRSTCOMP(ptshape))
	{
		iconcomp = ICONSHAPE_FIRSTCOMP(ptshape);
		ICONSHAPE_FIRSTCOMP(ptshape) = ICONSHAPE_NEXTCOMP(iconcomp);
		free(iconcomp);
	}
	if (ptshape == ICONGATE_SHAPES(pticon))
	{
		ICONGATE_SHAPES(pticon) = ICONSHAPE_NEXT(ptshape);
		free(ptshape);
		return OK;
	}
	for (iconshape = ICONGATE_SHAPES(pticon); ICONSHAPE_NEXT(iconshape); iconshape = ICONSHAPE_NEXT(iconshape))
		if (ICONSHAPE_NEXT(iconshape) == ptshape)
			break;
	if (ICONSHAPE_NEXT(iconshape) != ptshape)
		return PROBLEM;
	ICONSHAPE_NEXT(iconshape) = ICONSHAPE_NEXT(ptshape);
	free(ptshape);
	return OK;
} /* deliconshape */

#ifdef __STDC__
void viewiconshape (IconShape_list * ptshape)
#else
void viewiconshape (ptshape)
IconShape_list * ptshape;
#endif
{
	IconComp_list * ptcomp;
	
	if (ptshape == NULL)
	{
		(void)printf("!!! invalid icon shape (null pointer) !!!\n");
		return;
	}
	(void)printf("   |---shape :\n");
	(void)printf("   |      |---number of components : %d\n", ICONSHAPE_NBCOMP(ptshape));
	if (ICONSHAPE_FIRSTCOMP(ptshape))
		for (ptcomp = ICONSHAPE_FIRSTCOMP(ptshape); ptcomp; ptcomp = ICONSHAPE_NEXTCOMP(ptcomp))
			viewiconcomp(ptcomp);
	else
		(void)printf("   |      |---components list empty\n");
} /* viewiconshape */

/******************************/
/* Circle functions           */
/******************************/

#ifdef __STDC__
IconCircle_list * addiconcircle(IconGate_list * pticon,
								long x0,
								long y0,
								long width,
								long height)
#else
IconCircle_list * addiconcircle(pticon, x0, y0, width, height)
IconGate_list * pticon;
long x0;
long y0;
long width;
long height;
#endif
{
	IconCircle_list * iconcircle;
	
	if (pticon == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** addiconcircle impossible : Invalid Icon\n");
		return NULL;
	}
	iconcircle = (IconCircle_list*)malloc(sizeof(IconCircle_list));
	if (iconcircle == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** addiconcircle impossible : Unable to allocate circle : %ld, %ld, %ld, %ld\n",
				x0, y0, width, height);
		return NULL;
	}
	ICONCIRCLE_NEXT(iconcircle) = ICONGATE_CIRCLES(pticon);
	ICONGATE_CIRCLES(pticon) = iconcircle;
	ICONCIRCLE_X0(iconcircle) = x0;
	ICONCIRCLE_Y0(iconcircle) = y0;
	ICONCIRCLE_WIDTH(iconcircle) = width;
	ICONCIRCLE_HEIGHT(iconcircle) = height;
	return iconcircle;
} /* addiconcircle */

#ifdef __STDC__
int deliconcircle(IconGate_list * pticon, IconCircle_list * ptcircle)
#else
int deliconcircle(pticon, ptcircle)
IconGate_list * pticon;
IconCircle_list * ptcircle;
#endif
{
	IconCircle_list * iconcircle;
	
	/* some basic verification */
	if (pticon == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** deliconcircle impossible : Invalid Icon\n");
		return PROBLEM;
	}
	if (ptcircle == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** deliconcircle impossible : Invalid Circle\n");
		return PROBLEM;
	}
	if (ptcircle == ICONGATE_CIRCLES(pticon))
	{
		ICONGATE_CIRCLES(pticon) = ICONCIRCLE_NEXT(ptcircle);
		free(ptcircle);
		return OK;
	}
	for (iconcircle = ICONGATE_CIRCLES(pticon); ICONCIRCLE_NEXT(iconcircle); iconcircle = ICONCIRCLE_NEXT(iconcircle))
		if (ICONCIRCLE_NEXT(iconcircle) == ptcircle)
			break;
	if (ICONCIRCLE_NEXT(iconcircle) != ptcircle)
		return PROBLEM;
	ICONCIRCLE_NEXT(iconcircle) = ICONCIRCLE_NEXT(ptcircle);
	free(ptcircle);
	return OK;
} /* deliconcircle */

#ifdef __STDC__
void viewiconcircle (IconCircle_list * ptcircle)
#else
void viewiconcircle (ptcircle)
IconCircle_list * ptcircle;
#endif
{
	if (ptcircle == NULL)
	{
		(void)printf("!!! invalid icon circle (null pointer) !!!\n");
		return;
	}
	(void)printf("   |---circle :\n");
	(void)printf("   |      |---x : %ld\n", ICONCIRCLE_X0(ptcircle));
	(void)printf("   |      |---y : %ld\n", ICONCIRCLE_Y0(ptcircle));
	(void)printf("   |      |---width : %ld\n", ICONCIRCLE_WIDTH(ptcircle));
	(void)printf("   |      |---height : %ld\n", ICONCIRCLE_HEIGHT(ptcircle));
} /* viewiconcircle */

/******************************/
/* Arc functions              */
/******************************/

#ifdef __STDC__
IconArc_list * addiconarc(IconGate_list * pticon,
						  long x0,
						  long y0,
						  long width,
						  long height,
						  long angle1,
						  long angle2)
#else
IconArc_list * addiconarc(pticon, x0, y0, width, height, angle1, angle2)
IconGate_list * pticon;
long x0;
long y0;
long width;
long height;
long angle1;
long angle2;
#endif
{
	IconArc_list * iconarc;
	
	if (pticon == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** addiconarc impossible : Invalid Icon\n");
		return NULL;
	}
	iconarc = (IconArc_list*)malloc(sizeof(IconArc_list));
	if (iconarc == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** addiconarc impossible : Unable to allocate arc : %ld, %ld, %ld, %ld, %d, %d\n",
				x0, y0, width, height, angle1, angle2);
		return NULL;
	}
	ICONARC_NEXT(iconarc) = ICONGATE_ARCS(pticon);
	ICONGATE_ARCS(pticon) = iconarc;
	ICONARC_X0(iconarc) = x0;
	ICONARC_Y0(iconarc) = y0;
	ICONARC_WIDTH(iconarc) = width;
	ICONARC_HEIGHT(iconarc) = height;
	ICONARC_ANGLE1(iconarc) = angle1;
	ICONARC_ANGLE2(iconarc) = angle2;
	return iconarc;
} /* addiconarc */

#ifdef __STDC__
int deliconarc(IconGate_list * pticon, IconArc_list * ptarc)
#else
int deliconarc(pticon, ptarc)
IconGate_list * pticon;
IconArc_list * ptarc;
#endif
{
	IconArc_list * iconarc;
	
	/* some basic verification */
	if (pticon == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** deliconarc impossible : Invalid Icon\n");
		return PROBLEM;
	}
	if (ptarc == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** deliconarc impossible : Invalid Arc\n");
		return PROBLEM;
	}
	if (ptarc == ICONGATE_ARCS(pticon))
	{
		ICONGATE_ARCS(pticon) = ICONARC_NEXT(ptarc);
		free(ptarc);
		return OK;
	}
	for (iconarc = ICONGATE_ARCS(pticon); ICONARC_NEXT(iconarc); iconarc = ICONARC_NEXT(iconarc))
		if (ICONARC_NEXT(iconarc) == ptarc)
			break;
	if (ICONARC_NEXT(iconarc) != ptarc)
		return PROBLEM;
	ICONARC_NEXT(iconarc) = ICONARC_NEXT(ptarc);
	free(ptarc);
	return OK;
} /* deliconarc */

#ifdef __STDC__
void viewiconarc (IconArc_list * ptarc)
#else
void viewiconarc (ptarc)
IconArc_list * ptarc;
#endif
{
	if (ptarc == NULL)
	{
		(void)printf("!!! invalid icon arc (null pointer) !!!\n");
		return;
	}
	(void)printf("   |---arc :\n");
	(void)printf("   |      |---x : %ld\n", ICONARC_X0(ptarc));
	(void)printf("   |      |---y : %ld\n", ICONARC_Y0(ptarc));
	(void)printf("   |      |---width : %ld\n", ICONARC_WIDTH(ptarc));
	(void)printf("   |      |---height : %ld\n", ICONARC_HEIGHT(ptarc));
	(void)printf("   |      |---angle1 : %ld\n", ICONARC_ANGLE1(ptarc));
	(void)printf("   |      |---angle2 : %ld\n", ICONARC_ANGLE2(ptarc));
} /* viewiconarc */

/******************************/
/* Gate functions             */
/******************************/

#ifdef __STDC__
IconGate_list * addicongate(char*	modelname,
							long	x_model_name,
							long	y_model_name,
							char	halign_model,
							char	valign_model,
							char	direction_model,
							long	x_ins_name,
							long	y_ins_name,
							char	halign_ins,
							char	valign_ins,
							char	direction_ins,
							long	x_label,
							long	y_label,
							char	halign_label,
							char	valign_label,
							char	direction_label)
#else
IconGate_list * addicongate(modelname, x_model_name, y_model_name,
							halign_model, valign_model, direction_model,
							x_ins_name, y_ins_name, halign_ins,
							valign_ins, direction_ins, x_label, y_label,
							halign_label, valign_label, direction_label)
char*	modelname;
long	x_model_name;
long	y_model_name;
char	halign_model;
char	valign_model;
char	direction_model;
long	x_ins_name;
long	y_ins_name;
char	halign_ins;
char	valign_ins;
char	direction_ins;
long	x_label;
long	y_label;
char	halign_label;
char	valign_label;
char	direction_label;
#endif
{
	IconGate_list * newicon;
	char * iconname;
	
	/* verify if icon allready exist */
	iconname = namealloc(modelname);
	if (iconname == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** addicongate impossible : Unable to allocate icon name \"%s\"\n", modelname);
		return NULL;
	}
	for(newicon = HEAD_ICON; newicon; newicon = ICONGATE_NEXT(newicon))
		if (iconname == ICONGATE_MODELNAME(newicon))
			return NULL;
	/* some basic verification */
	if ((halign_model != SAX_LEFT) && (halign_model != SAX_CENTER) &&
		(halign_model != SAX_RIGHT))
	{
		(void)fprintf(stderr, "*** Icon Error *** addicongate impossible : Invalid Horizontal Alignment : %d\n", halign_model);
		return NULL;
	}
	if ((valign_model != SAX_UP) && (valign_model != SAX_CENTER) &&
		(valign_model != SAX_DOWN))
	{
		(void)fprintf(stderr, "*** Icon Error *** addicongate impossible : Invalid Vertical Alignment : %d\n", valign_model);
		return NULL;
	}
	if ((direction_model != SAX_HORIZONTAL) && (direction_model != SAX_VERTICAL))
	{
		(void)fprintf(stderr, "*** Icon Error *** addicongate impossible : Invalid direction : %d\n", direction_model);
		return NULL;
	}
	if ((halign_ins != SAX_LEFT) && (halign_ins != SAX_CENTER) &&
		(halign_ins != SAX_RIGHT))
	{
		(void)fprintf(stderr, "*** Icon Error *** addicongate impossible : Invalid Horizontal Alignment : %d\n", halign_ins);
		return NULL;
	}
	if ((valign_ins != SAX_UP) && (valign_ins != SAX_CENTER) &&
		(valign_ins != SAX_DOWN))
	{
		(void)fprintf(stderr, "*** Icon Error *** addicongate impossible : Invalid Vertical Alignment : %d\n", valign_ins);
		return NULL;
	}
	if ((direction_ins != SAX_HORIZONTAL) && (direction_ins != SAX_VERTICAL))
	{
		(void)fprintf(stderr, "*** Icon Error *** addicongate impossible : Invalid direction : %d\n", direction_ins);
		return NULL;
	}
	if ((halign_label != SAX_LEFT) && (halign_label != SAX_CENTER) &&
		(halign_label != SAX_RIGHT))
	{
		(void)fprintf(stderr, "*** Icon Error *** addicongate impossible : Invalid Horizontal Alignment : %d\n", halign_label);
		return NULL;
	}
	if ((valign_label != SAX_UP) && (valign_label != SAX_CENTER) &&
		(valign_label != SAX_DOWN))
	{
		(void)fprintf(stderr, "*** Icon Error *** addicongate impossible : Invalid Vertical Alignment : %d\n", valign_label);
		return NULL;
	}
	if ((direction_label != SAX_HORIZONTAL) && (direction_label != SAX_VERTICAL))
	{
		(void)fprintf(stderr, "*** Icon Error *** addicongate impossible : Invalid direction : %d\n", direction_label);
		return NULL;
	}
	/* create icon */
	newicon = (IconGate_list*)malloc(sizeof(IconGate_list));
	if (newicon == NULL)
	{
		(void)fprintf(stderr, "*** Icon Error *** addicongate impossible : Unable to allocate icon \"%s\"\n", modelname);
		return NULL;
	}
	ICONGATE_NEXT(newicon) = HEAD_ICON;
	HEAD_ICON = newicon;
	ICONGATE_ISDEFAULT(newicon) = 0;
	/* init model name */
	ICONGATE_MODELNAME(newicon) = iconname;
	ICONGATE_X_MODELNAME(newicon) = x_model_name;
	ICONGATE_Y_MODELNAME(newicon) = y_model_name;
	ICONGATE_HALIGN_MODELNAME(newicon) = halign_model;
	ICONGATE_VALIGN_MODELNAME(newicon) = valign_model;
	ICONGATE_DIRECTION_MODELNAME(newicon) = direction_model;
	/* init instance name geometry */
	ICONGATE_X_INSNAME(newicon) = x_ins_name;
	ICONGATE_Y_INSNAME(newicon) = y_ins_name;
	ICONGATE_HALIGN_INSNAME(newicon) = halign_ins;
	ICONGATE_VALIGN_INSNAME(newicon) = valign_ins;
	ICONGATE_DIRECTION_INSNAME(newicon) = direction_ins;
	/* init label geometry */
	ICONGATE_X_LABEL(newicon) = x_label;
	ICONGATE_Y_LABEL(newicon) = y_label;
	ICONGATE_HALIGN_LABEL(newicon) = halign_label;
	ICONGATE_VALIGN_LABEL(newicon) = valign_label;
	ICONGATE_DIRECTION_LABEL(newicon) = direction_label;
	/* x, y, width and height = 0 */
	ICONGATE_X(newicon) = 0;
	ICONGATE_Y(newicon) = 0;
	ICONGATE_WIDTH(newicon) = 0;
	ICONGATE_HEIGHT(newicon) = 0;
	/* scale = 1. */
	ICONGATE_SCALE(newicon) = 1.;
	/* resetting pointer to NULL */
	ICONGATE_CONNECTORS(newicon) = (IconCon_list*)0;
	ICONGATE_LINES(newicon) = (IconLine_list*)0;
	ICONGATE_SHAPES(newicon) = (IconShape_list*)0;
	ICONGATE_CIRCLES(newicon) = (IconCircle_list*)0;
	ICONGATE_ARCS(newicon) = (IconArc_list*)0;
	ICONGATE_USER(newicon) = (ptype_list*)0;
	ICONGATE_BITMAP(newicon) = (char*)0;
	return newicon;
} /* addicongate */

#ifdef __STDC__
int delicongate(char * modelname)
#else
int delicongate(modelname)
char * modelname;
#endif
{
	char * iconname;
	IconGate_list * icongate;
	IconCon_list * iconcon;
	IconLine_list * iconline;
	IconShape_list * iconshape;
	IconComp_list * iconcomp;
	IconCircle_list * iconcircle;
	IconArc_list * iconarc;

	iconname = namealloc(modelname);
	if (iconname == NULL)
		return PROBLEM;
	/* search icongate in the global list pointed to by HEAD_ICON */
	/* and remove it from the global list */
	if (iconname == ICONGATE_MODELNAME(HEAD_ICON))
	{
		icongate = HEAD_ICON;
		HEAD_ICON = ICONGATE_NEXT(icongate);
	}
	else
	{
		IconGate_list * ptmp;
		
		for (ptmp = HEAD_ICON; ICONGATE_NEXT(ptmp); ptmp = ICONGATE_NEXT(ptmp))
			if (iconname == ICONGATE_MODELNAME(ICONGATE_NEXT(ptmp)))
				break;
		if (ICONGATE_NEXT(ptmp) == NULL)
			return PROBLEM;
		icongate = ICONGATE_NEXT(ptmp);
		ICONGATE_NEXT(ptmp) = ICONGATE_NEXT(icongate);
	}
	while (ICONGATE_CONNECTORS(icongate))
	{
		iconcon = ICONGATE_CONNECTORS(icongate);
		ICONGATE_CONNECTORS(icongate) = ICONCON_NEXT(iconcon);
		free(iconcon);
	}
	while (ICONGATE_LINES(icongate))
	{
		iconline = ICONGATE_LINES(icongate);
		ICONGATE_LINES(icongate) = ICONLINE_NEXT(iconline);
		free(iconline);
	}
	while (ICONGATE_SHAPES(icongate))
	{
		iconshape = ICONGATE_SHAPES(icongate);
		ICONGATE_SHAPES(icongate) = ICONSHAPE_NEXT(iconshape);
		while(ICONSHAPE_FIRSTCOMP(iconshape))
		{
			iconcomp = ICONSHAPE_FIRSTCOMP(iconshape);
			ICONSHAPE_FIRSTCOMP(iconshape) = ICONSHAPE_NEXTCOMP(iconcomp);
			free(iconcomp);
		}
		free(iconshape);
	}
	while (ICONGATE_CIRCLES(icongate))
	{
		iconcircle = ICONGATE_CIRCLES(icongate);
		ICONGATE_CIRCLES(icongate) = ICONCIRCLE_NEXT(iconcircle);
		free(iconcircle);
	}
	while (ICONGATE_ARCS(icongate))
	{
		iconarc = ICONGATE_ARCS(icongate);
		ICONGATE_ARCS(icongate) = ICONARC_NEXT(iconarc);
		free(iconarc);
	}
	free(icongate);
	return OK;
} /* delicongate */

#ifdef __STDC__
IconGate_list * geticongate(char * modelname)
#else
IconGate_list * geticongate(modelname)
char * modelname;
#endif
{
	char * iconname;
	IconGate_list * icongate;

	iconname = namealloc(modelname);
	if (iconname == NULL)
		return NULL;
	/* search icongate in the global list pointed to by HEAD_ICON */
	for (icongate = HEAD_ICON; icongate; icongate = ICONGATE_NEXT(icongate))
		if (iconname == ICONGATE_MODELNAME(icongate))
			break;
	return icongate;
} /* geticongate */

#ifdef __STDC__
void viewicongate(IconGate_list * pticon)
#else
void viewicongate(pticon)
IconGate_list * pticon;
#endif
{
	IconCon_list * ptcon;
	IconLine_list * ptline;
	IconShape_list * ptshape;
	IconCircle_list * ptcircle;
	IconArc_list * ptarc;

	if (pticon == NULL)
	{
		(void)printf("!!! invalid icon (null pointer) !!!\n");
		return;
	}
	if (ICONGATE_MODELNAME(pticon) == NULL)
		(void)printf("!!! anonym icon !!!\n");
	else
		(void)printf("\nIcon : %-20s  default description : %s\n",
			   ICONGATE_MODELNAME(pticon),
			   (ICONGATE_ISDEFAULT(pticon)) ? "Yes" : "No");
	(void)printf("   |---x : %ld\n", ICONGATE_X(pticon));
	(void)printf("   |---y : %ld\n", ICONGATE_Y(pticon));
	(void)printf("   |---width : %ld\n", ICONGATE_WIDTH(pticon));
	(void)printf("   |---height : %ld\n", ICONGATE_HEIGHT(pticon));
	(void)printf("   |---scale : %g\n", ICONGATE_SCALE(pticon));
	(void)printf("   |---model name geometry :\n");
	(void)printf("   |      |---x : %ld\n", ICONGATE_X_MODELNAME(pticon));
	(void)printf("   |      |---y : %ld\n", ICONGATE_Y_MODELNAME(pticon));
	(void)printf("   |      |---horizontal alignment : %d (0:LEFT,1:CENTER,2:RIGHT)\n",
		   ICONGATE_HALIGN_MODELNAME(pticon));
	(void)printf("   |      |---vertical alignment : %d (0:UP,1:CENTER,2:DOWN)\n",
		   ICONGATE_VALIGN_MODELNAME(pticon));
	(void)printf("   |      |---text direction : %d (0:HORIZONTAL,1:VERTICAL)\n",
		   ICONGATE_DIRECTION_MODELNAME(pticon));
	(void)printf("   |---instance name geometry :\n");
	(void)printf("   |      |---x : %ld\n", ICONGATE_X_INSNAME(pticon));
	(void)printf("   |      |---y : %ld\n", ICONGATE_Y_INSNAME(pticon));
	(void)printf("   |      |---horizontal alignment : %d (0:LEFT,1:CENTER,2:RIGHT)\n",
		   ICONGATE_HALIGN_INSNAME(pticon));
	(void)printf("   |      |---vertical alignment : %d (0:UP,1:CENTER,2:DOWN)\n",
		   ICONGATE_VALIGN_INSNAME(pticon));
	(void)printf("   |      |---text direction : %d (0:HORIZONTAL,1:VERTICAL)\n",
		   ICONGATE_DIRECTION_INSNAME(pticon));
	(void)printf("   |---label geometry :\n");
	(void)printf("   |      |---x : %ld\n", ICONGATE_X_LABEL(pticon));
	(void)printf("   |      |---y : %ld\n", ICONGATE_Y_LABEL(pticon));
	(void)printf("   |      |---horizontal alignment : %d (0:LEFT,1:CENTER,2:RIGHT)\n",
		   ICONGATE_HALIGN_LABEL(pticon));
	(void)printf("   |      |---vertical alignment : %d (0:UP,1:CENTER,2:DOWN)\n",
		   ICONGATE_VALIGN_LABEL(pticon));
	(void)printf("   |      |---text direction : %d (0:HORIZONTAL,1:VERTICAL)\n",
		   ICONGATE_DIRECTION_LABEL(pticon));
	if (ICONGATE_BITMAP(pticon))
		(void)printf("   |---bitmap definition exist\n");
	else
		(void)printf("   |---no bitmap definition\n");
	if (ICONGATE_CONNECTORS(pticon))
		for (ptcon = ICONGATE_CONNECTORS(pticon); ptcon; ptcon = ICONCON_NEXT(ptcon))
			viewiconcon(ptcon);
	else
		(void)printf("   |---connectors list empty\n");
	if (ICONGATE_LINES(pticon))
		for (ptline = ICONGATE_LINES(pticon); ptline; ptline = ICONLINE_NEXT(ptline))
			viewiconline(ptline);
	else
		(void)printf("   |---lines list empty\n");
	if (ICONGATE_SHAPES(pticon))
		for (ptshape = ICONGATE_SHAPES(pticon); ptshape; ptshape = ICONSHAPE_NEXT(ptshape))
			viewiconshape(ptshape);
	else
		(void)printf("   |---shapes list empty\n");
	if (ICONGATE_CIRCLES(pticon))
		for (ptcircle = ICONGATE_CIRCLES(pticon); ptcircle; ptcircle = ICONCIRCLE_NEXT(ptcircle))
			viewiconcircle(ptcircle);
	else
		(void)printf("   |---circles list empty\n");
	if (ICONGATE_ARCS(pticon))
		for (ptarc = ICONGATE_ARCS(pticon); ptarc; ptarc = ICONARC_NEXT(ptarc))
			viewiconarc(ptarc);
	else
		(void)printf("   |---arcs list empty\n");
	if (ICONGATE_USER(pticon))
		(void)printf("   |---USER field not empty\n");
	else
		(void)printf("   |---USER field empty\n");
} /* viewicongate */

void viewicon()
{
	IconGate_list * pticon;
	
	if (HEAD_ICON == NULL)
	{
		(void)printf("\n*** Icon *** view : list of icon empty\n");
		return;
	}
	else
		for (pticon = HEAD_ICON; pticon; pticon = ICONGATE_NEXT(pticon))
			viewicongate(pticon);
} /* viewicon */
