/*------------------------------------------------------------\
|                                                             |
| Tool    :                     DRUC                          |
|                                                             |
| File    :                  DRUCHIER.C                       |
|                                                             |
| Authors :                Patrick Renaud                     |
|                                                             |
| Date    :                   11/01/94                        |
|                                                             |
\------------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <malloc.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 "druchier.h"
/*------------------------------------------------------------\
|                                                             |
|                         DRUCRING Constantes                 |
|                                                             |
\------------------------------------------------------------*/
/*\
 *  tableau des equivalences layer <-> transparences
\*/
DrucTypeStructLayerEquiv TableauEquivalence [ ] =
                         {
                           { RDS_ALU1 , RDS_TALU1 },
                           { RDS_ALU2 , RDS_TALU2 },
                           { RDS_ALU3 , RDS_TALU3 },
                           { RDS_POLY , RDS_TPOLY }
                         };
#define DRUC_MAX_TRANSPARENCES                               4
/*------------------------------------------------------------\
|                                                             |
|                  DRUCHIER  variables                        |
|                                                             |
\------------------------------------------------------------*/
extern long DrucCtmMax;

static char DrucFileBuffer [ DRUC_MAX_FILE_BUFFER + 1 ];

/*------------------------------------------------------------\
|                                                             |
|                  DRUCHIER  Fonctions                        |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                  DrucAsTransparenceEquivalent               |
|                                                             |
\------------------------------------------------------------*/
int DrucAsTransparenceEquivalent ( LayerInitial 
                                 )
    int LayerInitial;
{
int IndexTransp;

  for ( IndexTransp  = 0;
        IndexTransp  < DRUC_MAX_TRANSPARENCES;
        IndexTransp ++
      )
  {
    if ( ( ( TableauEquivalence [ IndexTransp ] ).LAYER_INDEX ) == 
         LayerInitial 
       )
    {
      return ( ( TableauEquivalence [ IndexTransp ] ).LAYER_TRANSPARENCE ); 
    }
  }
/*\
 * erreur l'appelant a trouve une transparence et la on ne l'a pas trouve
\*/
  return ( DRUC_UNDEFINED_LAYER );
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucInitialiseRegle                        |
|                                                             |
\------------------------------------------------------------*/
void DrucInitialiseRegle ( DrucStructInstruction
                         )
DrucTypeStructInstruction *DrucStructInstruction;
{
int IndexMesure;

  DrucStructInstruction->NEXT        = ( DrucTypeStructInstruction *)NULL;
  DrucStructInstruction->INSTRUCTION =   DRUC_UNDEFINED_INSTRUCTION;
  DrucStructInstruction->LAYER_DEST  =   DRUC_UNDEFINED_LAYER;
  DrucStructInstruction->LAYER_1     =   DRUC_UNDEFINED_LAYER;;
  DrucStructInstruction->LAYER_2     =   DRUC_UNDEFINED_LAYER;;
  DrucStructInstruction->OP_COMPOSE  =   DRUC_UNDEFINED_OPERATEUR;
  for ( IndexMesure = 0;
        IndexMesure < DRUC_MAX_MESURES;
        IndexMesure ++
      )
  {
    DrucStructInstruction->REGLE_NUM  [ IndexMesure ] = DRUC_UNDEFINED_REGLE;
    DrucStructInstruction->RELATION   [ IndexMesure ] = DRUC_UNDEFINED_RELATION;
    DrucStructInstruction->MESURE     [ IndexMesure ] = DRUC_UNDEFINED_MESURE;
    DrucStructInstruction->OP_COMPARE [ IndexMesure ] = DRUC_UNDEFINED_OPERATEUR;
    DrucStructInstruction->VALEUR     [ IndexMesure ] =DRUC_UNDEFINED_VALEUR;
  }
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucAddHierarchicalRules                   |
|                                                             |
\------------------------------------------------------------*/
void DrucAddHierarchicalRules ( DrucStructInstruction,
                                DrucNombreInstructions
                              )
DrucTypeStructInstruction **DrucStructInstruction;
int                        *DrucNombreInstructions;
{
DrucTypeStructInstruction *TmpStructInstruction;
int                        InstructionAddNumber ;
int                        IndexMesure;

InstructionAddNumber = DRUC_BEGIN_ADD_INSTRUCTION;
  TmpStructInstruction =
    ( DrucTypeStructInstruction *)malloc (sizeof ( DrucTypeStructInstruction ));
  if (TmpStructInstruction == (DrucTypeStructInstruction *)NULL )
  {
    DRUC_EXIT ( DRUC_ERROR_MEMOIRE );
  }
  DrucInitialiseRegle ( TmpStructInstruction
                       );
  TmpStructInstruction->NEXT        =  *DrucStructInstruction;
  TmpStructInstruction->INSTRUCTION =   DRUC_ASM_BEGIN_REGLE;
  TmpStructInstruction->LAYER_DEST  =   DRUC_UNDEFINED_LAYER;
  TmpStructInstruction->LAYER_1     =   DRUC_BBOX;
  TmpStructInstruction->LAYER_2     =   DRUC_BBOX;
  TmpStructInstruction->OP_COMPOSE  =   DRUC_INSTR_RELATION;

  for ( IndexMesure = 0;
        IndexMesure < 6;
        IndexMesure ++
      )
  {
    TmpStructInstruction->REGLE_NUM  [ IndexMesure ] = InstructionAddNumber ++;
  }
  TmpStructInstruction->RELATION   [ 0 ] = DRUC_RELATION_ENVELOPPE; 
  TmpStructInstruction->MESURE     [ 0 ] = DRUC_MESURE_LARGEUR_INTER;
  TmpStructInstruction->OP_COMPARE [ 0 ] = DRUC_OPERATION_INF;
  TmpStructInstruction->VALEUR     [ 0 ] = 0;
  TmpStructInstruction->RELATION   [ 1 ] = DRUC_RELATION_MARGE; 
  TmpStructInstruction->MESURE     [ 1 ] = DRUC_MESURE_PENETRE_INTER;
  TmpStructInstruction->OP_COMPARE [ 1 ] = DRUC_OPERATION_INF;
  TmpStructInstruction->VALEUR     [ 1 ] = DrucCtmMax;
  TmpStructInstruction->RELATION   [ 2 ] = DRUC_RELATION_CROIX; 
  TmpStructInstruction->MESURE     [ 2 ] = DRUC_MESURE_LARGEUR_INTER;
  TmpStructInstruction->OP_COMPARE [ 2 ] = DRUC_OPERATION_INF;
  TmpStructInstruction->VALEUR     [ 2 ] = 0;
  TmpStructInstruction->RELATION   [ 3 ] = DRUC_RELATION_INTERSECTION; 
  TmpStructInstruction->MESURE     [ 3 ] = DRUC_MESURE_LARGEUR_INTER;
  TmpStructInstruction->OP_COMPARE [ 3 ] = DRUC_OPERATION_INF;
  TmpStructInstruction->VALEUR     [ 3 ] = DrucCtmMax;
  TmpStructInstruction->RELATION   [ 4 ] = DRUC_RELATION_EXTENSION; 
  TmpStructInstruction->MESURE     [ 4 ] = DRUC_MESURE_PENETRE_INTER;
  TmpStructInstruction->OP_COMPARE [ 4 ] = DRUC_OPERATION_INF;
  TmpStructInstruction->VALEUR     [ 4 ] = DrucCtmMax;
  TmpStructInstruction->RELATION   [ 5 ] = DRUC_RELATION_INCLUSION; 
  TmpStructInstruction->MESURE     [ 5 ] = DRUC_MESURE_LARGEUR_INTER;
  TmpStructInstruction->OP_COMPARE [ 5 ] = DRUC_OPERATION_INF;
  TmpStructInstruction->VALEUR     [ 5 ] = 0;
  *DrucStructInstruction                 = TmpStructInstruction;
  (*DrucNombreInstructions) ++;
}
/*------------------------------------------------------------\
|                                                             |
|                  DrucDuplicateHierarchicalRule              |
|                                                             |
\------------------------------------------------------------*/
void DrucDuplicateHierarchicalRule ( DrucStructInstruction,
                                     DrucNombreInstructions
                                   )
DrucTypeStructInstruction **DrucStructInstruction;
int                        *DrucNombreInstructions;
{
DrucTypeStructInstruction *TmpStructInstruction;
int                        LayerTransparent;
int                        LayerTransparent2;
int                        IndexMesure;
int                        LayerSource;
int                        LayerSource2;

/*\
 *  duplication des regles pour le premier layer
\*/
  LayerSource       = (*DrucStructInstruction)->LAYER_1 ;
  LayerSource2      = (*DrucStructInstruction)->LAYER_2 ;
  LayerTransparent  = DrucAsTransparenceEquivalent ( LayerSource );
  LayerTransparent2 = DrucAsTransparenceEquivalent ( LayerSource2 );
  if ( LayerTransparent != DRUC_UNDEFINED_LAYER )
  { 
    TmpStructInstruction = 
    ( DrucTypeStructInstruction *)malloc (sizeof ( DrucTypeStructInstruction ));
    if (TmpStructInstruction == (DrucTypeStructInstruction *)NULL )
    {
      DRUC_EXIT ( DRUC_ERROR_MEMOIRE );
    }
    DrucInitialiseRegle ( TmpStructInstruction
                         );
    TmpStructInstruction->NEXT        =  *DrucStructInstruction;
    TmpStructInstruction->INSTRUCTION = (*DrucStructInstruction)->INSTRUCTION;
    TmpStructInstruction->LAYER_DEST  = (*DrucStructInstruction)->LAYER_DEST;
    TmpStructInstruction->LAYER_1     =   LayerTransparent;
    TmpStructInstruction->LAYER_2     =   LayerSource2;
    TmpStructInstruction->OP_COMPOSE  = (*DrucStructInstruction)->OP_COMPOSE;

    DrucStructRdsLayer [ LayerTransparent ].RDS_INDEX = LayerTransparent;
    DrucStructRdsLayer [ LayerTransparent ].WIDTH     = 
         ( DrucStructRdsLayer [ LayerSource ] ).WIDTH;
    DrucStructRdsLayer [ LayerTransparent ].CTM       = 
         ( DrucStructRdsLayer [ LayerSource ] ).CTM;

    for ( IndexMesure = 0;
          IndexMesure < DRUC_MAX_MESURES;
          IndexMesure ++
        )
    {
      if ( ( (*DrucStructInstruction)->REGLE_NUM [ IndexMesure ] ) 
           != DRUC_UNDEFINED_REGLE
         )
      {
        TmpStructInstruction->REGLE_NUM  [ IndexMesure ] =
          ( (*DrucStructInstruction)->REGLE_NUM [ IndexMesure ] ) + 
          DRUC_MAX_REGLES;
        TmpStructInstruction->RELATION   [ IndexMesure ] =
          (*DrucStructInstruction)->RELATION [ IndexMesure ] ;
        TmpStructInstruction->MESURE     [ IndexMesure ] =
          (*DrucStructInstruction)->MESURE [ IndexMesure] ;
        TmpStructInstruction->OP_COMPARE [ IndexMesure ] = 
          (*DrucStructInstruction)->OP_COMPARE [ IndexMesure ] ;
        TmpStructInstruction->VALEUR     [ IndexMesure ] =
          (*DrucStructInstruction)->VALEUR [ IndexMesure] ;
      }
    }
    *DrucStructInstruction             = TmpStructInstruction;
    (*DrucNombreInstructions) ++;
  }
/*\
 *  duplication des regles pour le deuxieme layer
\*/
  if ( LayerTransparent2 != DRUC_UNDEFINED_LAYER )
  { 
    TmpStructInstruction = 
    ( DrucTypeStructInstruction *)malloc (sizeof ( DrucTypeStructInstruction ));
    if (TmpStructInstruction == (DrucTypeStructInstruction *)NULL )
    {
      DRUC_EXIT ( DRUC_ERROR_MEMOIRE );
    }
    DrucInitialiseRegle ( TmpStructInstruction
                         );
    TmpStructInstruction->NEXT        =  *DrucStructInstruction;
    TmpStructInstruction->INSTRUCTION = (*DrucStructInstruction)->INSTRUCTION;
    TmpStructInstruction->LAYER_DEST  = (*DrucStructInstruction)->LAYER_DEST;
    TmpStructInstruction->LAYER_1     =   LayerSource;
    TmpStructInstruction->LAYER_2     =   LayerTransparent2;
    TmpStructInstruction->OP_COMPOSE  = (*DrucStructInstruction)->OP_COMPOSE;

    DrucStructRdsLayer [ LayerTransparent2 ].RDS_INDEX = LayerTransparent2;
    DrucStructRdsLayer [ LayerTransparent2 ].WIDTH     = 
         ( DrucStructRdsLayer [ LayerSource2 ] ).WIDTH;
    DrucStructRdsLayer [ LayerTransparent2 ].CTM       = 
         ( DrucStructRdsLayer [ LayerSource2 ] ).CTM;

    for ( IndexMesure = 0;
          IndexMesure < DRUC_MAX_MESURES;
          IndexMesure ++
        )
    {
      if ( ( (*DrucStructInstruction)->REGLE_NUM [ IndexMesure ] ) 
           != DRUC_UNDEFINED_REGLE
         )
      {
        TmpStructInstruction->REGLE_NUM  [ IndexMesure ] =
          ( (*DrucStructInstruction)->REGLE_NUM [ IndexMesure ] ) + 
          DRUC_MAX_REGLES;
        TmpStructInstruction->RELATION   [ IndexMesure ] =
          (*DrucStructInstruction)->RELATION [ IndexMesure ] ;
        TmpStructInstruction->MESURE     [ IndexMesure ] =
          (*DrucStructInstruction)->MESURE [ IndexMesure] ;
        TmpStructInstruction->OP_COMPARE [ IndexMesure ] = 
          (*DrucStructInstruction)->OP_COMPARE [ IndexMesure ] ;
        TmpStructInstruction->VALEUR     [ IndexMesure ] =
          (*DrucStructInstruction)->VALEUR [ IndexMesure] ;
      }
    }
    *DrucStructInstruction             = TmpStructInstruction;
    (*DrucNombreInstructions) ++;
  }
/*\
 *  duplication des regles pour les deux layers en meme temps
\*/
  if ( ( LayerTransparent  != DRUC_UNDEFINED_LAYER ) &&
       ( LayerTransparent2 != DRUC_UNDEFINED_LAYER )
     )
  {
    TmpStructInstruction =
    ( DrucTypeStructInstruction *)malloc (sizeof ( DrucTypeStructInstruction ));
    if (TmpStructInstruction == (DrucTypeStructInstruction *)NULL )
    {
      DRUC_EXIT ( DRUC_ERROR_MEMOIRE );
    }
    DrucInitialiseRegle ( TmpStructInstruction
                         );
    TmpStructInstruction->NEXT        =  *DrucStructInstruction;
    TmpStructInstruction->INSTRUCTION = (*DrucStructInstruction)->INSTRUCTION;
    TmpStructInstruction->LAYER_DEST  = (*DrucStructInstruction)->LAYER_DEST;
    TmpStructInstruction->LAYER_1     =   LayerTransparent;
    TmpStructInstruction->LAYER_2     =   LayerTransparent2;
    TmpStructInstruction->OP_COMPOSE  = (*DrucStructInstruction)->OP_COMPOSE;

    DrucStructRdsLayer [ LayerTransparent ].RDS_INDEX = LayerTransparent;
    DrucStructRdsLayer [ LayerTransparent ].WIDTH     =
         ( DrucStructRdsLayer [ LayerSource ] ).WIDTH;
    DrucStructRdsLayer [ LayerTransparent ].CTM       =
         ( DrucStructRdsLayer [ LayerSource ] ).CTM;

    DrucStructRdsLayer [ LayerTransparent2 ].RDS_INDEX = LayerTransparent2;
    DrucStructRdsLayer [ LayerTransparent2 ].WIDTH     = 
         ( DrucStructRdsLayer [ LayerSource2 ] ).WIDTH;
    DrucStructRdsLayer [ LayerTransparent2 ].CTM       = 
         ( DrucStructRdsLayer [ LayerSource2 ] ).CTM;

    for ( IndexMesure = 0;
          IndexMesure < DRUC_MAX_MESURES;
          IndexMesure ++
        )
    {
      if ( ( (*DrucStructInstruction)->REGLE_NUM [ IndexMesure ] ) 
           != DRUC_UNDEFINED_REGLE
         )
      {
        TmpStructInstruction->REGLE_NUM  [ IndexMesure ] =
          ( (*DrucStructInstruction)->REGLE_NUM [ IndexMesure ] ) +
          DRUC_MAX_REGLES;
        TmpStructInstruction->RELATION   [ IndexMesure ] =
          (*DrucStructInstruction)->RELATION [ IndexMesure ] ;
        TmpStructInstruction->MESURE     [ IndexMesure ] =
          (*DrucStructInstruction)->MESURE [ IndexMesure] ;
        TmpStructInstruction->OP_COMPARE [ IndexMesure ] =
          (*DrucStructInstruction)->OP_COMPARE [ IndexMesure ] ;
        TmpStructInstruction->VALEUR     [ IndexMesure ] =
          (*DrucStructInstruction)->VALEUR [ IndexMesure] ;
      }
    }
    *DrucStructInstruction             = TmpStructInstruction;
    (*DrucNombreInstructions) ++;
  }
}
