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

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

# include <stdio.h>
# include <Xm/Xm.h>
 
# include MUT_H
# include MPH_H
# include RDS_H
# include RPR_H
# include GSB_H
# include GRM_H
# include GMX_H

# include "GMX_grid.h"

/*------------------------------------------------------------\
|                                                             |
|                           Constants                         |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                            Types                            |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                          Variables                          |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                         Lambda Grid                         |
|                                                             |
\------------------------------------------------------------*/

  float      GraalLambdaGridStep;

  long       GraalLambdaGridX;
  long       GraalLambdaGridY;
  long       GraalLambdaGridDx;
  long       GraalLambdaGridDy;

  long       GraalPixelGridX;
  long       GraalPixelGridY;

/*------------------------------------------------------------\
|                                                             |
|                      User Lambda Grid                       |
|                                                             |
\------------------------------------------------------------*/

  long       GraalLambdaUserGridDx;
  long       GraalLambdaUserGridDy;
  char       GraalLambdaUserGrid;

/*------------------------------------------------------------\
|                                                             |
|                           Functions                         |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                GraalInitializeLambdaGrid                    |
|                                                             |
\------------------------------------------------------------*/

  void GraalInitializeLambdaGrid()

  {
    GraalLambdaGridX      = GRAAL_DEFAULT_GRID_X;
    GraalLambdaGridY      = GRAAL_DEFAULT_GRID_Y;
    GraalLambdaGridDx     = GRAAL_DEFAULT_GRID_DX;
    GraalLambdaGridDy     = GRAAL_DEFAULT_GRID_DY;
    GraalLambdaUserGridDx = 4;
    GraalLambdaUserGridDy = 4;
    GraalLambdaUserGrid   = GRAAL_FALSE;

    GraalComputeLambdaGrid();
  }

/*------------------------------------------------------------\
|                                                             |
|                 GraalComputeLambdaGrid                      |
|                                                             |
\------------------------------------------------------------*/

  void GraalComputeLambdaGrid()

  {
    float StepX;
    float StepY;

    if ( ( GraalLambdaGridX      <= ( GraalWindowXmin / RDS_LAMBDA )) ||
         ( GraalLambdaGridY      <= ( GraalWindowYmin / RDS_LAMBDA )) ||
         ( ( GraalLambdaGridX + 
             GraalLambdaGridDx ) >  ( GraalWindowXmax / RDS_LAMBDA )) ||
         ( ( GraalLambdaGridY + 
             GraalLambdaGridDy ) >  ( GraalWindowYmax / RDS_LAMBDA )) )
    {
      GraalLambdaGridX  = GRAAL_DEFAULT_GRID_X;
      GraalLambdaGridY  = GRAAL_DEFAULT_GRID_Y;
      GraalLambdaGridDx = GRAAL_DEFAULT_GRID_DX;
      GraalLambdaGridDy = GRAAL_DEFAULT_GRID_DY;

      GraalErrorMessage( GraalMainWindow, "Error, working space overflow !" );
    }

    StepX = (float)(GraalGraphicDx) / (float)(GraalLambdaGridDx);
    StepY = (float)(GraalGraphicDy) / (float)(GraalLambdaGridDy);

    if ( StepX < StepY )
    {
      GraalLambdaGridStep = StepX;
      GraalLambdaGridDy   = 1 + ( GraalGraphicDy / StepX );
    }
    else
    {
      GraalLambdaGridStep = StepY;
      GraalLambdaGridDx   = 1 + ( GraalGraphicDx / StepY );
    }

    GraalPixelGridX = (float)(GraalLambdaGridX) * GraalLambdaGridStep;
    GraalPixelGridY = (float)(GraalLambdaGridY) * GraalLambdaGridStep;
  }

/*------------------------------------------------------------\
|                                                             |
|                  GraalResizeLambdaGrid                      |
|                                                             |
\------------------------------------------------------------*/

  char GraalResizeLambdaGrid()

  {
    GraalLambdaGridDx = 1 + ( GraalGraphicDx / GraalLambdaGridStep );
    GraalLambdaGridDy = 1 + ( GraalGraphicDy / GraalLambdaGridStep );

    if ( ( ( GraalLambdaGridX +
             GraalLambdaGridDx ) >  ( GraalWindowXmax / RDS_LAMBDA )) ||
         ( ( GraalLambdaGridY +
             GraalLambdaGridDy ) >  ( GraalWindowYmax / RDS_LAMBDA )) )
    {
      return( GRAAL_FALSE );
    }
    
    return( GRAAL_TRUE );
  }

/*------------------------------------------------------------\
|                                                             |
|                     GraalDisplayLambdaGrid                  |
|                                                             |
\------------------------------------------------------------*/

  char GraalDisplayLambdaGrid( GraphicX1, GraphicY1, GraphicX2, GraphicY2 )

     Dimension GraphicX1;
     Dimension GraphicY1;
     Dimension GraphicX2;
     Dimension GraphicY2;
  {
    long      X;
    long      Y;
    long      MaxGridX;
    long      MaxGridY;
    long      PixelX;
    long      PixelY;
    long      Xmin;
    long      Ymin;
    char      UserGrid;
    char      LambdaGrid;
    char      TraceCroix;
    char      TracePoint;
    float     Check;

    if ( GraalLambdaGridStep < GRAAL_LOWER_GRID_STEP ) 
    {
      LambdaGrid = 0;
    }
    else 
    {
      LambdaGrid = 1;
    }

    if ( GraalLambdaUserGrid == 1  )
    {
      if ( GraalLambdaUserGridDx > GraalLambdaUserGridDy )
      {
        Check = ( GRAAL_LOWER_GRID_STEP * 2 / GraalLambdaUserGridDy );
      }
      else
      {
        Check = ( GRAAL_LOWER_GRID_STEP * 2 / GraalLambdaUserGridDy );
      }

      if ( GraalLambdaGridStep < Check ) UserGrid = 0;
      else                               UserGrid = 1;
    } 
    else
    {
      UserGrid = 0;
    }

    if ( ( UserGrid   == 0 ) &&
         ( LambdaGrid == 0 ) )    return( GRAAL_FALSE );

    MaxGridX = GraalLambdaGridX + GraalLambdaGridDx;
    MaxGridY = GraalLambdaGridY + GraalLambdaGridDy;
 
    if ( LambdaGrid )
    {
      for ( X = GraalLambdaGridX; X < MaxGridX; X = X + 1 )
      {
        PixelX = ((float)(X) * GraalLambdaGridStep);
        PixelX = PixelX - GraalPixelGridX;

        if ( ( PixelX <= GraphicX2 ) &&
             ( PixelX >= GraphicX1 ) )

        for ( Y = GraalLambdaGridY; Y < MaxGridY; Y = Y + 1 )
        {
          PixelY = ((float)(Y) * GraalLambdaGridStep);
          PixelY = PixelY - GraalPixelGridY;
          PixelY = GraalGraphicDy - PixelY;
  
          if ( ( PixelY <= GraphicY2 ) &&
               ( PixelY >= GraphicY1 ) )
          {
            XDrawPoint( XtDisplay( GraalGraphicWindow ),
                        XtWindow( GraalGraphicWindow ),
                        GraalGridGC,
                        PixelX, PixelY );
          }
        }
      }
    }

    if ( UserGrid )
    {
      Xmin  = ( GraalLambdaGridX / GraalLambdaUserGridDx ) * GraalLambdaUserGridDx;
      Ymin  = ( GraalLambdaGridY / GraalLambdaUserGridDy ) * GraalLambdaUserGridDy;

      for ( X = Xmin; X < MaxGridX ; X = X + GraalLambdaUserGridDx )
      {
        PixelX = ((float)(X) * GraalLambdaGridStep);
        PixelX = PixelX - GraalPixelGridX;

        if ( ( PixelX <= GraphicX2 ) &&
             ( PixelX >= GraphicX1 ) )

        for ( Y = Ymin; Y < MaxGridY; Y = Y + GraalLambdaUserGridDy )
        {
          PixelY = ((float)(Y) * GraalLambdaGridStep);
          PixelY = PixelY - GraalPixelGridY;
          PixelY = GraalGraphicDy - PixelY;
  
          if ( ( PixelY <= GraphicY2 ) &&
               ( PixelY >= GraphicY1 ) )
          {
            XDrawLine( XtDisplay( GraalGraphicWindow ),
                       XtWindow( GraalGraphicWindow ),
                       GraalGridGC,
                       PixelX - 2, PixelY,
                       PixelX + 2, PixelY );
                          
            XDrawLine( XtDisplay( GraalGraphicWindow ),
                       XtWindow( GraalGraphicWindow ),
                       GraalGridGC,
                       PixelX, PixelY + 2,
                       PixelX, PixelY - 2 );
          }
        }
      }
    }

    return( GRAAL_TRUE );
  }
