/*------------------------------------------------------------\
|                                                             |
| File    :                   Peek.c                          |
|                                                             |
| Authors :      Venot Frederic and Jacomme Ludovic           |
|                                                             |
| Date    :                  01.08.93                         |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                         Include Files                       |
|                                                             |
\------------------------------------------------------------*/

# include <stdio.h>
# include MUT_H
# include MPH_H
# include RDS_H
# include RPR_H
# include RFM_H
# include GRM_H
# include GSB_H
# include "GRM_peek.h"

/*------------------------------------------------------------\
|                                                             |
|                          Variables                          |
|                                                             |
\------------------------------------------------------------*/

  graalpeek *GraalHeadPeek = (graalpeek *)NULL;

/*------------------------------------------------------------\
|                                                             |
|                          Functions                          |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                       Alloc Functions                       |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                         GraalAllocPeek                     |
|                                                             |
\------------------------------------------------------------*/

   graalpeek *GraalAllocPeek()
   {
     return((graalpeek *)rdsalloc(sizeof(graalpeek), 1));
   }

/*------------------------------------------------------------\
|                                                             |
|                        Free Functions                       |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                          GraalFreePeek                     |
|                                                             |
\------------------------------------------------------------*/
  
  void GraalFreePeek( FreePeek )

     graalpeek *FreePeek;
  {
    rdsfree((char *)FreePeek, sizeof(graalpeek));
  }

/*------------------------------------------------------------\
|                                                             |
|                        GraalAddPeek                        |
|                                                             |
\------------------------------------------------------------*/

  void GraalAddPeek( Rectangle )

     rdsrec_list *Rectangle;
  {
    graalpeek *Peek;

    Peek = GraalAllocPeek();

    Peek->RECTANGLE = Rectangle;
    Peek->NEXT      = GraalHeadPeek;
    GraalHeadPeek   = Peek;

    SetGraalPeek( Rectangle );
  }

/*------------------------------------------------------------\
|                                                             |
|                         GraalDelPeek                        |
|                                                             |
\------------------------------------------------------------*/

  void GraalDelPeek()

  {
    graalpeek    *Peek;
    rdsins_list  *Instance;
    rdsrec_list  *ScanRec;
    rdsrec_list  *DelRec;
    rdsrec_list **Previous;
    char          Layer;

    while ( GraalHeadPeek != (graalpeek *)NULL )
    {
      Peek    = GraalHeadPeek;
      ScanRec = Peek->RECTANGLE;

      ClearGraalPeek( ScanRec );

      Instance = (rdsins_list *)GRAAL_PREVIOUS( ScanRec );

      for ( Layer = 0; Layer < RDS_ABOX; Layer++ )
      {
        Previous = &Instance->LAYERTAB[ Layer ];
        ScanRec  = *Previous;

        while( ScanRec != (rdsrec_list *)NULL )
        {
          DelRec  = ScanRec;
          ScanRec = ScanRec->NEXT;

          if ( IsGraalPeek( DelRec ) )
          {
            *Previous = ScanRec;

            GraalEraseRectangle( DelRec );

            freerdsrec( DelRec, GRAAL_SIZE );
          }
          else
          {
            Previous = &DelRec->NEXT;
          }
        }
      }

      GraalHeadPeek = GraalHeadPeek->NEXT;

      GraalFreePeek( Peek );
    }
  }

/*------------------------------------------------------------\
|                                                             |
|                   Graal Peek Instance                       |
|                                                             |
\------------------------------------------------------------*/

  void GraalPeekInstance( Rectangle, LambdaX1, LambdaY1, LambdaX2, LambdaY2 )

     rdsrec_list *Rectangle;
     long         LambdaX1;
     long         LambdaY1;
     long         LambdaX2;
     long         LambdaY2;
  {
    phfig_list   *ModelMbk;
    phfig_list   *FigureMbk;

    phins_list   *InstanceMbk;
    phins_list   *SourceMbk;
    phins_list  **PreviousMbk;

    rdsfig_list  *FigureRds;
    rdsins_list  *TargetRds;
    rdsrec_list  *ScanRec; 
    rdsrec_list  *DelRec; 
    void         *Pointer;
    void         *Delete;
    long          X1;
    long          Y1;
    long          X2;
    long          Y2;
    long          Xab1;
    long          Yab1;
    long          Xab2;
    long          Yab2;
    long          XabMin;
    long          YabMin;
    long          XabMax;
    long          YabMax;
    long          Swap;
    char          Layer;

    XabMin = LambdaX1 - GRAAL_PEEK_BOUND;
    YabMin = LambdaY1 - GRAAL_PEEK_BOUND;
    XabMax = LambdaX2 + GRAAL_PEEK_BOUND;
    YabMax = LambdaY2 + GRAAL_PEEK_BOUND;
    
    FigureRds   = addrdsfig( "_ludo_", GRAAL_SIZE );
    FigureMbk   = addphfig( "_ludo_"              );
    SourceMbk   = (phins_list  *)GRAAL_MBK( Rectangle );
    TargetRds   = (rdsins_list *)GRAAL_PREVIOUS( Rectangle );

    InstanceMbk = addphins( FigureMbk,
                            SourceMbk->FIGNAME, SourceMbk->INSNAME, 
                            SourceMbk->TRANSF, 
                            SourceMbk->XINS, SourceMbk->YINS );
    do
    {
      Pointer = (void *)

        Graalflattenphfig( FigureMbk, FigureMbk->PHINS->INSNAME, YES );

      if ( Pointer == (void *)NULL ) break;

      Pointer         = (void *)FigureMbk->PHSEG;
      FigureMbk->PHSEG = (phseg_list *)NULL;

      while( Pointer != (void *)NULL )
      {
        Delete  = Pointer;
        Pointer = ((phseg_list *)Pointer)->NEXT;

        segmbkrds( FigureRds, (phseg_list *)Delete );
        mbkfree( Delete );
      }

      Pointer         = (void *)FigureMbk->PHREF;
      FigureMbk->PHREF = (phref_list *)NULL; 
 
      while( Pointer != (void *)NULL ) 
      { 
        Delete  = Pointer;
        Pointer = ((phref_list *)Pointer)->NEXT; 
       
        refmbkrds( FigureRds, (phref_list *)Delete );
        mbkfree( Delete ); 
      }

      Pointer         = (void *)FigureMbk->PHVIA;
      FigureMbk->PHVIA = (phvia_list *)NULL; 
 
      while( Pointer != (void *)NULL ) 
      { 
        Delete  = Pointer;
        Pointer = ((phvia_list *)Pointer)->NEXT; 

        viambkrds( FigureRds, (phvia_list *)Delete );
        mbkfree( Delete ); 
      }

      for ( Layer = 0; Layer < RDS_MAX_LAYER; Layer++ )
      {
        ScanRec = FigureRds->LAYERTAB[ Layer ];

        while ( ScanRec != (rdsrec_list *)NULL )
        {
          DelRec  = ScanRec;
          ScanRec = ScanRec->NEXT;

          X1 = DelRec->X;
          Y1 = DelRec->Y;
          X2 = DelRec->DX + X1;
          Y2 = DelRec->DY + Y1;

          if ( ( X1 < LambdaX2 ) &&
               ( Y1 < LambdaY2 ) &&
               ( X2 > LambdaX1 ) &&
               ( Y2 > LambdaY1 ) )
          {
            SetGraalPeek( DelRec );
            ClearRdsFigRec( DelRec );

            DelRec->NEXT                 = TargetRds->LAYERTAB[ Layer ];
            TargetRds->LAYERTAB[ Layer ] = DelRec;

            GRAAL_MBK( DelRec )      = (void         *)SourceMbk;
            GRAAL_PREVIOUS( DelRec ) = (rdsrec_list **)TargetRds;

            if ( X1 < LambdaX1 ) { X1 = LambdaX1; }
            if ( Y1 < LambdaY1 ) { Y1 = LambdaY1; }
            if ( X2 > LambdaX2 ) { X2 = LambdaX2; }
            if ( Y2 > LambdaY2 ) { Y2 = LambdaY2; }

            DelRec->X    = X1;
            DelRec->Y    = Y1;
            DelRec->DX   = X2 - X1;
            DelRec->DY   = Y2 - Y1;

            GraalInsertRectangle( DelRec );
          }
          else
          {
            freerdsrec( DelRec, GRAAL_SIZE );
          }
        }

        FigureRds->LAYERTAB[ Layer ] = (rdsrec_list *)NULL;
      }

      InstanceMbk = FigureMbk->PHINS;
      PreviousMbk = &FigureMbk->PHINS;

      while( InstanceMbk != (phins_list *)NULL )
      {
        ModelMbk = Graalgetphfig( InstanceMbk->FIGNAME, 'P' );

        if ( ModelMbk != (phfig_list *)NULL )
        {
          xyflat
          ( &Xab1              , &Yab1,
            ModelMbk->XAB1     , ModelMbk->YAB1,
            InstanceMbk->XINS  , InstanceMbk->YINS,
            ModelMbk->XAB1     , ModelMbk->YAB1,
            ModelMbk->XAB2     , ModelMbk->YAB2,
            InstanceMbk->TRANSF
          );
 
          xyflat
          ( &Xab2              , &Yab2,
            ModelMbk->XAB2     , ModelMbk->YAB2,
            InstanceMbk->XINS  , InstanceMbk->YINS,
            ModelMbk->XAB1     , ModelMbk->YAB1,
            ModelMbk->XAB2     , ModelMbk->YAB2,
            InstanceMbk->TRANSF
          );
 
          Xab1 = RfmRoundLow( Xab1 * RDS_LAMBDA / SCALE_X );
          Yab1 = RfmRoundLow( Yab1 * RDS_LAMBDA / SCALE_X );
          Xab2 = RfmRoundHigh( Xab2 * RDS_LAMBDA / SCALE_X );
          Yab2 = RfmRoundHigh( Yab2 * RDS_LAMBDA / SCALE_X );
 
          if ( Xab1 > Xab2 ) { Swap = Xab1; Xab1 = Xab2; Xab2 = Swap; }
          if ( Yab1 > Yab2 ) { Swap = Yab1; Yab1 = Yab2; Yab2 = Swap; }
          
          if ( ( Xab1 < XabMax ) &&
               ( Yab1 < YabMax ) &&
               ( Xab2 > XabMin ) &&
               ( Yab2 > YabMin ) )
          {
            PreviousMbk = &InstanceMbk->NEXT;
            InstanceMbk = InstanceMbk->NEXT;

            continue;
          }
        }

        *PreviousMbk = InstanceMbk->NEXT;
        Delete       = (void *)InstanceMbk;
        InstanceMbk  = InstanceMbk->NEXT;

        mbkfree( Delete );
      }
    }
    while( FigureMbk->PHINS != (phins_list *)NULL );

    delphfig( "_ludo_" );
    delrdsfig( "_ludo_" );
  }
