/*------------------------------------------------------------\
|                                                             |
| Tool    :                   GRAAL                           |
|                                                             |
| File    :                   Edit.c                          |
|                                                             |
| Authors :      Venot Frederic and Jacomme Ludovic           |
|                                                             |
| Date    :                  01.08.93                         |
|                                                             |
\------------------------------------------------------------*/

/*------------------------------------------------------------\
|                                                             |
|                         Include Files                       |
|                                                             |
\------------------------------------------------------------*/

# include <stdio.h>
# include <string.h>
# include <Xm/Xm.h>
# include <Xm/PushBG.h>
# include <Xm/CascadeBG.h>

# include MUT_H
# include MPH_H
# include RDS_H
# include RPR_H
# include RFM_H
# include GRM_H
# include GMX_H
# include GTB_H
# include GSB_H
# include GME_H

# include "GME_edit.h"
# include "GME_panel.h"
# include "GME_message.h"

/*------------------------------------------------------------\
|                                                             |
|                           Constants                         |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                            Types                            |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                          Variables                          |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                        Identify Buffer                      |
|                                                             |
\------------------------------------------------------------*/

  static char  GraalIdentifyMessage[ GRAAL_IDENTIFY_MESSAGE_SIZE ];
  static char  GraalIdentifyBuffer [ GRAAL_IDENTIFY_BUFFER_SIZE  ];
  static char *GraalScanIdentify;
  static long  GraalIdentifyLength;

/*------------------------------------------------------------\
|                                                             |
|                          Functions                          |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                      GraalEditUndo                          |
|                                                             |
\------------------------------------------------------------*/

 void GraalEditUndo()

 {
   graalundorec *UndoRec;
   rdsrec_list  *Rec;
   rdsins_list  *Instance;
   long          X1;
   long          X2;
   long          Y1;
   long          Y2;
   char          OneElement;

   if ( GraalHeadUndo != (graalundo *)NULL )
   {
     if ( ( GraalHeadUndo->UNDO->NEXT != (graalundorec *)NULL ) ||
          ( GraalHeadEqui             != (rdsrec_list  *)NULL ) ||
          ( GraalHeadPeek             != (graalpeek    *)NULL ) )
     { 
       OneElement = GRAAL_FALSE;
     }
     else
     {
       OneElement = (GraalHeadSelect == (graalselect *)NULL);
     }

     GraalDelSelect();
     GraalDelEqui();
     GraalDelPeek();
     GraalRecomputeBound = GRAAL_TRUE;

     for ( UndoRec  = GraalHeadUndo->UNDO;
           UndoRec != (graalundorec *)NULL;
           UndoRec  = UndoRec->NEXT )
     {
       Rec = UndoRec->RECTANGLE;

       if ( GetRdsLayer( Rec ) != RDS_ABOX )
       {
         if ( IsGraalDeleted( Rec ) )
         {
           GraalUndeleteRectangle( Rec );
           if ( OneElement ) GraalDisplayRectangle( Rec );
         }
         else
         {   
           GraalDeleteRectangle( Rec );
           if ( OneElement ) GraalDisplayRectangle( Rec );
  
           GraalDelRectangle( Rec );
         }
       }
       else
       {
         if ( IsRdsFigure( Rec ) )
         {
           if ( IsGraalDeleted( Rec ) )
           { 
             ClearGraalDeleted( Rec );

             GraalFigureMbk->XAB1 = Rec->X * SCALE_X / RDS_LAMBDA;
             GraalFigureMbk->YAB1 = Rec->Y * SCALE_X / RDS_LAMBDA;
             GraalFigureMbk->XAB2 = ( Rec->X + Rec->DX ) * SCALE_X / RDS_LAMBDA;
             GraalFigureMbk->YAB2 = ( Rec->Y + Rec->DY ) * SCALE_X / RDS_LAMBDA;
           }
           else
           {
             GraalDelRectangle( Rec );
           }
         }
         else
         {
           if ( IsGraalDeleted( Rec ) )
           {
             ClearGraalDeleted( Rec );
           }
           else
           {
             GraalDelInstance( GRAAL_PREVIOUS( Rec ) );
           }
         }

         OneElement = GRAAL_FALSE;
       }
     }

     if ( ! OneElement )
     {
       GraalZoomRefresh();
     }

     GraalDelUndo();

     GraalChangeEditMode( GRAAL_EDIT_MEASURE,
                          GraalPromptEditMeasure );
   }   
   else
   {
     GraalWarningMessage( GraalMainWindow, "Nothing to undo !" );
   }
 }

/*------------------------------------------------------------\
|                                                             |
|                         GraalAddIdentify                    |
|                                                             |
\------------------------------------------------------------*/

  char GraalAddIdentify( Rectangle )
 
    rdsrec_list *Rectangle;
  {
    void *Pointer;
    char  Orient;
    long  Length;

    GraalIdentifyBuffer[0] = '\0';
    Pointer = GRAAL_MBK( Rectangle );

    if ( IsRdsSegment( Rectangle ) )
    {
      if ( ( ((phseg_list *)Pointer)->LAYER == NTRANS ) || 
           ( ((phseg_list *)Pointer)->LAYER == PTRANS ) )
      {
        sprintf( GraalIdentifyBuffer, 
        "TRANSISTOR :\n\n  TYPE : %s\n  X1 : %d\n  Y1 : %d\n  X2 : %d  \n  Y2 : %d\n  WIDTH : %d\n\n",
        GRAAL_SEGMENT_NAME_TABLE[ ((phseg_list *)Pointer)->LAYER ][0],
        ((phseg_list *)Pointer)->X1    / SCALE_X, 
        ((phseg_list *)Pointer)->Y1    / SCALE_X,
        ((phseg_list *)Pointer)->X2    / SCALE_X,
        ((phseg_list *)Pointer)->Y2    / SCALE_X,
        ((phseg_list *)Pointer)->WIDTH / SCALE_X );
      }
      else
      {
        sprintf( GraalIdentifyBuffer, 
        "SEGMENT :\n\n  NAME : %s\n  LAYER : %s\n  X1 : %d\n  Y1 : %d\n  X2 : %d\n  Y2 : %d\n  WIDTH : %d\n\n",
          ( Rectangle->NAME != (char *)NULL ) ? Rectangle->NAME : "None",
          GRAAL_SEGMENT_NAME_TABLE[ ((phseg_list *)Pointer)->LAYER ][0],
          ((phseg_list *)Pointer)->X1    / SCALE_X, 
          ((phseg_list *)Pointer)->Y1    / SCALE_X,
          ((phseg_list *)Pointer)->X2    / SCALE_X,
          ((phseg_list *)Pointer)->Y2    / SCALE_X,
          ((phseg_list *)Pointer)->WIDTH / SCALE_X );
      }
    }
    else
    if ( IsRdsConnector( Rectangle ) )
    {
      switch( ((phcon_list *)Pointer)->ORIENT )
      {
        case NORTH : Orient = GRAAL_NORTH;
        break;

        case SOUTH : Orient = GRAAL_SOUTH;
        break;

        case EAST  : Orient = GRAAL_EAST;
        break;

        default    : Orient = GRAAL_WEST;
      }

      sprintf( GraalIdentifyBuffer,
      "CONNECTOR :\n\n  NAME : %s\n  LAYER : %s\n  XCON : %d\n  YCON : %d\n  WIDTH : %d\n  ORIENT : %s\n\n",
      ( Rectangle->NAME != (char *)NULL ) ? Rectangle->NAME : "None",
      GRAAL_CONNECTOR_NAME_TABLE[ ((phcon_list *)Pointer)->LAYER ][0],
      ((phcon_list *)Pointer)->XCON  / SCALE_X,
      ((phcon_list *)Pointer)->YCON  / SCALE_X,
      ((phcon_list *)Pointer)->WIDTH / SCALE_X,
      GRAAL_ORIENT_NAME_TABLE[ Orient ][0] );
    }
    else
    if ( IsRdsVia( Rectangle ) )
    {
      sprintf( GraalIdentifyBuffer,
      "VIA :\n\n  TYPE: %s\n  XVIA : %d\n  YVIA : %d\n\n",
      GRAAL_VIA_NAME_TABLE[ ((phvia_list *)Pointer)->TYPE ][0],
      ((phvia_list *)Pointer)->XVIA  / SCALE_X,
      ((phvia_list *)Pointer)->YVIA  / SCALE_X );
    }
    else
    if ( IsRdsReference( Rectangle ) )
    {
      sprintf( GraalIdentifyBuffer,
      "REFERENCE :\n\n  NAME : %s\n  TYPE : %s\n  XREF : %d\n  YREF : %d\n\n",
      ( Rectangle->NAME != (char *)NULL ) ? Rectangle->NAME : "None",
      ( ! strcmp( ((phref_list *)Pointer)->FIGNAME, "ref_ref" ) ) ? "Ref_Ref" : "Ref_Con",
      ((phref_list *)Pointer)->XREF  / SCALE_X,
      ((phref_list *)Pointer)->YREF  / SCALE_X );
    }
    else
    if ( IsRdsInstance( Rectangle ) )
    {
      Orient = ((phins_list *)Pointer)->TRANSF;

      sprintf( GraalIdentifyBuffer,
      "INSTANCE :\n\n  NAME : %s\n  MODEL : %s\n  TRANSF : %s\n  XINS : %d\n  YINS : %d\n\n",
      ((phins_list *)Pointer)->INSNAME,
      ((phins_list *)Pointer)->FIGNAME,
      GRAAL_SYMMETRY_NAME_TABLE[ Orient ][0], 
      ((phins_list *)Pointer)->XINS  / SCALE_X,
      ((phins_list *)Pointer)->YINS  / SCALE_X );
    }
    if ( IsRdsFigure( Rectangle ) )
    {
      sprintf( GraalIdentifyBuffer,
      "ABUTMENT BOX :\n\n  NAME : %s\n  XAB1 : %d\n  YAB1 : %d\n  XAB2 : %d\n  YAB2 : %d\n\n",
      ((phfig_list *)Pointer)->NAME,
      ((phfig_list *)Pointer)->XAB1  / SCALE_X,
      ((phfig_list *)Pointer)->YAB1  / SCALE_X,
      ((phfig_list *)Pointer)->XAB2  / SCALE_X,
      ((phfig_list *)Pointer)->YAB2  / SCALE_X );
    }

    Length = strlen( GraalIdentifyBuffer );

    if ( ( GraalIdentifyLength + Length ) < ( GRAAL_IDENTIFY_MESSAGE_SIZE - 1 ) )
    {
      strcpy( GraalScanIdentify, GraalIdentifyBuffer );

      GraalScanIdentify   += Length; 
      GraalIdentifyLength += Length;

      return( GRAAL_TRUE );
    }
    else
    {
      strcpy( GraalScanIdentify, "#" );
   
      return( GRAAL_FALSE );
    }
  }

/*------------------------------------------------------------\
|                                                             |
|                     GraalEditIdentify                       |
|                                                             |
\------------------------------------------------------------*/

  void GraalEditIdentify()
  {
    graalselect *Select;

    strcpy( GraalIdentifyMessage, "No element found !" );
    GraalScanIdentify   = GraalIdentifyMessage;
    GraalIdentifyLength = 0;

    for ( Select  = GraalHeadSelect; 
          Select != (graalselect *)NULL;
          Select  = Select->NEXT )
    {
      if ( ! GraalAddIdentify( Select->RECTANGLE ) ) break;
    }

    GraalDelSelect();

    GraalDisplayIdentifyMessage( GraalIdentifyMessage );
    GraalEnterPanel( &GraalEditIdentifyPanel       );
  }

/*------------------------------------------------------------\
|                                                             |
|                        GraalEditCopy                        |
|                                                             |
\------------------------------------------------------------*/

 void GraalEditCopy( LambdaX1, LambdaY1, LambdaX2, LambdaY2, Mode )

    long LambdaX1;
    long LambdaY1;
    long LambdaX2;
    long LambdaY2;
    char Mode; 
 {
   graalselect *Select;
   rdsrec_list *Rectangle;
   rdsrec_list *NewRec;
   void        *Element;
   void        *Pointer;
   char         Orient;
   char         FirstUndo;
   char         MbkOrient;
   long         DeltaX;
   long         DeltaY;
   long         X1;
   long         X2;
   long         Y1;
   long         Y2;

   DeltaX = ( LambdaX2 - LambdaX1 ) * SCALE_X;
   DeltaY = ( LambdaY2 - LambdaY1 ) * SCALE_X;

   FirstUndo = 1;

   for ( Select  = GraalHeadSelect;
         Select != (graalselect *)NULL;
         Select  = Select->NEXT )
   {
     Rectangle = Select->RECTANGLE;
 
     if ( IsRdsSegment( Rectangle ) )
     {
       if ( FirstUndo )
       { 
         GraalAddUndo(); 
 
         FirstUndo = 0; 
       }

       Pointer = GRAAL_MBK( Rectangle );

       X1 = ((phseg_list *)Pointer)->X1 + DeltaX;
       Y1 = ((phseg_list *)Pointer)->Y1 + DeltaY;
       X2 = ((phseg_list *)Pointer)->X2 + DeltaX;
       Y2 = ((phseg_list *)Pointer)->Y2 + DeltaY;

       Element = (void *)

          addphseg( GraalFigureMbk, 
                    ((phseg_list *)Pointer)->LAYER,
                    ((phseg_list *)Pointer)->WIDTH,
                    X1, Y1, X2, Y2,
                    ((phseg_list *)Pointer)->NAME );

       ((phseg_list *)Element)->TYPE = ((phseg_list *)Pointer)->TYPE;
       ((phseg_list *)Element)->USER = (void *)(&GraalFigureMbk->PHSEG);

       if ( ((phseg_list *)Element)->NEXT != (phseg_list *)NULL )
       {
         ((phseg_list *)Element)->NEXT->USER = (void *)(&((phseg_list *)Element)->NEXT);
       }

       NewRec = GraalAddSegment( ((phseg_list *)Element) );

       GraalAddUndoRec( NewRec );
     }
     else
     if ( IsRdsVia( Rectangle ) )
     {
       if ( FirstUndo )
       { 
         GraalAddUndo(); 
 
         FirstUndo = 0; 
       }

       Pointer = GRAAL_MBK( Rectangle );

       X1 = ((phvia_list *)Pointer)->XVIA + DeltaX;
       Y1 = ((phvia_list *)Pointer)->YVIA + DeltaY;

       Element = (void *)

          addphvia( GraalFigureMbk,
                    ((phvia_list *)Pointer)->TYPE, X1, Y1 );

       ((phvia_list *)Element)->USER = (void *)(&GraalFigureMbk->PHVIA);

       if ( ((phvia_list *)Element)->NEXT != (phvia_list *)NULL )
       {
         ((phvia_list *)Element)->NEXT->USER = (void *)(&((phvia_list *)Element)->NEXT);
       }

       NewRec = GraalAddVia( ((phvia_list *)Element) );

       GraalAddUndoRec( NewRec );
     }
     else
     if ( IsRdsReference( Rectangle ) )
     { 
       if ( FirstUndo )
       { 
         GraalAddUndo(); 
 
         FirstUndo = 0; 
       }

       Pointer = GRAAL_MBK( Rectangle );

       X1 = ((phref_list *)Pointer)->XREF + DeltaX;
       Y1 = ((phref_list *)Pointer)->YREF + DeltaY;

       Element = (void *)

          addphref( GraalFigureMbk,
                    ((phref_list *)Pointer)->FIGNAME,
                    Rectangle->NAME, X1, Y1 );

       ((phref_list *)Element)->USER = (void *)(&GraalFigureMbk->PHREF);

       if ( ((phref_list *)Element)->NEXT != (phref_list *)NULL )
       {
         ((phref_list *)Element)->NEXT->USER = (void *)(&((phref_list *)Element)->NEXT);
       }

       NewRec = GraalAddReference( ((phvia_list *)Element) );

       GraalAddUndoRec( NewRec );
     }
     else
     if ( IsRdsConnector( Rectangle ) )
     {
       Pointer = GRAAL_MBK( Rectangle );

       X1 = ((phcon_list *)Pointer)->XCON + DeltaX;
       Y1 = ((phcon_list *)Pointer)->YCON + DeltaY;

       Orient = 0;

       if ( ( X1 == GraalFigureMbk->XAB1 ) &&
            ( Y1 >= GraalFigureMbk->YAB1 ) &&
            ( Y1 <= GraalFigureMbk->YAB2 ) )
       {
         Orient    |= GRAAL_WEST_MASK;
         MbkOrient  = WEST;
       }

       if ( ( X1 == GraalFigureMbk->XAB2 ) &&
            ( Y1 >= GraalFigureMbk->YAB1 ) &&
            ( Y1 <= GraalFigureMbk->YAB2 ) )
       {
         Orient    |= GRAAL_EAST_MASK;
         MbkOrient  = EAST;
       }

       if ( ( Y1 == GraalFigureMbk->YAB1 ) &&
            ( X1 >= GraalFigureMbk->XAB1 ) &&
            ( X1 <= GraalFigureMbk->XAB2 ) )
       {
         Orient    |= GRAAL_SOUTH_MASK;
         MbkOrient  = SOUTH;
       }

       if ( ( Y1 == GraalFigureMbk->YAB2 ) &&
            ( X1 >= GraalFigureMbk->XAB1 ) &&
            ( X1 <= GraalFigureMbk->XAB2 ) )
       {
         Orient    |= GRAAL_NORTH_MASK;
         MbkOrient  = NORTH;
       }

       if ( Orient != 0 )
       {
         if ( FirstUndo )
         { 
           GraalAddUndo(); 
 
           FirstUndo = 0; 
         }

         switch ( ((phcon_list *)Pointer)->ORIENT )
         {
           case NORTH :
 
             if ( Orient & GRAAL_NORTH_MASK )
             {
               MbkOrient = NORTH;
             }

           break;
 
           case SOUTH :
 
             if ( Orient & GRAAL_SOUTH_MASK )
             {
               MbkOrient = SOUTH;
             }

           break;

           case EAST  :

             if ( Orient & GRAAL_EAST_MASK )
             {  
               MbkOrient = EAST;
             } 

           break;

           case WEST  :
 
             if ( Orient & GRAAL_WEST_MASK )
             {  
               MbkOrient = WEST;
             } 
 
           break;
         }

         Element = (void *)

           addphcon( GraalFigureMbk,
                     MbkOrient,
                     Rectangle->NAME, 
                     X1, Y1,
                     ((phcon_list *)Pointer)->LAYER,
                     ((phcon_list *)Pointer)->WIDTH );

         ((phcon_list *)Element)->USER = (void *)(&GraalFigureMbk->PHCON);
 
         if ( ((phcon_list *)Element)->NEXT != (phcon_list *)NULL )
         {
           ((phcon_list *)Element)->NEXT->USER = (void *)(&((phcon_list *)Element)->NEXT);
         }

         NewRec = GraalAddConnector( ((phcon_list *)Element) );
  
         GraalAddUndoRec( NewRec );
       }
     }
   }

   GraalDelEqui();
   GraalDelPeek();
   GraalDelSelect();
   GraalZoomRefresh();

   if ( Mode == 0 )
   {
     GraalChangeEditMode( GRAAL_SELECT_POINT_COPY,
                          GraalPromptSelectPointCopy );
   }
   else
   {
     GraalChangeEditMode( GRAAL_SELECT_WINDOW_COPY,
                          GraalPromptSelectWindowCopy );
   }
 }

/*------------------------------------------------------------\
|                                                             |
|                        GraalEditMove                        |
|                                                             |
\------------------------------------------------------------*/

 void GraalEditMove( LambdaX1, LambdaY1, LambdaX2, LambdaY2, Mode )

    long LambdaX1;
    long LambdaY1;
    long LambdaX2;
    long LambdaY2;
    char Mode;
 {
   graalselect *Select;
   rdsrec_list *Rectangle;
   rdsrec_list *NewRec;
   rdsins_list *Instance;
   phins_list  *SaveInstance;
   graalconrec *ConRec;
   void        *Element;
   void        *Pointer;
   char         Orient;
   char         MbkOrient;
   char         FirstUndo;
   long         DeltaX;
   long         DeltaY;
   long         X1;
   long         X2;
   long         Y1;
   long         Y2;

   DeltaX = ( LambdaX2 - LambdaX1 ) * SCALE_X;
   DeltaY = ( LambdaY2 - LambdaY1 ) * SCALE_X;

   FirstUndo = 1;

   for ( Select  = GraalHeadSelect;
         Select != (graalselect *)NULL;
         Select  = Select->NEXT )
   { 
     if ( IsRdsFigure( Select->RECTANGLE ) ) 
     {
       FirstUndo = 0;

       GraalAddUndo();
       GraalDeleteRectangle( Select->RECTANGLE );
       GraalAddUndoRec( Select->RECTANGLE );

       GraalFigureMbk->XAB1 += DeltaX;
       GraalFigureMbk->XAB2 += DeltaX;
       GraalFigureMbk->YAB1 += DeltaY;
       GraalFigureMbk->YAB2 += DeltaY;

       NewRec = GraalAddAbox();
       GraalAddUndoRec( NewRec );

       for ( ConRec  = GraalHeadConRec;
             ConRec != (graalconrec *)NULL;
             ConRec  = ConRec->NEXT )
       {
         Rectangle = ConRec->RECTANGLE;

         if ( ! IsGraalDeleted( Rectangle ) ) 
         {
           GraalDeleteRectangle( Rectangle );
           GraalAddUndoRec( Rectangle );
      
           Pointer = GRAAL_MBK( Rectangle );

           X1 = ((phcon_list *)Pointer)->XCON + DeltaX;
           Y1 = ((phcon_list *)Pointer)->YCON + DeltaY;

           Element = (void *)

             addphcon( GraalFigureMbk,
                       ((phcon_list *)Pointer)->ORIENT,
                       Rectangle->NAME,
                       X1, Y1,
                       ((phcon_list *)Pointer)->LAYER,
                       ((phcon_list *)Pointer)->WIDTH );

           ((phcon_list *)Element)->USER = (void *)(&GraalFigureMbk->PHCON);

           if ( ((phcon_list *)Element)->NEXT != (phcon_list *)NULL )
           {
             ((phcon_list *)Element)->NEXT->USER = (void *)(&((phcon_list *)Element)->NEXT);
           }

           NewRec = GraalAddConnector( ((phcon_list *)Element) );
           GraalAddUndoRec( NewRec );
         }
       }

       break;
     }
   }

   for ( Select  = GraalHeadSelect;
         Select != (graalselect *)NULL;
         Select  = Select->NEXT )
   {
     Rectangle = Select->RECTANGLE;

     if ( ! IsGraalAccepted( Rectangle ) ) continue;
 
     if ( IsRdsSegment( Rectangle ) )
     {
       if ( FirstUndo )
       {
         GraalAddUndo();

         FirstUndo = 0;
       }

       GraalDeleteRectangle( Rectangle );
       GraalAddUndoRec( Rectangle );

       Pointer = GRAAL_MBK( Rectangle );

       X1 = ((phseg_list *)Pointer)->X1 + DeltaX;
       Y1 = ((phseg_list *)Pointer)->Y1 + DeltaY;
       X2 = ((phseg_list *)Pointer)->X2 + DeltaX;
       Y2 = ((phseg_list *)Pointer)->Y2 + DeltaY;

       Element = (void *)

          addphseg( GraalFigureMbk, 
                    ((phseg_list *)Pointer)->LAYER,
                    ((phseg_list *)Pointer)->WIDTH,
                    X1, Y1, X2, Y2,
                    ((phseg_list *)Pointer)->NAME );

       ((phseg_list *)Element)->TYPE = ((phseg_list *)Pointer)->TYPE;
       ((phseg_list *)Element)->USER = (void *)(&GraalFigureMbk->PHSEG);

       if ( ((phseg_list *)Element)->NEXT != (phseg_list *)NULL )
       {
         ((phseg_list *)Element)->NEXT->USER = (void *)(&((phseg_list *)Element)->NEXT);
       }

       NewRec = GraalAddSegment( ((phseg_list *)Element) );
       GraalAddUndoRec( NewRec );
     }
     else
     if ( IsRdsVia( Rectangle ) )
     {
       if ( FirstUndo )
       { 
         GraalAddUndo(); 
 
         FirstUndo = 0; 
       }

       GraalDeleteRectangle( Rectangle );
       GraalAddUndoRec( Rectangle );

       Pointer = GRAAL_MBK( Rectangle );

       X1 = ((phvia_list *)Pointer)->XVIA + DeltaX;
       Y1 = ((phvia_list *)Pointer)->YVIA + DeltaY;

       Element = (void *)

          addphvia( GraalFigureMbk,
                    ((phvia_list *)Pointer)->TYPE, X1, Y1 );

       ((phvia_list *)Element)->USER = (void *)(&GraalFigureMbk->PHVIA);

       if ( ((phvia_list *)Element)->NEXT != (phvia_list *)NULL )
       {
         ((phvia_list *)Element)->NEXT->USER = (void *)(&((phvia_list *)Element)->NEXT);
       }

       NewRec = GraalAddVia( ((phvia_list *)Element) );

       GraalAddUndoRec( NewRec );
     }
     else
     if ( IsRdsReference( Rectangle ) )
     {
       if ( FirstUndo )
       { 
         GraalAddUndo(); 
 
         FirstUndo = 0; 
       }

       GraalDeleteRectangle( Rectangle );
       GraalAddUndoRec( Rectangle );

       Pointer = GRAAL_MBK( Rectangle );

       X1 = ((phref_list *)Pointer)->XREF + DeltaX;
       Y1 = ((phref_list *)Pointer)->YREF + DeltaY;
 
       Element = (void *)

          addphref( GraalFigureMbk,
                    ((phref_list *)Pointer)->FIGNAME,
                    Rectangle->NAME, X1, Y1 );

       ((phref_list *)Element)->USER = (void *)(&GraalFigureMbk->PHREF);

       if ( ((phref_list *)Element)->NEXT != (phref_list *)NULL )
       {
         ((phref_list *)Element)->NEXT->USER = (void *)(&((phref_list *)Element)->NEXT);
       }

       NewRec = GraalAddReference( ((phvia_list *)Element) );

       GraalAddUndoRec( NewRec );
     }
     else
     if ( IsRdsConnector( Rectangle ) )
     {
       Pointer = GRAAL_MBK( Rectangle );

       X1 = ((phcon_list *)Pointer)->XCON + DeltaX;
       Y1 = ((phcon_list *)Pointer)->YCON + DeltaY;

       Orient = 0;

       if ( ( X1 == GraalFigureMbk->XAB1 ) &&
            ( Y1 >= GraalFigureMbk->YAB1 ) &&
            ( Y1 <= GraalFigureMbk->YAB2 ) )
       {
         Orient    |= GRAAL_WEST_MASK;
         MbkOrient  = WEST;
       }

       if ( ( X1 == GraalFigureMbk->XAB2 ) &&
            ( Y1 >= GraalFigureMbk->YAB1 ) &&
            ( Y1 <= GraalFigureMbk->YAB2 ) )
       {
         Orient    |= GRAAL_EAST_MASK;
         MbkOrient  = EAST;
       }

       if ( ( Y1 == GraalFigureMbk->YAB1 ) &&
            ( X1 >= GraalFigureMbk->XAB1 ) &&
            ( X1 <= GraalFigureMbk->XAB2 ) )
       {
         Orient    |= GRAAL_SOUTH_MASK;
         MbkOrient  = SOUTH;
       }

       if ( ( Y1 == GraalFigureMbk->YAB2 ) &&
            ( X1 >= GraalFigureMbk->XAB1 ) &&
            ( X1 <= GraalFigureMbk->XAB2 ) )
       {
         Orient    |= GRAAL_NORTH_MASK;
         MbkOrient  = NORTH;
       }    

       if ( Orient != 0 )
       {
         if ( FirstUndo )
         { 
           GraalAddUndo(); 
 
           FirstUndo = 0; 
         }

         GraalDeleteRectangle( Rectangle );
         GraalAddUndoRec( Rectangle );

         switch ( ((phcon_list *)Pointer)->ORIENT )
         {
           case NORTH :
 
             if ( Orient & GRAAL_NORTH_MASK )
             {
               MbkOrient = NORTH;
             }

           break;
 
           case SOUTH :
 
             if ( Orient & GRAAL_SOUTH_MASK )
             {
               MbkOrient = SOUTH;
             }

           break;

           case EAST  :

             if ( Orient & GRAAL_EAST_MASK )
             {  
               MbkOrient = EAST;
             } 

           break;

           case WEST  :
 
             if ( Orient & GRAAL_WEST_MASK )
             {  
               MbkOrient = WEST;
             } 
 
           break;
         }

         Element = (void *)

           addphcon( GraalFigureMbk,
                     MbkOrient,
                     Rectangle->NAME, 
                     X1, Y1,
                     ((phcon_list *)Pointer)->LAYER,
                     ((phcon_list *)Pointer)->WIDTH );

         ((phcon_list *)Element)->USER = (void *)(&GraalFigureMbk->PHCON);
 
         if ( ((phcon_list *)Element)->NEXT != (phcon_list *)NULL )
         {
           ((phcon_list *)Element)->NEXT->USER = (void *)(&((phcon_list *)Element)->NEXT);
         }

         NewRec = GraalAddConnector( ((phcon_list *)Element) );
  
         GraalAddUndoRec( NewRec );
       }
     }
     else
     if ( IsRdsInstance( Rectangle ) )
     {
       if ( FirstUndo )
       { 
         GraalAddUndo(); 
 
         FirstUndo = 0; 
       }

       GraalDeleteRectangle( Rectangle );
       GraalAddUndoRec( Rectangle );

       Pointer = GRAAL_MBK( Rectangle );

       X1 = ((phins_list *)Pointer)->XINS + DeltaX;
       Y1 = ((phins_list *)Pointer)->YINS + DeltaY;

       SaveInstance          = GraalFigureMbk->PHINS;
       GraalFigureMbk->PHINS = (phins_list *)NULL;

       Element = (void *)

          addphins( GraalFigureMbk,
                    ((phins_list *)Pointer)->FIGNAME,
                    ((phins_list *)Pointer)->INSNAME,
                    ((phins_list *)Pointer)->TRANSF,
                    X1, Y1 );
 
       ((phins_list *)Element)->NEXT = SaveInstance;
       ((phins_list *)Element)->USER = (void *)(&GraalFigureMbk->PHINS);
      
       if ( SaveInstance != (phins_list *)NULL )
       {
         SaveInstance->USER = (void *)(&((phins_list *)Element)->NEXT);
       }

       Instance = GraalAddInstance( ((phins_list *)Element) );

       GraalDisplayToolsMessage();

       if ( Instance == (rdsins_list *)NULL )
       {
         GraalErrorMessage( GraalMainWindow, "Unable to load instance model !" );
       }
       else
       {
         NewRec   = Instance->LAYERTAB[ RDS_ABOX ];

         GraalAddUndoRec( NewRec );
       }
     }
   }

   GraalDelEqui();
   GraalDelPeek();
   GraalDelSelect();
   GraalZoomRefresh();

   if ( Mode == 0 )
   {
     GraalChangeEditMode( GRAAL_SELECT_POINT_MOVE,
                          GraalPromptSelectPointMove );
   }
   else
   {
     GraalChangeEditMode( GRAAL_SELECT_WINDOW_MOVE,
                          GraalPromptSelectWindowMove );
   }
 }

/*------------------------------------------------------------\
|                                                             |
|                        GraalEditDelete                      |
|                                                             |
\------------------------------------------------------------*/

 void GraalEditDelete()
 {
   graalselect *Select;
   rdsrec_list *Rectangle;
   char         FirstUndo;
   graalconrec *ConRec;

   FirstUndo = 1;

   for ( Select  = GraalHeadSelect;
         Select != (graalselect *)NULL;
         Select  = Select->NEXT )
   {
     if ( IsRdsFigure( Select->RECTANGLE ) )
     {
       FirstUndo = 0;

       GraalAddUndo();
       GraalDeleteRectangle( Select->RECTANGLE );
       GraalAddUndoRec( Select->RECTANGLE );

       GraalFigureMbk->XAB1 = 0;
       GraalFigureMbk->XAB2 = 0;
       GraalFigureMbk->YAB1 = 0;
       GraalFigureMbk->YAB2 = 0;
 
       for ( ConRec  = GraalHeadConRec;
             ConRec != (graalconrec *)NULL;
             ConRec  = ConRec->NEXT )
       {
         Rectangle = ConRec->RECTANGLE;

         if ( ! IsGraalDeleted( Rectangle ) )
         {
           GraalDeleteRectangle( Rectangle );
           GraalAddUndoRec( Rectangle );
         }
       }

       break;
     }
   }

   for ( Select  = GraalHeadSelect;
         Select != (graalselect *)NULL;
         Select  = Select->NEXT )
   {
     Rectangle = Select->RECTANGLE;

     if ( ! IsGraalAccepted( Rectangle ) ) continue;
 
     if ( ( IsRdsSegment( Rectangle   ) ) ||
          ( IsRdsVia( Rectangle       ) ) ||
          ( IsRdsReference( Rectangle ) ) ||
          ( IsRdsConnector( Rectangle ) ) ||
          ( IsRdsInstance( Rectangle  ) ) ) 
     {
       if ( FirstUndo ) 
       {
         GraalAddUndo();
         FirstUndo = 0;
       }

       GraalDeleteRectangle( Rectangle );
       GraalAddUndoRec( Rectangle );
     }
   }

   GraalDelEqui();
   GraalDelPeek();
   GraalDelSelect();
   GraalZoomRefresh();
 }

/*------------------------------------------------------------\
|                                                             |
|                       GraalEditStretch                      |
|                                                             |
\------------------------------------------------------------*/

 void GraalEditStretch( LambdaX1, LambdaY1, LambdaX2, LambdaY2 )

   long LambdaX1;
   long LambdaY1;
   long LambdaX2;
   long LambdaY2;
 {
   graalselect *Select;
   rdsrec_list *Rectangle;
   rdsrec_list *NewRec;
   graalconrec *ConRec;
   void        *Element;
   void        *Pointer;
   char         FirstUndo;
   char         Orient;
   char         Stretch;
   long         Delta;
   long         Delta1;
   long         Delta2;
   long         Length;
   long         X1;
   long         X2;
   long         Y1;
   long         Y2;

   Orient = 0;

   LambdaX1 = LambdaX1 * SCALE_X;
   LambdaX2 = LambdaX2 * SCALE_X;
   LambdaY1 = LambdaY1 * SCALE_X;
   LambdaY2 = LambdaY2 * SCALE_X;

   if ( LambdaX2 != LambdaX1 )
   {
     Delta  = LambdaX2 - LambdaX1;
     Orient = ( Delta > 0 ) ? GRAAL_EAST : GRAAL_WEST;
   }
   else
   {
     Delta  = LambdaY2 - LambdaY1;
     Orient = ( Delta > 0 ) ? GRAAL_NORTH : GRAAL_SOUTH;
   }
  
   if ( Delta != 0 )
   {
     FirstUndo = 1;

     for ( Select  = GraalHeadSelect;
           Select != (graalselect *)NULL;
           Select  = Select->NEXT )
     { 
       Rectangle = Select->RECTANGLE;

       if ( IsRdsFigure( Rectangle ) ) 
       {
         X1 = GraalFigureMbk->XAB1;
         X2 = GraalFigureMbk->XAB2;
         Y1 = GraalFigureMbk->YAB1;
         Y2 = GraalFigureMbk->YAB2;

         Stretch = 0;

         if ( ( Orient == GRAAL_EAST ) ||
              ( Orient == GRAAL_WEST ) )
         {
           Delta1 = X1 - LambdaX1;
           Delta2 = X2 - LambdaX1;

           if ( Delta1 < 0 ) Delta1 = -Delta1;
           if ( Delta2 < 0 ) Delta2 = -Delta2;

           if ( Delta1 < Delta2 ) X1 += Delta;
           else                   X2 += Delta;

           if ( X2 > X1 )
           {
             Stretch = 1;
           }
         }
         else
         {
           Delta1 = Y1 - LambdaY1;
           Delta2 = Y2 - LambdaY1;

           if ( Delta1 < 0 ) Delta1 = -Delta1;
           if ( Delta2 < 0 ) Delta2 = -Delta2;

           if ( Delta1 < Delta2 ) Y1 += Delta;
           else                   Y2 += Delta;

           if ( Y2 > Y1 )
           {
             Stretch = 1;
           }
         }

         if ( Stretch )
         {
           if ( FirstUndo )
           {
             GraalAddUndo();

             FirstUndo = 0;
           }

           GraalDeleteRectangle( Rectangle );
           GraalAddUndoRec( Rectangle );

           GraalFigureMbk->XAB1 = X1;
           GraalFigureMbk->YAB1 = Y1;
           GraalFigureMbk->XAB2 = X2;
           GraalFigureMbk->YAB2 = Y2;

           NewRec = GraalAddAbox();
           GraalAddUndoRec( NewRec );
      
           for ( ConRec  = GraalHeadConRec;
                 ConRec != (graalconrec *)NULL;
                 ConRec  = ConRec->NEXT )
           {
             Rectangle = ConRec->RECTANGLE;

             if ( ! IsGraalDeleted( Rectangle ) ) 
             {
               Stretch = 0;
               Pointer = GRAAL_MBK( Rectangle );

               X1 = ((phcon_list *)Pointer)->XCON;
               Y1 = ((phcon_list *)Pointer)->YCON;

               if ( ( X1 != GraalFigureMbk->XAB1 ) &&
                    ( X1 != GraalFigureMbk->XAB2 ) &&
                    ( Y1 != GraalFigureMbk->YAB1 ) &&
                    ( Y1 != GraalFigureMbk->YAB2 ) )
               {
                 switch ( Orient )
                 {
                   case GRAAL_SOUTH:
                   case GRAAL_NORTH: Y1 += Delta;

                   break;

                   case GRAAL_WEST:
                   case GRAAL_EAST:  X1 += Delta;

                   break;
                 }
        
                 Stretch = 1;
               }

               if ( X1 < GraalFigureMbk->XAB1 )
               {
                 X1 = GraalFigureMbk->XAB1; Stretch = 1;
               }

               if ( X1 > GraalFigureMbk->XAB2 )
               {
                 X1 = GraalFigureMbk->XAB2; Stretch = 1;
               }

               if ( Y1 < GraalFigureMbk->YAB1 )
               {
                 Y1 = GraalFigureMbk->YAB1; Stretch = 1;
               }

               if ( Y1 > GraalFigureMbk->YAB2 )
               {
                 Y1 = GraalFigureMbk->YAB2; Stretch = 1;
               }

               if ( Stretch )
               {
                 GraalDeleteRectangle( Rectangle );
                 GraalAddUndoRec( Rectangle );
      
                 Element = (void *)

                   addphcon( GraalFigureMbk,
                             ((phcon_list *)Pointer)->ORIENT,
                             Rectangle->NAME,
                             X1, Y1,
                             ((phcon_list *)Pointer)->LAYER,
                             ((phcon_list *)Pointer)->WIDTH );

                 ((phcon_list *)Element)->USER = (void *)(&GraalFigureMbk->PHCON);

                 if ( ((phcon_list *)Element)->NEXT != (phcon_list *)NULL )
                 {
                   ((phcon_list *)Element)->NEXT->USER = (void *)(&((phcon_list *)Element)->NEXT);
                 }

                 NewRec = GraalAddConnector( ((phcon_list *)Element) );
                 GraalAddUndoRec( NewRec );
               }
             }
           }
         }

         break;
       }
     }

     for ( Select  = GraalHeadSelect;
           Select != (graalselect *)NULL;
           Select  = Select->NEXT )
     {
       Rectangle = Select->RECTANGLE;

       if ( IsRdsSegment( Rectangle ) )
       {
         Pointer = GRAAL_MBK( Rectangle );

         X1 = ((phseg_list *)Pointer)->X1;
         Y1 = ((phseg_list *)Pointer)->Y1;
         X2 = ((phseg_list *)Pointer)->X2;
         Y2 = ((phseg_list *)Pointer)->Y2;

         Length = GRAAL_SEGMENT_VALUE_TABLE[ ((phseg_list *)Pointer)->LAYER ][1] * SCALE_X;

         Stretch = 0;

         switch ( ((phseg_list *)Pointer)->TYPE )
         {
           case RIGHT :
           case LEFT  :

             if ( ( Orient == GRAAL_EAST ) || 
                  ( Orient == GRAAL_WEST ) )
             {
               Delta1 = X1 - LambdaX1;
               Delta2 = X2 - LambdaX1;

               if ( Delta1 < 0 ) Delta1 = -Delta1;
               if ( Delta2 < 0 ) Delta2 = -Delta2;

               if ( Delta1 < Delta2 ) X1 += Delta;
               else                   X2 += Delta;

               if ( ( X2 - X1 ) >= Length )
               {
                 Stretch = 1;
               }
             }

             break;

           case UP    :
           case DOWN  :

             if ( ( Orient == GRAAL_NORTH ) || 
                  ( Orient == GRAAL_SOUTH ) )
             {
               Delta1 = Y1 - LambdaY1;
               Delta2 = Y2 - LambdaY1;

               if ( Delta1 < 0 ) Delta1 = -Delta1;
               if ( Delta2 < 0 ) Delta2 = -Delta2;

               if ( Delta1 < Delta2 ) Y1 += Delta;
               else                   Y2 += Delta;

               if ( ( Y2 - Y1 ) >= Length )
               {
                 Stretch = 1;
               }
             }

             break;
         }

         if ( Stretch ) 
         {
           if ( FirstUndo )
           {
             GraalAddUndo();

             FirstUndo = 0;
           }

           GraalDeleteRectangle( Rectangle );
           GraalAddUndoRec( Rectangle );

           Element = (void *)

              addphseg( GraalFigureMbk, 
                        ((phseg_list *)Pointer)->LAYER,
                        ((phseg_list *)Pointer)->WIDTH,
                        X1, Y1, X2, Y2,
                        ((phseg_list *)Pointer)->NAME );

           ((phseg_list *)Element)->TYPE = ((phseg_list *)Pointer)->TYPE;
           ((phseg_list *)Element)->USER = (void *)(&GraalFigureMbk->PHSEG);

           if ( ((phseg_list *)Element)->NEXT != (phseg_list *)NULL )
           {
             ((phseg_list *)Element)->NEXT->USER = (void *)(&((phseg_list *)Element)->NEXT);
           }

           NewRec = GraalAddSegment( ((phseg_list *)Element) );
           GraalAddUndoRec( NewRec );
         }
       }
     }
   } 

   GraalDelEqui();
   GraalDelPeek();
   GraalDelSelect();
   GraalZoomRefresh();

   GraalChangeEditMode( GRAAL_SELECT_POINT_STRETCH,
                        GraalPromptSelectPointStretch );
 }
