/************************************************************************
*        Alliance VLSI CAD system                                       *
*                                                                       *
*   fichier : alc_driv_p.c                                              *
*   author(s)   : V. POUILLET           on : 09/07/92                   *
*   modified by : L. MAURIN\R. PREVOT   on : 12/07/93                   *
*   modified by : F. PETROT             on : 04/08/93                   *
*   version     : 4.00                                                  *
************************************************************************/

#include "generic_target.h"
#include MUT_H
#include MPH_H

#ident "@(#)Driver alliance physic v4.00 04/08/92" 

#define EOPEN        -4
#define ECLOSE       -5
#define ELAYER       -7
#define EOPGEO       -8
#define ETYPEVIA     -14
#define EFILENAME    -17
#define EREF         -23
#define MAXLBUFFER   64


#define  mc_isthrough(layer)    \
        (   ((layer)==TPOLY)    \
          ||((layer)==TALU1)    \
          ||((layer)==TALU2)    \
          ||((layer)==TALU3) )

static void alc_printwar(warn_code)
long  warn_code;
{
   fprintf( stderr, "\n*** mbk warning *** alcavephfig : ");
   switch( warn_code ) {
       case ELAYER    :
          fprintf( stderr, "layer out of range for alc\n"); break;
       case EOPGEO    :
       fprintf( stderr, "unknown transformation"); break;
       case EOPEN    :
       fprintf( stderr, "can\'t open tempory file"); break;
   case ETYPEVIA  :
       fprintf( stderr, "unknown via"); break;
      default : fprintf( stderr, "unknown warning");
      }
}


static void get_date(date)
char *date;
{
time_t tim;
struct tm *rest;

   (void)time(&tim);
   rest=localtime(&tim);
   (void)sprintf(date, "%2d/%2d/%2d", rest->tm_mday,
                 rest->tm_mon, rest->tm_year);
}

char * alc_decodelayer(layer)
char layer;
{
   static char * alc_decode[LAST_LAYER + 1] =
      { "NWELL", "PWELL", "NTIE", "PTIE", "NDIF", "PDIF",
      "NTRANS", "PTRANS", "POLY", "ALU1", "ALU2", "ALU3", "TPOLY",
      "TALU1", "TALU2", "TALU3" };

   if (layer < 0 || layer > LAST_LAYER)
      {
      alc_printwar(ELAYER);
      return "NULL";
      }
   return alc_decode[layer];
}


/****************************** alc_decodevia() *******************************/
char * alc_decodevia(type)
int type;
{
static char *alc_decode[LAST_CONTACT + 1] = 
          { "CONT_POLY",
            "CONT_VIA",
            "CONT_DIF_N",
             "CONT_DIF_P",
            "CONT_BODY_N",
            "CONT_BODY_P",
             "C_X_N",
            "C_X_P",
            "CONT_VIA2",
            "CONT_VIA3"};
   
   if (type < 0 || type > 9) {
      alc_printwar(ETYPEVIA);
      EXIT(1);
   }
   return alc_decode[type];
}


char *alc_decoderef(figname)
char *figname;
{
#define MAXREF 2
static char *alc_decode[MAXREF] = { 
      "ref_ref", 
      "ref_con", 
};
static char *alc_return[MAXREF] = { 
      "REF_REF", 
      "REF_CON", 
};
int i;

   for(i = 0; i < MAXREF; i++)
      if (strcmp(figname, alc_decode[i]) == 0)
         return alc_return[i];

   return NULL;
}


char *alc_decodetransf(transf)
char transf;
{
static char *alc_decode[8] = { "NOSYM", "ROT_P", "SYMXY", 
           "ROT_M", "SYM_X", "SY_RM", "SYM_Y", "SY_RP" };

   if (transf < 0 || transf > 7) {
      alc_printwar(EOPGEO);
      return "NOSYM";
   }

   return alc_decode[transf];
}

static void  alc_printerr2(err_code, word)
long  err_code;
char *word;
{
   fprintf( stderr, "\n*** mbk error *** alcsavephfig : ");
   switch( err_code )
    {   case EFILENAME :
       fprintf( stderr, "bad file name : %s .\n", word); break;
   case EOPEN     :
       fprintf( stderr, "can\'t open file : %s .\n", word); break;
   case EREF    :
       fprintf( stderr, " inconsistant reference :%s.\n", word); break;
   case ECLOSE    :
       fprintf( stderr, "can\'t close file : %s.\n", word); break;
   default : fprintf( stderr, "unknown error");
    }
    EXIT(1);
}



/******************************************************************************/
/******************************** alcsavephfig() ******************************/
/******************************************************************************/

void alcsavephfig(pfig)
phfig_list *pfig;
{
phcon_list *pcon;
phseg_list *pseg;
phref_list *pref;
phins_list *pins;
phvia_list *pvia;
FILE *f;
char nomp[MAXLBUFFER];

   if(!(f = mbkfopen(pfig->NAME, OUT_PH, WRITE_TEXT)))
      alc_printerr2(EOPEN, filepath(pfig->NAME, OUT_PH));

   if (TRACE_MODE == 'Y')
      (void) fprintf(stderr, "\n---mbk--- writing the file : %s\n",
							filepath(pfig->NAME, OUT_PH));

   get_date(nomp);
   (void)fprintf(f, "V ALLIANCE : 3\n");
   (void)fprintf(f, "H %s,P,%s\n", pfig->NAME, nomp);

   (void)fprintf(f, "A %ld,%ld,%ld,%ld\n", pfig->XAB1/SCALE_X,
														pfig->YAB1/SCALE_X,
                                          pfig->XAB2/SCALE_X,
														pfig->YAB2/SCALE_X);

   for(pcon = pfig->PHCON; pcon; pcon = pcon->NEXT) {
      (void)fprintf(f, "C %d,%d,%d,%s,%ld,",
                        pcon->XCON/SCALE_X, pcon->YCON/SCALE_X,
                        pcon->WIDTH/SCALE_X, pcon->NAME, pcon->INDEX);
      switch(pcon->ORIENT) {
         case NORTH :
            (void)fprintf(f, "NORTH");
            break;
         case SOUTH :
            (void)fprintf(f, "SOUTH");
            break;
         case EAST :
            (void)fprintf(f, "EAST");
            break;
         case WEST :
            (void)fprintf(f, "WEST");
            break;
      }
      (void)fprintf(f, ",%s\n", alc_decodelayer(pcon->LAYER));
   }

   for(pref = pfig->PHREF; pref; pref = pref->NEXT) {
      if (!alc_decoderef(pref->FIGNAME))
          alc_printerr2(EREF, pref->FIGNAME);
      (void)fprintf(f, "R %d,%d,%s,%s\n",
                        pref->XREF/SCALE_X, pref->YREF/SCALE_X,
                        pref->FIGNAME, pref->NAME);
   }

   for(pseg = pfig->PHSEG; pseg; pseg = pseg->NEXT) {
      (void)fprintf(f, "S %d,%d,%d,%d,%d,%s,",
                     pseg->X1/SCALE_X, pseg->Y1/SCALE_X,
                        pseg->X2/SCALE_X, pseg->Y2/SCALE_X,
                        pseg->WIDTH/SCALE_X,
                        pseg->NAME == NULL ? "*" : pseg->NAME);
      switch(pseg->TYPE) {
         case LEFT :
            (void)fprintf(f, "LEFT");
            break;
         case UP :
            (void)fprintf(f, "UP");
            break;
         case RIGHT :
            (void)fprintf(f, "RIGHT");
            break;
         case DOWN :
            (void)fprintf(f, "DOWN");
            break;
         default :
            (void)fprintf(f, "UNKNOWN");
      }
      (void)fprintf(f, ",%s\n", alc_decodelayer(pseg->LAYER));
   }

   for(pins = pfig->PHINS; pins; pins = pins->NEXT)
      (void)fprintf(f, "I %d,%d,%s,%s,%s\n",
                        pins->XINS/SCALE_X, pins->YINS/SCALE_X,
                        pins->FIGNAME, pins->INSNAME,
                        alc_decodetransf(pins->TRANSF));

   for(pvia = pfig->PHVIA; pvia; pvia = pvia->NEXT)
      (void)fprintf(f, "V %d,%d,%s\n",
                        pvia->XVIA/SCALE_X, 
                        pvia->YVIA/SCALE_X,
                        alc_decodevia(pvia->TYPE)); 

   (void)fputs("EOF\n", f);

   if (fclose(f) != 0)
      alc_printerr2(ECLOSE, filepath(pfig->NAME, OUT_PH));
}
