/*------------------------------------------------------------\
|                                                             |
| Tool    :                    DRUC                           |
|                                                             |
| File    :                  DRUCRING.C                       |
|                                                             |
| Authors :                Renaud Patrick                     |
|                                                             |
| Date    :                   11/01/94                        |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
| |                                                           |
|                         Include Files                       |
|                                                             |
\------------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.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 "druchier.h"
#include "drucring.h"
/*------------------------------------------------------------\ 
|                                                             |
|                         DRUCRING Variables                  |
|                                                             |
\------------------------------------------------------------*/ 
extern long DrucCtmMax; 
/*------------------------------------------------------------\ 
|                                                             |
|                         DRUCRING Fonctions                  |
|                                                             |
\------------------------------------------------------------*/ 
/*------------------------------------------------------------\
|                                                             |
|                          DrucDelLayer                       |
|                                                             |
\------------------------------------------------------------*/
void DrucDelLayer ( DrucFigureRds,
                    DeleteLayer
                  )
     rdsfig_list *DrucFigureRds;
     int          DeleteLayer;
{
rdsrec_list *TmpRectangle;

  while ( DrucFigureRds->LAYERTAB [ DeleteLayer ] != ( rdsrec_list *)NULL
        )
  {
    TmpRectangle = DrucFigureRds->LAYERTAB [ DeleteLayer ];
    DrucFigureRds->LAYERTAB [ DeleteLayer ] = TmpRectangle->NEXT;
    freerdsrec ( TmpRectangle,
                 MACRO_PLUS_TAILLE
               );
  }
}
/*------------------------------------------------------------\
|                                                             |
|                          DrucModifieBboxInstance            |
|                                                             |
\------------------------------------------------------------*/
void      DrucModifieBboxInstance ( RectangleCourant,
                                    PositionBboxX,
                                    PositionBboxY,
                                    PositionBboxDX,
                                    PositionBboxDY
                                  )
rdsrec_list    *RectangleCourant;
long           *PositionBboxX;
long           *PositionBboxY;
long           *PositionBboxDX;
long           *PositionBboxDY;

{
  *PositionBboxX  = ( *PositionBboxX < RectangleCourant->X ?
                      *PositionBboxX :
                       RectangleCourant->X
                    );
  *PositionBboxY =  ( *PositionBboxY < RectangleCourant->Y ?
                      *PositionBboxY :
                       RectangleCourant->Y
                    );
  *PositionBboxDX = ( *PositionBboxDX > ( RectangleCourant->X + 
                                          RectangleCourant->DX  ) ?
                      *PositionBboxDX :
                       ( RectangleCourant->X + 
                         RectangleCourant->DX  )
                    );
  *PositionBboxDY = ( *PositionBboxDY > ( RectangleCourant->Y +
                                          RectangleCourant->DY  ) ?
                      *PositionBboxDY :
                       ( RectangleCourant->Y +
                         RectangleCourant->DY  )
                    );
}
/*------------------------------------------------------------\ 
|                                                             |
|                         DrucFlattenInstanceRings            |
|                                                             |
\------------------------------------------------------------*/ 
void DrucFlattenInstanceRings ( DrucFigureRds
                              )
     rdsfig_list *DrucFigureRds;
{
rdsfig_list               *InstanceModele;
rdsins_list               *InstanceCourante;
long                       PositionBboxX;
long                       PositionBboxY;
long                       PositionBboxDX;
long                       PositionBboxDY;
int                        IndexLayer;
char                      *TmpName;
char                      *savName;
char                      *brico = "a";
rdsrec_list               *RectangleCourant;
rdsrec_list               *NouveauRectangle;
boolean                    InitBbox;

DrucViewString ("Flatten Instance Rings:");
    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_COURONNE_EXTEND
                                   );
DrucViewString (TmpName);
      InstanceModele = searchrdsfig( TmpName
                                   );
      InitBbox = DRUC_FALSE;

      for ( IndexLayer  = 0;
            IndexLayer  < RDS_MAX_LAYER;
            IndexLayer ++
          )
      {
        if ( ( IndexLayer == DRUC_BBOX ) ||
             ( IndexLayer == RDS_ABOX  ) ||
             ( IndexLayer == RDS_USER0 ) ||
             ( IndexLayer == RDS_USER1 ) ||
             ( IndexLayer == RDS_USER2 )
           )
        {
          continue;
        }
        for ( RectangleCourant  = InstanceModele->LAYERTAB [ IndexLayer ];
              RectangleCourant != (rdsrec_list *)NULL;
              RectangleCourant  = RectangleCourant->NEXT
            )
        {
          NouveauRectangle = addrdsfigrec ( DrucFigureRds,
				            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
                      );
          MACRO_INSTANCE_NUM ( NouveauRectangle ) = InstanceCourante;
if ( InitBbox == DRUC_FALSE 
   )
{
      PositionBboxX  = NouveauRectangle->X;
      PositionBboxY  = NouveauRectangle->Y;
      PositionBboxDX = NouveauRectangle->X + NouveauRectangle->DX;
      PositionBboxDY = NouveauRectangle->Y + NouveauRectangle->DY;
      InitBbox = DRUC_TRUE;
}
          DrucModifieBboxInstance (   NouveauRectangle,
                                    & PositionBboxX,
                                    & PositionBboxY,
                                    & PositionBboxDX,
                                    & PositionBboxDY
                                  );
        } 
      }/* for tous les layers */
      NouveauRectangle = addrdsfigrec ( DrucFigureRds,
			                (char *)NULL,
			                DRUC_BBOX,
			                PositionBboxX,
			                PositionBboxY,
			                PositionBboxDX - PositionBboxX,
			                PositionBboxDY - PositionBboxY
			              );
      MACRO_INSTANCE_NUM (NouveauRectangle ) = InstanceCourante;
    }/* for toutes les instances */
}
/*------------------------------------------------------------\
|                                                             |
|                          DrucIsLayerTransparence            |
|                                                             |
\------------------------------------------------------------*/
boolean DrucIsLayerTransparence ( IndexLayer 
                                )
        int IndexLayer;
{
int IndexTableau;

  for ( IndexTableau  = 0;
        IndexTableau  < DRUC_MAX_TRANSPARENCES;
        IndexTableau ++
      )
  {
    if ( IndexLayer == ( TableauEquivalence [ IndexTableau ] ).LAYER_TRANSPARENCE
       )
    {
      return DRUC_TRUE;
    }
  }
  return DRUC_FALSE;
}
/*------------------------------------------------------------\
|                                                             |
|                          DrucCreateRectangleInCouronne      |
|                                                             |
\------------------------------------------------------------*/
void DrucCreateRectangleInCouronne ( DrucCouronneRds,
                                     IndexLayer,
                                     RectangleCourant,
                                     PositionInterneCouronneX,
                                     PositionInterneCouronneY,
                                     PositionInterneCouronneDX,
                                     PositionInterneCouronneDY
                                   )
    rdsfig_list *DrucCouronneRds;
    int          IndexLayer;
    rdsrec_list *RectangleCourant;
    long         PositionInterneCouronneX;
    long         PositionInterneCouronneY;
    long         PositionInterneCouronneDX;
    long         PositionInterneCouronneDY;

{
rdsrec_list     *RectangleDest;
      /*\
       *  si le rectangle est en contact avec la couronne
      \*/
      if ( ( RectangleCourant->X                        <= 
             PositionInterneCouronneX  )                   ||
           ( RectangleCourant->Y                        <= 
             PositionInterneCouronneY  )                   ||
           ( RectangleCourant->X + RectangleCourant->DX >= 
             PositionInterneCouronneDX )                   ||
           ( RectangleCourant->Y + RectangleCourant->DY >= 
             PositionInterneCouronneDY ) 
         )
      {
      /*\
       *  creer un nouveau rectangle, 
       *  l'inserer dans la figure couronne sur son layer
      \*/
        RectangleDest    = addrdsfigrec ( DrucCouronneRds,
                                          RectangleCourant->NAME,
                                          IndexLayer,
                                          RectangleCourant->X,
                                          RectangleCourant->Y,
                                          RectangleCourant->DX,
                                          RectangleCourant->DY
                                        );
  }
} 

/*------------------------------------------------------------\
|                                                             |
|                          DrucCreateCouron                   |
|                                                             |
\------------------------------------------------------------*/
void DrucCreateCouron ( DrucFigureRds,
                        DrucRdsWindow,
                        DrucCouronneName
                      )
rdsfig_list         *DrucFigureRds;
rdswindow           *DrucRdsWindow;
char                *DrucCouronneName;
{
rdsfig_list         *DrucCouronneRds;
rdsrec_list         *RectangleCourant;
long                 IndexLayer;
long                 PositionInterneCouronneX;
long                 PositionInterneCouronneY;
long                 PositionInterneCouronneDX;
long                 PositionInterneCouronneDY;

  /*\
   *  calculer les positions de la couronne interne
  \*/
  DrucCouronneRds           = addrdsfig ( DrucCouronneName,
                                          MACRO_PLUS_TAILLE
                                        );
  for ( IndexLayer  = 0;
        IndexLayer  < RDS_MAX_LAYER;
        IndexLayer ++
      )
  {
    /*\
     * on ne remonte pas les layers user ni l'ABOX ni les BBOX des instances
    \*/
    if ( ( IndexLayer == DRUC_BBOX ) ||
         ( IndexLayer == RDS_ABOX  ) ||
         ( IndexLayer == RDS_USER0 ) ||
         ( IndexLayer == RDS_USER1 ) ||
         ( IndexLayer == RDS_USER2 )
       )
    {
      continue;
    } 
    PositionInterneCouronneX  = ( DrucRdsWindow->XMIN + 
                                  DrucCtmMax + 
                                  DrucStructRdsLayer[ IndexLayer ].CTM
                                );
    PositionInterneCouronneDX = ( DrucRdsWindow->XMAX - 
                                  DrucCtmMax - 
                                  DrucStructRdsLayer[ IndexLayer ].CTM
                                );
    PositionInterneCouronneY  = ( DrucRdsWindow->YMIN + 
                                  DrucCtmMax + 
                                  DrucStructRdsLayer[ IndexLayer ].CTM
                                );
    PositionInterneCouronneDY = ( DrucRdsWindow->YMAX - 
                                  DrucCtmMax - 
                                  DrucStructRdsLayer[ IndexLayer ].CTM
                                );
    if ( DrucIsLayerTransparence ( IndexLayer ) == DRUC_TRUE
       )
    {
    /*\
     *  on ne garde que les transparences du bloc (pere)
    \*/
      for ( RectangleCourant    = DrucFigureRds->LAYERTAB [ IndexLayer ];
            RectangleCourant   != (rdsrec_list *)NULL;
            RectangleCourant    = RectangleCourant->NEXT
          )
      {
        if ( MACRO_INSTANCE_NUM ( RectangleCourant ) == DRUC_BLOC_PERE
           )
        {
          DrucCreateRectangleInCouronne ( DrucCouronneRds,
                                          IndexLayer,
                                          RectangleCourant,
                                          PositionInterneCouronneX,
                                          PositionInterneCouronneY,
                                          PositionInterneCouronneDX,
                                          PositionInterneCouronneDY
                                        );
        }
      }
      continue;
    }
    for ( RectangleCourant    = DrucFigureRds->LAYERTAB [ IndexLayer ];
          RectangleCourant   != (rdsrec_list *)NULL;
          RectangleCourant    = RectangleCourant->NEXT
        )
    {
      DrucCreateRectangleInCouronne ( DrucCouronneRds,
                                      IndexLayer,
                                      RectangleCourant,
                                      PositionInterneCouronneX,
                                      PositionInterneCouronneY,
                                      PositionInterneCouronneDX,
                                      PositionInterneCouronneDY
                                    );
    }
  /*\
   *  sauver la couronne sur disque
  \*/
  }
   saverdsfig ( DrucCouronneRds );
}
