#include ICN_H
#include IAC_H
#include "genlib.h"

/* some defines :
   for normalisation purposes
   to ease the description */
/* to use the usual system of coordinates */
#define ICONX  10
#define ICONY -10
/* to make homogeneous connector placement */
#define CON_NORTH(d) SAX_NORTH, d, SAX_CENTER, SAX_UP,     SAX_HORIZONTAL
#define CON_SOUTH(d) SAX_SOUTH, d, SAX_CENTER, SAX_DOWN,   SAX_HORIZONTAL
#define CON_WEST(d)  SAX_WEST,  d, SAX_LEFT,   SAX_CENTER, SAX_HORIZONTAL
#define CON_EAST(d)  SAX_EAST,  d, SAX_RIGHT,  SAX_CENTER, SAX_HORIZONTAL
/* globals for the use of the macros */
IconGate_list *icon;	
IconComp_list *comp = NULL;
#define ADDICONGATE(name, xm, ym, xi, yi, xl, yl)                    \
        (icon = addicongate(name, (xm) * ICONX, (ym) * ICONY,        \
                             SAX_CENTER, SAX_CENTER, SAX_HORIZONTAL, \
                             (xi) * ICONX, (yi) * ICONY,             \
                             SAX_CENTER, SAX_CENTER, SAX_HORIZONTAL, \
                             (xl) * ICONX, (yl) * ICONY,             \
                             SAX_CENTER, SAX_CENTER, SAX_HORIZONTAL))
#define ADDICONCON(name, xc, yc, face, dir) \
        do {                           \
            switch (face) { \
               case SAX_NORTH: \
		            addiconcon(icon, name, (xc) * ICONX, (yc) * ICONY, \
                             CON_NORTH (dir), (xc) * ICONX, ((yc) + 10) * ICONY); \
                  break; \
               case SAX_SOUTH: \
		            addiconcon(icon, name, (xc) * ICONX, (yc) * ICONY, \
                             CON_NORTH (dir), (xc) * ICONX, ((yc) - 5) * ICONY); \
                  break; \
               case SAX_EAST: \
		            addiconcon(icon, name, (xc) * ICONX, (yc) * ICONY, \
						           CON_EAST (dir), ((xc) + 15) * ICONX, (yc) * ICONY); \
                  break; \
               case SAX_WEST: \
		            addiconcon(icon, name, (xc) * ICONX, (yc) * ICONY, \
                             CON_WEST (dir), ((xc) - 15) * ICONX, (yc) * ICONY); \
                  break; \
            } \
         } while (0)
#define ADDICONLINE(x0, y0, x1, y1) \
        addiconline(icon, (x0) * ICONX, (y0) * ICONY, \
                    (x1) * ICONX, (y1) * ICONY)
#define ADDICONSHAPE() do { \
                          addiconshape(icon, comp); \
                          comp = NULL; \
                       } while (0)
#define ADDICONCOMP(type, x, y) \
        (comp = addiconcomp(comp, type, (x) * ICONX, (y) * ICONY))
#define SAVEICON() do { \
                      mbkenv(); \
                      saveicon(icon); \
                   } while(0)

extern long N,M;
extern char *name;
extern int n,t0,t1;
int d=0;


void
	iconpack ()
{
	if (n+t0+t1) d=30;
	ADDICONGATE(name, 40, 50, 40, 40, 40, 30);
	ADDICONCON(NAME("A [%d:0]", M - 1), 0, 50, SAX_WEST, IN);
	ADDICONLINE(0,50,20,50);
	ADDICONCON(NAME("B [%d:0]", N - 1), 0, 30, SAX_WEST, IN);
	ADDICONLINE(0,30,20,30);
	ADDICONCON("vdd", 40, 80, SAX_NORTH, IN);
	ADDICONLINE(40, 80, 40, 60);
	ADDICONCON("vss", 40,  0, SAX_SOUTH, IN);
	ADDICONLINE(40,0,40,20);
	ADDICONCON(NAME("P [%d:0]",N+M-1), 80+d, 40, SAX_EAST, OUT);
	ADDICONLINE(80+d, 40, 60+d, 40);

	ADDICONLINE(20, 20, 60, 20);
	ADDICONLINE(60, 20, 60, 60);
	ADDICONLINE(60, 60, 20, 60);
	ADDICONLINE(20, 60, 20, 20);

	ADDICONLINE(20, 25, 35, 40);
	ADDICONLINE(35, 40, 20, 55);
	ADDICONLINE(25, 60, 40 ,45);
	ADDICONLINE(40, 45, 55, 60);
	ADDICONLINE(60, 55, 45, 40);
	ADDICONLINE(45, 40, 60, 25);
	ADDICONLINE(55, 20, 40, 35);
	ADDICONLINE(25, 20, 40, 35);

	/* si il y a un pipeline */
	if (n+t0+t1)
		{
		ADDICONLINE (60, 20, 90, 20);
		ADDICONLINE (90, 20, 90, 60);
		ADDICONLINE (90, 60, 60, 60);
		ADDICONLINE (60, 60, 60, 20);
		ADDICONLINE (70, 20, 75, 25);
		ADDICONLINE (75, 25, 80, 20);
		ADDICONCON  ("scin",  65, 0, SAX_SOUTH ,IN);	
		ADDICONCON  ("ck",    75, 0, SAX_SOUTH ,IN);	
		ADDICONCON  ("scout", 85, 0, SAX_SOUTH ,OUT);	
		ADDICONLINE (65, 0, 65, 20);
		ADDICONLINE (75, 0, 75, 20);
		ADDICONLINE (85, 0, 85, 20);
		ADDICONCON  ("sd", 70, 80, SAX_NORTH ,IN);	
		ADDICONCON  ("st", 80, 80, SAX_NORTH ,IN);	
		ADDICONLINE (70, 80, 70, 60);
		ADDICONLINE (80, 80, 80, 60);
		}

	ADDICONCOMP(COMP_ISLINE, 20, 20);
	ADDICONCOMP(COMP_ISLINE, 20, 60);
	ADDICONCOMP(COMP_ISLINE, 60+d, 60);
	ADDICONCOMP(COMP_ISLINE, 60+d, 20);

	ADDICONSHAPE();

	SAVEICON();
}
