/*------------------------------------------------------------\
|                                                             |
| Tool    :                    DRUC                           |
|                                                             |
| File    :                  DRUCBATH.C                       |
|                                                             |
| Authors :                Renaud Patrick                     |
|                                                             |
| Date    :                   11/01/94                        |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                         Include Files                       |
|                                                             |
\------------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include MPU_H
#include MPH_H
#include MUT_H
#include RDS_H
#include RUT_H
#include RTL_H
#include RWI_H
#include RFM_H
#include RPR_H

#include "drucutil.h"
#include "vmctools.h"
#include "vmcerror.h"
#include "druchier.h"
#include "vmcasmld.h"
#include "vmcaract.h"
#include "vmcdefin.h"
#include "vmcrelat.h"
#include "drucmin.h"
#include "vmcunify.h"
#include "drucring.h"
#include "drucbath.h"
/*------------------------------------------------------------\
|                                                             |
|                          Variables                          |
|                                                             |
\------------------------------------------------------------*/

extern rdsfig_list   *DrucFigureRdsErreur;
extern FILE          *DrucErrorFile;

/*------------------------------------------------------------\
|                                                             |
|                          DrucConcateneErrorFiles            |
|                                                             |
\------------------------------------------------------------*/

void DrucConcateneErrorFiles ( DrucFigureRds,
                               DrucErrorFile
                             )
     rdsfig_list *DrucFigureRds;
     FILE        *DrucErrorFile;

{

rdsins_list *InstanceCourante;
char        *TmpErrorFileName;
FILE        *TmpErrorFile;
char         DrucTmpFileBuffer [ DRUC_MAX_STRING_BUFFER + 1 ];

  fputs ( "\n" ,
          DrucErrorFile 
        );
  fputs ( DrucFigureRds->NAME , 
          DrucErrorFile 
        );
  fputs ( "\n" , 
          DrucErrorFile 
        );

DrucViewString      ( "Merge Errorfiles: "
                    );
DrucViewString      ( "\n"
                    );
        
  for ( InstanceCourante  = DrucFigureRds->INSTANCE;
        InstanceCourante != (rdsins_list *)NULL;
        InstanceCourante  = InstanceCourante->NEXT
      )
  {
    TmpErrorFileName = DrucAddSuffixeName ( InstanceCourante->FIGNAME,
                                            DRUC_ERROR_FILE_SUFFIXE
                                          );

    DrucViewString      ( TmpErrorFileName
                        );
    DrucViewString      ( "\n"
                        );
       
    TmpErrorFile = fopen ( TmpErrorFileName,
                           "r"
                         );

    if ( TmpErrorFile != NULL ) 
    {
      while ( fgets( DrucTmpFileBuffer,
                     DRUC_MAX_FILE_BUFFER,
                     TmpErrorFile
                   )
              != (char *)NULL
            )
      {
        fputs ( DrucTmpFileBuffer , 
                DrucErrorFile 
              );
      }

      fclose  ( TmpErrorFile
              );
      unlink  ( TmpErrorFileName
              );
    }
  }
}

/*------------------------------------------------------------\
|                                                             |
|                          DrucConcateneErrorFigures          |
|                                                             |
\------------------------------------------------------------*/

void DrucConcateneErrorFigures ( DrucFigureRds,
                                 DrucFigureRdsErreur
                               )
     rdsfig_list *DrucFigureRds;
     rdsfig_list *DrucFigureRdsErreur;

{

rdsfig_list *InstanceModele;
rdsins_list *InstanceCourante;
rdsrec_list *RectangleCourant;
rdsrec_list *NouveauRectangle;
char        *TmpName;
long         PositionBboxX  = 0;
long         PositionBboxY  = 0;
long         PositionBboxDX = 0;
long         PositionBboxDY = 0;
int          IndexLayer;

DrucViewString      ( "Merge Error Instances:"
                    );
    DrucViewString      ( "\n"
                        );
        
  for ( InstanceCourante  = DrucFigureRds->INSTANCE;
        InstanceCourante != (rdsins_list *)NULL;
        InstanceCourante  = InstanceCourante->NEXT
      )
  {
/*\
 * pour toutes les instances de la figure inserer les rectangles 
 * du modele de l'instance dans le bloc
 * et modifier la taille de ABOX par la taille de BBOX
\*/
    TmpName = DrucAddSuffixeName ( InstanceCourante->FIGNAME,
                                   DRUC_ERROR_EXTEND
                                 );

    InstanceModele = searchrdsfig( TmpName
                                 );

    if ( InstanceModele == (rdsfig_list *)NULL
       )
    {
      continue;
    }
    DrucViewString      ( TmpName 
                        );
    DrucViewString      ( "\n"
                        );
        
    for ( IndexLayer  = 0;
          IndexLayer  < RDS_MAX_LAYER;
          IndexLayer ++
        )
    {
      if ( ( IndexLayer == DRUC_BBOX ) ||
           ( IndexLayer == RDS_USER0 ) ||
           ( IndexLayer == RDS_USER1 ) ||
           ( IndexLayer == RDS_USER2 )
         )
      {
        continue;
      }

      for ( RectangleCourant  = InstanceModele->LAYERTAB [ IndexLayer ];
            RectangleCourant != (rdsrec_list *)NULL;
            RectangleCourant  = RectangleCourant->NEXT
          )
      {
        NouveauRectangle = addrdsfigrec ( DrucFigureRdsErreur,
                                          RectangleCourant->NAME,
                                          IndexLayer,
                                          RectangleCourant->X,
                                          RectangleCourant->Y,
                                          RectangleCourant->DX,
                                          RectangleCourant->DY
                                        );

        applyrdssym ( & NouveauRectangle->X,
                      & NouveauRectangle->Y,
                      & NouveauRectangle->DX,
                      & NouveauRectangle->DY,
                      InstanceCourante->X,
                      InstanceCourante->Y,
                      InstanceCourante->TRANSF
                    );

        DrucModifieBboxInstance (   RectangleCourant,
                                  & PositionBboxX,
                                  & PositionBboxY,
                                  & PositionBboxDX,
                                  & PositionBboxDY
                                );
      } /* for tous les rectangles */
    }/* for tous les layers */

    NouveauRectangle = addrdsfigrec ( DrucFigureRdsErreur,
                                      (char *)NULL,
                                      DRUC_BBOX,
                                      PositionBboxX,
                                      PositionBboxY,
                                      PositionBboxDX - PositionBboxX,
                                      PositionBboxDY - PositionBboxY
                                    );
  }/* for toutes les instances */
}

/*------------------------------------------------------------\
|                                                             |
|                         DrucSaveFgureErreur                 |
|                                                             |
\------------------------------------------------------------*/

void DrucSaveFigureErreur ( DrucFigureRdsErreur
                          )
     rdsfig_list *DrucFigureRdsErreur;

{

rdsrec_list *RectangleCourant;
/*\
 * ce n'est pas les abox qui sont en violation 
 * ce sont les BBOX 
 * d'ou on laisse le layer USER2 
 * ca doit etre indique dans la doc

  DrucFigureRdsErreur->LAYERTAB [ RDS_ABOX ] =
     DrucFigureRdsErreur->LAYERTAB [ DRUC_BBOX ]; 

  DrucFigureRdsErreur->LAYERTAB [ DRUC_BBOX ] = ( rdsrec_list *)NULL;;

  for ( RectangleCourant  = DrucFigureRdsErreur->LAYERTAB [ RDS_ABOX ];
        RectangleCourant != (rdsrec_list *)NULL;
        RectangleCourant  = RectangleCourant->NEXT
      )
  {
    SetRdsLayer ( RectangleCourant,
                  RDS_ABOX
                );
  }

  DrucDelLayer     ( DrucFigureRdsErreur,
                     RDS_USER0
                   );
  DrucDelLayer     ( DrucFigureRdsErreur,
                     RDS_USER1
                   );
  DrucDelLayer     ( DrucFigureRdsErreur,
                     RDS_USER2
                   );
viewrdsfig ( DrucFigureRdsErreur
           );
\*/
  saverdsfig       ( DrucFigureRdsErreur
                   );
}
/*------------------------------------------------------------\
|                                                             |
|                         DrucBloc                            |
|                                                             |
\------------------------------------------------------------*/

void DrucBloc ( DrucFigureName ,
                DrucRuleFileName
              )
char *DrucFigureName;
char *DrucRuleFileName;

{

extern DrucTypeStructRdsLayer  DrucStructRdsLayer[];
rdswindow                 *DrucRdsWindow;
DrucTypeStructInstruction *DrucTabInstruction = ( DrucTypeStructInstruction *)NULL;
phfig_list                *DrucFigureMbk;
rdsfig_list               *DrucFigureRds;
rdsins_list               *InstanceCourante;
rdsfig_list               *InstanceModele;
char                      *TmpName;
char                      *DrucErrorName;
char                      *DrucCouronneName;
int                        DrucNombreInstructions;

  DrucFigureMbk = getphfig ( DrucFigureName,
                             'A'
                           );

  if ( incatalog ( DrucFigureName) ||
       DrucStructStat.FLAG_FLATTEN_MODE == DRUC_FLATTEN 
     )
  {
    DrucViewString ( "Flatten DRC on: "
                   );
    DrucViewString ( DrucFigureName
                   );
    DrucViewString ( "\n"
                   );
    rflattenphfig ( DrucFigureMbk,
                    YES,
                    NO
                  );
    
    DrucFigureRds = figmbkrds ( DrucFigureMbk,
                                MACRO_PLUS_TAILLE,
                                0
                              );

    DrucViewString      ( "Delete MBK figure : "
                        );
    DrucViewString      ( DrucFigureName 
                        );
    DrucViewString      ( "\n"
                        );
    delphfig            ( DrucFigureName
                        );
    DrucViewString      ( "Load Flatten Rules : "
                        );
    DrucViewString      ( RDS_TECHNO_NAME
                        );
    DrucViewString      ( "\n"
                        );
       
    DrucNombreInstructions = DrucInitInstruction (   DrucRuleFileName,
                                                   & DrucTabInstruction
                                               );
    DrucViewString      ( "Unify : "
                        );
    DrucViewString      ( DrucFigureName
                        );
    DrucViewString      ( "\n"
                        );
    DrucUnifyFigure     (   DrucFigureRds,
                            DrucStructRdsLayer
                        );

    DrucRdsWindow    = buildrdswindow ( DrucFigureRds
                                      );

    DrucComputeEquiFigure ( DrucFigureRds
                          );
  }
  else
  {
/*\
 *  le bloc n'est pas dans le catalogue alors on fait sa verification hierarchique
\*/
    DrucViewString      ( "Hierarchical DRC on : "
                        );
    DrucViewString      ( DrucFigureName
                        );
    DrucViewString      ( "\n"
                        );
       
    DrucFigureRds = figmbkrds ( DrucFigureMbk,
                                MACRO_PLUS_TAILLE,
                                0
                              );

    if ( DrucFigureRds->LAYERTAB [ DRUC_BBOX ]
        != (rdsrec_list *)NULL 
       )
    {
      delrdsfigrec ( DrucFigureRds,
                     DrucFigureRds->LAYERTAB [ DRUC_BBOX ]
                   );
    }
 
    DrucViewString      ( "Delete MBK figure : "
                        );
    DrucViewString      ( DrucFigureName 
                        );
    DrucViewString      ( "\n"
                        );
    delphfig            ( DrucFigureName
                        );

    for ( InstanceCourante  = DrucFigureRds->INSTANCE;
          InstanceCourante != (rdsins_list *)NULL;
          InstanceCourante  = InstanceCourante->NEXT
        )
    {
/*\
 *  pour toutes les instances de la figure lancer la verif hierarchique
\*/
      TmpName = DrucAddSuffixeName ( InstanceCourante->FIGNAME,
                                     DRUC_COURONNE_EXTEND
                                   );

      InstanceModele = searchrdsfig ( TmpName
                                    );
/*\
 *  si la couronne de l'instance n'exite pas lancer la verif hierarchique
\*/
      if ( InstanceModele == ( rdsfig_list *)NULL
         )
      {
        DrucBloc ( InstanceCourante->FIGNAME,
                   DrucRuleFileName
                 );
      }
    }
    DrucViewString      ( "Load Hierarchical Rules"
                        );
    DrucViewString      ( "\n"
                        );
       
    DrucNombreInstructions = DrucInitInstruction (   DrucRuleFileName,
                                                   & DrucTabInstruction
                                                 );

    DrucViewString           ( "Unify : "
                             );
    DrucViewString           ( DrucFigureName
                             );
    DrucViewString           ( "\n"
                             );
    DrucUnifyFigure          (   DrucFigureRds,
                                 DrucStructRdsLayer
                             );
    DrucFlattenInstanceRings ( DrucFigureRds 
                             );

    InstanceCourante        = DrucFigureRds->INSTANCE;
    DrucFigureRds->INSTANCE = (rdsins_list *)NULL;
    DrucRdsWindow           = buildrdswindow ( DrucFigureRds
                                             );
    DrucFigureRds->INSTANCE = InstanceCourante;

    DrucComputeEquiFigure ( DrucFigureRds
                          );
  }/* else */
/*\
 *  la figure RDS est chargee soit a plat soit avec ses couronnes on n'a plus besoin de MBK
\*/
  DrucCouronneName = DrucAddSuffixeName ( DrucFigureName,
                                          DRUC_COURONNE_EXTEND
                                        );

  DrucViewString      ( "Create Ring : "
                      );
  DrucViewString      ( DrucCouronneName
                      );
  DrucViewString      ( "\n"
                      );
  DrucCreateCouron    ( DrucFigureRds,
                        DrucRdsWindow,
                        DrucCouronneName
                      );
/*\
 *  ici se colle la concatenation des fichiers d'erreurs
 *  ici se colle la verification
\*/

  DrucErrorName = DrucAddSuffixeName ( DrucFigureName,
                                       DRUC_ERROR_FILE_SUFFIXE
                                     );

  DrucOpenErrorFile       ( DrucErrorName,
                            "w"
                          );
  DrucConcateneErrorFiles ( DrucFigureRds,
                            DrucErrorFile
                          );
/*\
 *  concatener les figures des erreurs
\*/
  DrucConcateneErrorFigures ( DrucFigureRds,
                              DrucFigureRdsErreur
                            );
/*\
 * envoyer la verif des regles
\*/
  DrucMin ( DrucFigureRds,
            DrucRdsWindow,
            DrucTabInstruction ,
            DrucNombreInstructions
          );

/*\
 * fermer le fichier des erreurs
 * sauver la figure des erreurs
\*/
  DrucSaveFigureErreur ( DrucFigureRdsErreur
                       );
  DrucDelLayer         ( DrucFigureRds,
                         DRUC_BBOX
                       );
  DrucDelLayer         ( DrucFigureRds,
                         RDS_USER0
                       );
  DrucDelLayer         ( DrucFigureRds,
                         RDS_USER1
                       );
  DrucDelLayer         ( DrucFigureRds,
                         RDS_USER2
                       );
  InstanceCourante        = DrucFigureRds->INSTANCE;
  DrucFigureRds->INSTANCE = (rdsins_list *)NULL;


  DrucFigureRds->INSTANCE = InstanceCourante;
/*\
\*/
  DrucFigureRds->INSTANCE = (rdsins_list *)NULL;
 
  destroyrdswindow   ( DrucFigureRds,
                       DrucRdsWindow
                     );
  delrdsfig          ( DrucFigureName
                     ); 
  DrucViewString     ( "End DRC on: "
                     );
  DrucViewString     ( DrucFigureName 
                     );
  DrucViewString     ( "\n"
                     );
  DrucCloseErrorFile (
                     );
}

/*------------------------------------------------------------\
|                                                             |
|                             Main                            |
|                                                             |
\------------------------------------------------------------*/
void main (argc , argv )
     int   argc;
     char *argv[];
{
phfig_list                *DrucFigureMbk;
rdsfig_list               *DrucFigureRds;
rdswindow                 *DrucRdsWindow;
char                      *Name;
char                      *DrucFigureName;
char                      *DrucErrorName           = (char *)NULL;
char                      *DrucCouronneRdsName;
char                      *DrucRuleFileName        ; /* = DRUC_TMP_OUTPUT_NAME; */
char                      *DrucNetworkName;
DrucTypeStructInstruction *DrucTabInstruction      = ( DrucTypeStructInstruction *)NULL;
int                        DrucNombreInstructions;
int                        IndexLayer;
int                        Resultat;

/*\
 *  lecture des parametres d'entree
\*/
  if ( argc != 2 
     )
  {
    printf       ( "Usage : %s figure_name (without extention)\n",argv [0]
                 );
    exit         ( 1
                 );
  }

  DrucStatInit   ( DRUC_FLATTEN,
                   DRUC_VERBOSE,
                   DRUC_ERROR_FILE
                 );

/*\
 *  affichage de la banniere standard
\*/
  alliancebanner ( "DRuC", 
                    VERSION, 
                   "Design Rule Checker", 
                   "1993", 
                    ALLIANCE_VERSION
                 );

  Name           = argv [ 1 ];

  DrucFigureName = namealloc ( Name 
                             );
  Name           = malloc ( strlen ( DrucFigureName )    +
                            strlen ( DRUC_ERROR_EXTEND) +
                            1
                 );

  strcpy         ( Name ,
                   DrucFigureName
                 );
  strcat         ( Name,
                   DRUC_ERROR_EXTEND
                 );
  DrucErrorName = namealloc ( Name );
  free           ( Name
                 );
  mbkenv         (
                 );
  rdsenv         (
                 );
  loadrdsparam   (
                 );
/*\
 *  creer la figure des erreurs locale
\*/
  DrucFigureRdsErreur    = addrdsfig ( DrucErrorName,
                                       MACRO_PLUS_TAILLE
                                     );

  DrucBloc       ( DrucFigureName,
                   RDS_TECHNO_NAME
                 );
  DrucViewString ( "Saving the Error file figure\n"
                 );
  DrucDelLayer   ( DrucFigureRdsErreur,
                   DRUC_BBOX 
                 );
  DrucViewString ( "Done\n"
                 );
  DrucViewNumber   ( DrucStructStat.ERROR_NUMBER
                   );
  DrucViewString   ( "\n"
                   );

  if ( DrucStructStat.ERROR_NUMBER == 0
     )
  {
    fprintf ( stdout,
              "\nFile: %s%s is empty: no errors detected.\n",
              DrucFigureName,
              namealloc ( DRUC_ERROR_FILE_SUFFIXE
                        )
            );
  }
  else
  {
    fprintf ( stdout,
              "\nSome errors have been detected, see file: %s%s for detailled\n",
              DrucFigureName,
              namealloc ( DRUC_ERROR_FILE_SUFFIXE
                        )
            );
  }
  exit      ( DrucStructStat.ERROR_NUMBER
            );
}



