PROGRAM McPAAL;

  { This is the driving program to handle several analysis techniques
    in a menu driven environment. Many of the analysis programs are
    in overlays so all processing can be done from one program }

  CONST
    PI      = 3.1415926535;
    SPACE12 = '            ';
    SPACE15 = '               ';
    SPACE30 = '                              ';
    SPACE32 = '                                ';
    SPACE79 = '                                                                               ';


  TYPE
    NUMS = INTEGER;

    DATETYPE = STRING[8];
    NAME     = STRING[32];
    TXT      = STRING[80];

    RADIOREC = RECORD
               X : REAL;
               Y : REAL;
               Z : REAL;
               DATEV : DATETYPE;
               TIMEV : DATETYPE;
               HOURV : INTEGER;
               LOCATION : INTEGER;
               ACTIVITY : INTEGER;
               SUBJECT_NO : INTEGER;
               RECORD_NO  : INTEGER;
               SEX : CHAR;
               END;

    STUDYREC = RECORD
               X1        : REAL;
               Y1        : REAL;
               X2        : REAL;
               Y2        : REAL;
               Z1        : REAL;
               Z2        : REAL;
               LINE_TYPE : INTEGER;
               END;

    REGISTERS = RECORD
                  CASE INTEGER OF
                    1: (AX,BX,CX,DX,BP,SI,DI,DS,ES,FLAGS : INTEGER);
                    2: (AL,AH,BL,BH,CL,CH,DL,DH          : BYTE);
                END;

    ARRAY100R = ARRAY[1..100] OF REAL;
    ARRAY50I  = ARRAY[1..50]  OF INTEGER;
    ARRAY100I = ARRAY[1..100] OF INTEGER;

  VAR
    HEAP_TOP       : ^INTEGER;    { MARKER FOR MEMORY TO RELEASE }
    GOODRECORD     : BOOLEAN;     { VALID RECORD FLAG IN INPUT FORMATTING }
    KEEP_GOING     : BOOLEAN;     { CONTINUE PROCESSING FLAG }
    RELEASE_FLAG   : BOOLEAN;     { True when stack memory is to be released.}
    REPLAYOPEN     : BOOLEAN;     { TRUE WHEN THE REPLAYFILE IS OPEN }
    STUDYOPEN      : BOOLEAN;     { TRUE WHEN THE STUDYFILE IS OPEN }
    UDOPEN         : BOOLEAN;     { TRUE WHEN THE UDRESTART FILE IS OPEN }

    COLORCHAR      : CHAR;        { USE COLOR ON SCREEN - Y OR N }
    DRAWCHAR       : CHAR;        { DRAW THE POLYGON OPTIONS - Y OR N }
    GRIDCHAR       : CHAR;        { OVERLAY A GRID - Y OR N }
    KEYVALUE       : CHAR;        { KEY PRESSED IN RESPONSE TO A MENU }
    MODULE         : CHAR;        { SELECTION VALUE FOR THE MODULE TO USE }
    PRECISION      : CHAR;        { AREA CALCULATION PRECISION - I OR G }
    PRINTCHAR      : CHAR;        { PRINT OPTIONS - D, P, OR B }
    STUDYDRAWN     : CHAR;        { YES IF STUDY AREA OVERLAY HAS BEEN DRAWN }

    ACTBEGIN       : INTEGER;     { BEGIN COLUMN FOR ACTIVITY }
    ACTEND         : INTEGER;     { END COLUMN FOR ACTIVIEY }
    DATEBEGIN      : INTEGER;     { BEGIN COLUMN FOR DATE }
    DATEEND        : INTEGER;     { END COLUMN FOR DATE }
    GRIDSIZE       : INTEGER;     { SIZE OF GRID USED IN HISTOGRAM }
    HOURBEGIN      : INTEGER;     { BEGIN COLUMN FOR HOUR }
    HOUREND        : INTEGER;     { END COLUMN FOR HOUR }
    LINEBEGIN      : INTEGER;     { BEGIN COLUMN FOR LINE TYPE VARIABLE }
    LINEEND        : INTEGER;     { END COLUMN FOR LINE TYPE VARIABLE }
    LOCBEGIN       : INTEGER;     { BEGIN COLUMN FOR LOCATION }
    LOCEND         : INTEGER;     { END COLUMN FOR LOCATION }
    RECBEGIN       : INTEGER;     { BEGIN COLUMN FOR RECORD NUMBER }
    RECEND         : INTEGER;     { END COLUMN FOR RECORD NUMBER }
    SEXBEGIN       : INTEGER;     { BEGIN COLUMN FOR SUBJECT SEX }
    SEXEND         : INTEGER;     { END COLUMN FOR SUBJECT SEX }
    SPOINTS        : INTEGER;     { TEMPORARY HOLD FOR NUMBER OF POINTS IN FILE }
    SUBNOBEGIN     : INTEGER;     { BEGIN COLUMN FOR SUBJECT NO. }
    SUBNOEND       : INTEGER;     { END COLUMN FOR SUBJECT NO. }
    TIMEBEGIN      : INTEGER;     { BEGIN COLUMN FOR TIME }
    TIMEEND        : INTEGER;     { END COLUMN FOR TIME }
    XBEGIN         : INTEGER;     { BEGIN COLUMN FOR X VARIABLE }
    XEND           : INTEGER;     { END COLUMN FOR X VARIABLE }
    XGRID_NUM      : INTEGER;     { NUMBER OF GRIDS IN X DIRECTION }
    X1BEGIN        : INTEGER;     { BEGIN COLUMN FOR X1 VARIABLE }
    X1END          : INTEGER;     { END COLUMN FOR X1 VARIABLE }
    X2BEGIN        : INTEGER;     { BEGIN COLUMN FOR X2 VARIABLE }
    X2END          : INTEGER;     { END COLUMN FOR X2 VARIABLE }
    YBEGIN         : INTEGER;     { BEGIN COLUMN FOR Y VARIABLE }
    YEND           : INTEGER;     { END COLUMN FOR Y VARIABLE }
    YGRID_NUM      : INTEGER;     { NUMBER OF GRIDS IN THE Y DIRECTION }
    Y1BEGIN        : INTEGER;     { BEGIN COLUMN FOR Y1 VARIABLE }
    Y1END          : INTEGER;     { END COLUMN FOR Y1 VARIABLE }
    Y2BEGIN        : INTEGER;     { BEGIN COLUMN FOR Y2 VARIABLE }
    Y2END          : INTEGER;     { END COLUMN FOR Y2 VARIABLE }
    ZBEGIN         : INTEGER;     { BEGIN COLUMN FOR Z VARIABLE }
    ZEND           : INTEGER;     { END COLUMN FOR Z VARIABLE }
    Z1BEGIN        : INTEGER;     { BEGIN COLUMN FOR Z1 VARIABLE }
    Z1END          : INTEGER;     { END COLUMN FOR Z1 VARIABLE }
    Z2BEGIN        : INTEGER;     { BEGIN COLUMN FOR Z2 VARIABLE }
    Z2END          : INTEGER;     { END COLUMN FOR Z2 VARIABLE }

    AREA           : REAL;        { AREA OF ENCLOSED AREAS - SQ. METERS }
    AREAK          : REAL;        { AREA OF ENCLOSED AREAS - SQ. KILOMETERS }
    GRIDFACTOR     : REAL;        { SCALING FACTOR FOR A GRAPH }
    GRIDHIGH       : REAL;        { MAXIMUM GRID VALUE }
    GRIDLOW        : REAL;        { MINIMUM GRID VALUE }
    GRID_SPAN      : REAL;        { THE MAXIMUM OF XDELTA AND YDELTA }
    METER_SQUARE   : REAL;        { AREA IN SQ. METERS IN GRID OF 1.0 BY 1.0 }
    METER_VALUE    : REAL;        { DISTANCE IN METERS FROM 1.0 TO 2.0 }
    RESVAL         : REAL;        { RESOLUTION TO USE IN THE GRAPHIC ROUTINES }
    SECTION_VALUE  : REAL;        { WIDTH IN METERS OF 1 GRID CELL }
    SXHIGH         : REAL;        { MAX X COORDINATE IN THE STUDY AREA }
    SXLOW          : REAL;        { MIN X COORDINATE IN THE STUDY AREA }
    SYHIGH         : REAL;        { MAX Y COORDINATE IN THE STUDY AREA }
    SYLOW          : REAL;        { MIN Y COORDINATE IN THE STUDY AREA }
    SZHIGH         : REAL;        { MAX Z COORDINATE IN THE STUDY AREA }
    SZLOW          : REAL;        { MIN Z COORDINATE IN THE STUDY AREA }
    TOTAL_METERS   : REAL;        { TOTAL METERS OF ENTIRE X RANGE }
    XDELTA         : REAL;        { THE RANGE OF X VALUES }
    XFACTOR        : REAL;        { SCALING FACTOR FOR THE X COORDINATE }
    XHIGH          : REAL;        { HIGHEST X COORDINATE - MAXIMUM GRID VALUE }
    XLOW           : REAL;        { LOWEST X COORDINATE - MINIMUM GRID VALUE }
    XOFFSET        : REAL;        { TRANSLATION VALUE TO GET ALL X INTO 1 QUAD }
    XSECTIONS      : REAL;        { THE NUMBER OF GRID SECTIONS IN X DIR. }
    YDELTA         : REAL;        { THE RANGE OF THE Y VALUES }
    YFACTOR        : REAL;        { SCALING FACTOR FOR THE Y COORDINATE }
    YHIGH          : REAL;        { HIGHEST Y COORDINATE - MAXIMUM GRID VALUE }
    YLOW           : REAL;        { LOWEST Y COORDINATE - MINIMUM GRID VALUE }
    YOFFSET        : REAL;        { TRANSLATION VALUE TO GET ALL Y INTO 1 QUAD }
    YSECTIONS      : REAL;        { TOTAL NUMBER OF GRID SECTIONS IN Y DIR. }
    ZHIGH          : REAL;        { HIGHEST Z COORDINATE - MAXIMUM GRID VALUE }
    ZLOW           : REAL;        { LOWEST Z COORDINATE - MINIMUM GRID VALUE }
    ZOFFSET        : REAL;        { TRANSLATION VALUE TO GET ALL Z INTO 1 QUAD }
    ZDELTA         : REAL;        { THE RANGE OF THE Z VALUES }
    ZFACTOR        : REAL;        { SCALING FACTOR FOR THE Z COORDINATE }


    DRAWSTR        : STRING[30];  { OPTION TO PLOT POINTS ON SCREEN }
    GRIDSTR        : STRING[10];  { Option to overlay a grid on the graphs. }
    CONFIGFILE     : NAME;        { CONFIGURATION FILE WITH MENU OPTION VALUES }
    FILEIN         : NAME;        { RAW DATA INPUT FILE }
    FILEOUT        : NAME;        { STRUCTURED DATA FILE}
    MAPFILE        : NAME;        { MAP RESULT DATA FROM FFT }
    REPLAYFILE     : NAME;        { VECTORS AND POINTS FROM PLOTS }
    RESTARTFILE    : NAME;        { TEXT FILE FOR HARMONIC RESTART VALUES }
    STUDYFILE      : NAME;        { FORMATTED STUDY AREA FILE }
    STUDYIN        : NAME;        { UNFORMATTED STUDY AREA FILE }
    UDRESTART      : NAME;        { UTILIZATION DISTRIBUTION WORK FILE }
    POINTFILE      : NAME;        { PLOTTER COORDINATES FROM PLOT ON SCREEN }
    PRINTSTR       : STRING[30];  { OPTION TO PRINT DATA ON SCREEN, PRINTER }
    WORKSTR1       : STRING[40];  { A WORK STRING }
    WORKSTR2       : STRING[40];  { A WORK STRING }
    LINE1          : STRING[255]; { BUFFER FOR INPUT DATA }

    FILEVAR1       : TEXT;        { FILE VARIABLE FOR RAW DATA INPUT FILE }
                                  { FILE VARIABLE FOR STUDY FILE INPUT FILE }
                                  { UD WORK FILE IN FFT }
    FILEVAR2       : FILE OF RADIOREC;  { FILE VAR FOR FORMATTED OUTPUT FILE }
    FILE2REC       : RADIOREC;    { DEFINITION OF ONE RECORD }
    FILEVAR3       : FILE OF STUDYREC;  { STUDY AREA IN ALL ANALYSIS }
    FILE3REC       : STUDYREC;    { DEFINITION OF ONE RECORD }
    FILEVAR4       : FILE OF STUDYREC; { REPLAY VECTORS IN ALL ANALYSIS }
    FILE4REC       : STUDYREC;    { DEFINITION OF ONE RECORD }
    FILEVAR5       : TEXT;        { MAP RESULT OUTPUT DATA IN FFT }
                                  { PLOT POINT FILE IN CONCAVE }
    FILEVAR6       : TEXT;        { RESTART FILE IN HARMONIC  }
    FILEVAR7       : TEXT;        { FILE WITH CONFIGURATION VALUES }
    REGS           : REGISTERS;   { Record for MsDOS calls. }

{ ************************************************************************ }
{ ****************  FUNCTIONS  ******************************************* }

  FUNCTION EXIST(FILENAME : NAME) : BOOLEAN;

    { FUNCTION TO SEE IF A FILE EXISTS }

    VAR
      FIL : FILE;

    BEGIN  { EXIST FUNCTION }
      ASSIGN(FIL, FILENAME);
      {$I-}
      RESET (FIL);
      CLOSE (FIL);       {This is where EAB solved the I/O Error (too many files open}
      {$I+}
      EXIST := (IORESULT = 0);
    END;  { EXIST FUNCTION }

  FUNCTION STUDY_IN_REPLAY : BOOLEAN;

    { Function to see if the study area is already in the replay file. }

    BEGIN  { STUDY_IN_REPLAY FUNCTION }

      ASSIGN (FILEVAR4,REPLAYFILE);
      RESET  (FILEVAR4);
      SEEK   (FILEVAR4,2);        { THIRD RECORD IN THE FILE }
      READ   (FILEVAR4,FILE4REC);
      IF FILE4REC.X1 = 0.0
        THEN STUDY_IN_REPLAY := FALSE
        ELSE STUDY_IN_REPLAY := TRUE;
    END;  { STUDY_IN_REPLAY FUNCTION }

  FUNCTION MAX_VAL(V1 : REAL;
                   V2 : REAL) : REAL;

    BEGIN
      IF V1 > V2
        THEN MAX_VAL := V1
        ELSE MAX_VAL := V2;
    END;  { MAX_VAL FUNCTION }

  FUNCTION MIN_VAL(V1 : REAL;
                   V2 : REAL) : REAL;

    BEGIN
      IF V1 < V2
        THEN MIN_VAL := V1
        ELSE MIN_VAL := V2;
    END;  { MIN_VAL FUNCTION }

  FUNCTION MEMORY_LEFT : REAL;

    { CHECKS THE AMOUNT OF MEMORY LEFT ON THE HEAP }

    BEGIN  { MEMORY_LEFT FUNCTION }

      IF MEMAVAIL < 0
        THEN MEMORY_LEFT := 65536.0 + MEMAVAIL
        ELSE MEMORY_LEFT := MEMAVAIL;

    END;  { MEMORY_LEFT FUNCTION }

{ ************************************************************************ }
{ *************  COMMONLY CALLED PROCEDURES  ***************************** }

  PROCEDURE CLEAR_BUFFER_;

    { Clears the keyboard buffer of the 'cr' after a READ is performed. }
    VAR
      TEMP : CHAR;

    BEGIN
      GOTOXY(1,24);
      READLN (INPUT,TEMP);
    END;  { CLEAR BUFFER }

  PROCEDURE YES_NO(VAR ASKVAR : CHAR);

    { PROCEDURE TO GET A YES OR NO FROM THE USER }

    BEGIN  { YES_NO PROCEDURE }
      ASKVAR := ' ';
      WHILE NOT(UPCASE(ASKVAR) IN ['Y','N']) DO
        READ   (KBD,ASKVAR);
      ASKVAR := UPCASE(ASKVAR);
    END;  { YES_NO PROCEDURE }

  PROCEDURE ADD_GRAPH(GRAPH_TYPE : TXT);

    { PROCEDURE TO ADD A GRAPH TO THE REPLAY FILE }

    BEGIN  { ADD_GRAPH PROCEDURE }
      IF GRAPH_TYPE = 'STUDYFILE' THEN
        IF NOT STUDY_IN_REPLAY THEN
          BEGIN
            SEEK(FILEVAR3,1);               { RECORD 2 OF STUDY FILE }
            READ(FILEVAR3,FILE3REC);

            SEEK(FILEVAR4,1);               { RECORD 2 OF REPLAY FILE }
            READ(FILEVAR4,FILE4REC);

            FILE4REC.X1 := MIN_VAL(FILE3REC.X1,FILE4REC.X1);
            FILE4REC.Y1 := MIN_VAL(FILE3REC.Y1,FILE4REC.Y1);
            FILE4REC.Z1 := MIN_VAL(FILE3REC.Z1,FILE4REC.Z1);
            FILE4REC.X2 := MAX_VAL(FILE3REC.X2,FILE4REC.X2);
            FILE4REC.Y2 := MAX_VAL(FILE3REC.Y2,FILE4REC.Y2);
            FILE4REC.Z2 := MAX_VAL(FILE3REC.Z2,FILE4REC.Z2);
            FILE4REC.LINE_TYPE := FILE4REC.LINE_TYPE + FILE3REC.LINE_TYPE;

            SEEK(FILEVAR4,1);               { RECORD 2 WRITE OF REPLAY FILE }
            WRITE(FILEVAR4,FILE4REC);

            READ(FILEVAR4,FILE4REC);        { RECORD 3 OF REPLAY }

            FILE4REC.X2 := FILE4REC.X2 + 1; { INCREMENT NUMBER OF GRAPHS IN FILE }
            FILE4REC.Y1 := FILE4REC.X2;     { MARK WHICH FILE IS THE STUDY FILE }
            FILE4REC.X1 := 1;

            SEEK (FILEVAR4,2);
            WRITE(FILEVAR4,FILE4REC);
            SEEK (FILEVAR4,FILESIZE(FILEVAR4)-1);
            READ (FILEVAR4,FILE4REC);       { LAST RECORD OF THE REPLAY FILE }

            FILE4REC.X1 := -2;
            FILE4REC.Y1 := -10;
            FILE4REC.X2 := -10;
            FILE4REC.Y2 := -10;

            SEEK (FILEVAR4,FILESIZE(FILEVAR4)-1);
            WRITE(FILEVAR4,FILE4REC);

            FILE4REC := FILE3REC;
            WRITE(FILEVAR4,FILE4REC);

            WHILE NOT EOF(FILEVAR3) DO
              BEGIN
                READ(FILEVAR3,FILE3REC);
                FILE4REC := FILE3REC;
                WRITE(FILEVAR4,FILE4REC);
              END;

          END;  { IF NOT STUDY IN REPLAY }

      IF GRAPH_TYPE = 'DATAFILE' THEN
        BEGIN

          SEEK(FILEVAR4,1);
          READ(FILEVAR4,FILE4REC);
          SEEK(FILEVAR2,1);
          READ(FILEVAR2,FILE2REC);

          SXLOW := FILE2REC.X;
          SYLOW := FILE2REC.Y;
          SZLOW := FILE2REC.Z;
          SPOINTS := FILE2REC.RECORD_NO;
          FILE4REC.X1 := MIN_VAL(FILE4REC.X1,FILE2REC.X);
          FILE4REC.Y1 := MIN_VAL(FILE4REC.Y1,FILE2REC.Y);
          FILE4REC.Z1 := MIN_VAL(FILE4REC.Z1,FILE2REC.Z);

          READ(FILEVAR2,FILE2REC);

          SXHIGH := FILE2REC.X;
          SYHIGH := FILE2REC.Y;
          SZHIGH := FILE2REC.Z;
          FILE4REC.X2 := MAX_VAL(FILE4REC.X2,FILE2REC.X);
          FILE4REC.Y2 := MAX_VAL(FILE4REC.Y2,FILE2REC.Y);
          FILE4REC.Z2 := MAX_VAL(FILE4REC.Z2,FILE2REC.Z);
          FILE4REC.LINE_TYPE := FILE4REC.LINE_TYPE + SPOINTS;

          SEEK (FILEVAR4,1);
          WRITE(FILEVAR4,FILE4REC);         { WRITE OUT RECORD 2 }
          READ (FILEVAR4,FILE4REC);         { READ RECORD 3 }

          FILE4REC.X2 := FILE4REC.X2 + 1;   { NUMBER OF GRAPHS IN FILE }
          FILE4REC.Z1 := FILE4REC.X2;       { GRAPH NUMBER OF THE DATA FILE }

          SEEK (FILEVAR4,2);
          WRITE(FILEVAR4,FILE4REC);

          SEEK (FILEVAR4,FILESIZE(FILEVAR4)-1);  { LAST RECORD IN FILE }
          READ (FILEVAR4,FILE4REC);

          FILE4REC.X1 := -1;
          FILE4REC.Y1 := -10;
          FILE4REC.X2 := -10;
          FILE4REC.Y2 := -10;

          SEEK (FILEVAR4,FILESIZE(FILEVAR4)-1);  { LAST RECORD IN FILE }
          WRITE(FILEVAR4,FILE4REC);

          FILE4REC.X1 := SXLOW;             { BUILD SECOND GRAPH HEADER }
          FILE4REC.Y1 := SYLOW;
          FILE4REC.Z1 := SZLOW;
          FILE4REC.X2 := SXHIGH;
          FILE4REC.Y2 := SYHIGH;
          FILE4REC.Z2 := SZHIGH;
          FILE4REC.LINE_TYPE := SPOINTS;
          WRITE(FILEVAR4,FILE4REC);

          FILE4REC.X2 := 0.0;
          FILE4REC.Y2 := 0.0;
          FILE4REC.Z2 := 0.0;
          FILE4REC.LINE_TYPE := 0;

          WHILE NOT EOF(FILEVAR2) DO
            BEGIN
              READ (FILEVAR2,FILE2REC);
              FILE4REC.X1 := FILE2REC.X;
              FILE4REC.Y1 := FILE2REC.Y;
              FILE4REC.Z1 := FILE2REC.Z;
              WRITE(FILEVAR4,FILE4REC);
            END;  { WHILE NOT EOF(FILEVAR2) }

        END;  { IF GRAPH_TYPE = DATAFILE }

      { WRITE OUT THE TRAILER/HEADER RECORD }

      FILE4REC.X1 := 0.0;
      FILE4REC.Y1 := 0.0;
      FILE4REC.Z1 := 0.0;
      FILE4REC.X2 := 0.0;
      FILE4REC.Y2 := 0.0;
      FILE4REC.Z2 := 0.0;
      FILE4REC.LINE_TYPE := 0;
      WRITE (FILEVAR4,FILE4REC);

    END;  { ADD_GRAPH PROCEDURE }

  PROCEDURE INIT_REPLAY_FILE;

    { PROCEDURE TO INITIALIZE THE PLOT REPLAY FILE }

    BEGIN  { INIT_REPLAY_FILE PROCEDURE }

      ASSIGN (FILEVAR4,REPLAYFILE);
      REWRITE (FILEVAR4);

      WITH FILE4REC DO
        BEGIN
          X1 := -3.0;             { RECORD 1 THE IDENTITY RECORD FOR THE FILE }
          Y1 := -4.0;
          X2 := -7.0;
          Y2 := -9.0;
          Z1 :=  0.0;
          Z2 :=  0.0;
          LINE_TYPE := -10;

          WRITE (FILEVAR4,FILE4REC);

          X1 := 10000.0;
          Y1 := 10000.0;          { MIN AND MAX VALUES FOR ENTIRE FILE }
          X2 := -1000.0;          { LINE TYPE HAS TOTAL POINTS FOR ENTIRE FILE }
          Y2 := -1000.0;
          Z1 := 10000.0;
          Z2 := -1000.0;
          LINE_TYPE := 0;

          WRITE (FILEVAR4,FILE4REC);

          X1 := 0.0;
          Y1 := 0.0;
          Z1 := 0.0;
          X2 := 0.0;
          Y2 := 0.0;
          Z2 := 0.0;

          WRITE (FILEVAR4,FILE4REC); { RECORD 3 HAS STATUS OF STUDY FILE IN THE
                                       REPLAY FILE }
          WRITE (FILEVAR4,FILE4REC); { LAST RECORD IS ALWAYS THE FIRST RECORD OF
                                       NEXT FILE TO BE ADDED. }

        END;  { WITH FILE4REC DO }

      CLOSE (FILEVAR4);

    END;  { INIT_REPLAY_FILE PROCEDURE }

  PROCEDURE METERS_TO_GRIDS ( VAR VDELTA      : REAL;
                              VAR NUMBER_GRID : INTEGER );

    { PROCEDURE TO CALCULATE THE NUMBER OF GRIDS ACROSS A HOME RANGE
      OR STUDY AREA. }
    VAR
      SECTIONS     : REAL;        { A REAL WORK VARIABLE }

    BEGIN  { METERS_TO_GRIDS PROCEDURE }
      TOTAL_METERS := METER_VALUE * VDELTA;
      SECTIONS     := TOTAL_METERS / SECTION_VALUE;
      NUMBER_GRID  := TRUNC(SECTIONS);
      IF FRAC(SECTIONS) > 0 THEN NUMBER_GRID := NUMBER_GRID + 1;
      VDELTA       := NUMBER_GRID * SECTION_VALUE / METER_VALUE;
    END;   { METERS_TO_GRIDS PROCEDURE }

  PROCEDURE VERIFY_DATA_FILE;

    { PROCEDURE TO VERIFY THAT A DATA FILE IS BEING USED AS DATA INPUT }

    BEGIN  { VERIFY_DATA_FILE PROCEDURE }
      ASSIGN (FILEVAR2,FILEOUT);
      RESET  (FILEVAR2);

      READ (FILEVAR2,FILE2REC);

      { NEXT LOGIC STRUCTURE DOES THIS. IF IT IS NOT A VALID DATA FILE, THEN
        THE IDENTIFYING RECORD IS RETURNED IN XLOW, YLOW, AND ZLOW. IF IT IS
        A VALID DATA RECORD, THEN THE NEXT RECORD IS READ AND THE MIN AND MAX
        VALUES ARE RETURNED. }

      IF (FILE2REC.X <> -1) OR (FILE2REC.Y <> -2) OR (FILE2REC.Z <> -3)
        THEN KEEP_GOING := FALSE
        ELSE READ (FILEVAR2,FILE2REC);

      XLOW := FILE2REC.X;
      YLOW := FILE2REC.Y;
      ZLOW := FILE2REC.Z;

      READ (FILEVAR2,FILE2REC);

      XHIGH := FILE2REC.X;
      YHIGH := FILE2REC.Y;
      ZHIGH := FILE2REC.Z;
      XDELTA := XHIGH - XLOW;
      YDELTA := YHIGH - YLOW;
      ZDELTA := ZHIGH - ZLOW;

      CLOSE (FILEVAR2);

    END;  { VERIFY_DATA_FILE PROCEDURE }

  PROCEDURE VERIFY_STUDY_AREA_FILE;

    { PROCEDURE TO VERIFY THAT A STUDY AREA FILE IS BEING USED AS A STUDY AREA }

    BEGIN  { VERIFY_STUDY_AREA_FILE PROCEDURE }
      ASSIGN (FILEVAR3,STUDYFILE);
      RESET  (FILEVAR3);

      READ (FILEVAR3,FILE3REC);

      { The following logic structure works in the same way as the explanation
        for the VERIFY_DATA_FILE explaination. }

      IF (FILE3REC.X1 <> -5) OR (FILE3REC.Y1 <> -3) OR (FILE3REC.X2 <> -7)
        THEN KEEP_GOING := FALSE
        ELSE READ (FILEVAR3,FILE3REC);

      SXLOW  := FILE3REC.X1;
      SYLOW  := FILE3REC.Y1;
      SZLOW  := FILE3REC.Z1;
      SXHIGH := FILE3REC.X2;
      SYHIGH := FILE3REC.Y2;
      SZHIGH := FILE3REC.Z2;

      CLOSE (FILEVAR3);

    END;  { VERIFY_STUDY_AREA_FILE PROCEDURE }

  PROCEDURE VERIFY_REPLAY_FILE;

    { PROCEDURE TO VERIFY THAT A REPLAY FILE IS BEING USED AS A REPLAY FILE. }

    BEGIN  { VERIFY_REPLAY_FILE PROCEDURE }

      ASSIGN (FILEVAR4,REPLAYFILE);
      RESET  (FILEVAR4);

      READ   (FILEVAR4,FILE4REC);

      { With the replay file, the only time the s-min and s-max values are
        modified is when an invalid replay file is given. Processing is halted
        by the KEEP_GOING flag being false. }

      IF (FILE4REC.X1 <> -3) OR (FILE4REC.Y1 <> -4) OR (FILE4REC.X2 <> -7) THEN
        BEGIN
          KEEP_GOING := FALSE;

          SXLOW  := FILE4REC.X1;
          SYLOW  := FILE4REC.Y1;
          SZLOW  := FILE4REC.Z1;
          SXHIGH := FILE4REC.X2;
          SYHIGH := FILE4REC.Y2;
          SZHIGH := FILE4REC.Z2;
        END;

      CLOSE (FILEVAR4);

    END;  { VERIFY_REPLAY_FILE PROCEDURE }

  PROCEDURE CAPIT(VAR WORKWORD : NAME);

    VAR
      I       : INTEGER;          { A WORK COUNTER }

    BEGIN
      FOR I := 1 TO LENGTH(WORKWORD) DO
        WORKWORD[I] := UPCASE(WORKWORD[I]);

    END;  { CAPIT PROCEDURE }

  PROCEDURE LINE_OUT(SCOL, ECOL : NUMS; MSGTEXT : TXT);

    { This procedure displays a line of text at the screen positions
      given by scol and ecol. The text is in the parameter msgtext }

    BEGIN;
      GOTOXY(SCOL,ECOL);
      WRITE (OUTPUT,MSGTEXT);
    END;  { LINE_OUT PROCEDURE }

  PROCEDURE PROCESSING_VERIFY;

    { PROCEDURE TO SEE IF ALL FILES MEET REQUIREMENTS }

    BEGIN  { PROCESSING_VERIFY PROCEDURE }

      IF MODULE = 'A' THEN
        IF (FILEOUT = '') THEN
          BEGIN
            IF RESTARTFILE = '' THEN
              BEGIN
                LINE_OUT(1,23,'The input data set must be defined.');
                KEEP_GOING := FALSE;
              END;

            IF (KEEP_GOING) AND (NOT EXIST(RESTARTFILE)) THEN
              BEGIN
                GOTOXY(1,23);
                WRITE('The Harmonic Restart file ',RESTARTFILE,' does not exist.');
                KEEP_GOING := FALSE;
              END;

            IF KEEP_GOING THEN
              BEGIN

                { VERIFY THAT THE GIVEN FILE IS A RESTART FILE }

                ASSIGN (FILEVAR6,RESTARTFILE);
                RESET  (FILEVAR6);

                READLN (FILEVAR6,LINE1);
                IF COPY(LINE1,1,7) <> 'RESTART' THEN
                  BEGIN
                    GOTOXY(1,23);
                    WRITE('The given file ',RESTARTFILE,' is not a valid restart file.');
                    KEEP_GOING := FALSE;
                  END;

                CLOSE (FILEVAR6);

              END;

          END    { IF FILEOUT = '' }
        ELSE
          IF EXIST(RESTARTFILE) THEN
            BEGIN
              LINE_OUT(1,23,'The restart file already exists. Do you want to erase it? (Y|N) ');
              YES_NO(KEYVALUE);
              IF KEYVALUE = 'N' THEN KEEP_GOING := FALSE;
            END;


      IF (MODULE <> 'A') OR ((MODULE = 'A') AND (FILEOUT <> '')) THEN
      BEGIN

      IF FILEOUT = '' THEN
        BEGIN
          LINE_OUT(1,23,'The input data set must be defined.');
          KEEP_GOING := FALSE;
        END;

      IF (KEEP_GOING) AND (NOT EXIST(FILEOUT)) THEN
        BEGIN
          GOTOXY(1,23);
          WRITE('Formatted data file ',FILEOUT,' does not exist.');
          KEEP_GOING := FALSE;
        END;

       IF KEEP_GOING THEN
         BEGIN
           VERIFY_DATA_FILE;
           IF NOT KEEP_GOING THEN
             BEGIN
               GOTOXY(1,23);
               WRITE('The input file ',FILEOUT,' is not a formatted data file.');
               IF (XLOW = -5) AND (YLOW = -3) AND (ZLOW = -7)
                 THEN LINE_OUT(1,24,'It is a formatted STUDY AREA file.')

                 ELSE IF (XLOW = -3) AND (YLOW = -4) AND (ZLOW = -7)
                        THEN LINE_OUT(1,24,'It is a PLOT REPLAY file.')
                        ELSE LINE_OUT(1,24,'It may be an unformatted data file or a version 1.0 file.');
             END;
         END;

      END;  { IF MODULE <> 'A' }

      IF (KEEP_GOING) AND (STUDYFILE <> '') THEN
        IF NOT EXIST(STUDYFILE) THEN
          BEGIN
            GOTOXY(1,23);
            WRITE('Formatted study area file ',STUDYFILE,' does not exist.');
            KEEP_GOING := FALSE;
          END;

      IF (KEEP_GOING) AND (STUDYFILE <> '') THEN
        BEGIN
          VERIFY_STUDY_AREA_FILE;
          IF NOT KEEP_GOING THEN
            BEGIN
              GOTOXY(1,23);
              WRITE('The study area file ',STUDYFILE,' is not a formatted study area file.');
              IF (SXLOW = -1) AND (SYLOW = -2) AND (SXHIGH = -3)
                THEN LINE_OUT(1,24,'It is a formatted INPUT DATA file.')
                ELSE IF (SXLOW = -3) AND (SYLOW = -4) AND (SXHIGH = -7)
                  THEN LINE_OUT(1,24,'It is a PLOT REPLAY file.')
                  ELSE LINE_OUT(1,24,'It may be an unformatted data file or unformatted study area file.');
            END;
        END;

     IF (KEEP_GOING) AND (REPLAYFILE <> '') THEN
       IF EXIST(REPLAYFILE) THEN
         BEGIN
           VERIFY_REPLAY_FILE;
           IF NOT KEEP_GOING THEN
             BEGIN
               GOTOXY(1,23);
               WRITE('The plot replay file ',REPLAYFILE,' is not a plot file.');
               IF (SXLOW = -1) AND (SYLOW = -2) AND (SXHIGH = -3)
                 THEN LINE_OUT(1,24,'It is a formatted INPUT DATA file.')
                 ELSE IF (SXLOW = -5) AND (SYLOW = -3) AND (SXHIGH = -7)
                   THEN LINE_OUT(1,24,'It is a formatted STUDY AREA file.')
                   ELSE LINE_OUT(1,24,'It may be an unformatted data file or an unformatted study area file.');
             END;

         END;  { IF EXIST REPLAYFILE }

    END;  { PROCESSING_VERIFY PROCEDURE }

  PROCEDURE MENU_CALL ( REQUESTED_SELECTION : INTEGER );

    { PROCEDURE TO PERFORM MANY OF THE COMMONLY USED MENU TERMS }

    BEGIN
      CASE REQUESTED_SELECTION OF
        1 : BEGIN
            LINE_OUT(1,22,'様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様');
            LINE_OUT(1,23,' Enter the name of the formatted INPUT data file: ');
            READLN    (INPUT,FILEOUT);
            CAPIT   (FILEOUT);
            GOTOXY(1,24);
            DELLINE;
            GOTOXY(1,23);
            DELLINE;
            GOTOXY(1,22);
            DELLINE;
            LINE_OUT(24,4,SPACE15);
            LINE_OUT(24,4,FILEOUT);
            END;
        2 : BEGIN
            LINE_OUT(1,22,'様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様');
            LINE_OUT(1,23,' Enter the name of the formatted STUDY AREA file: ');
            READLN    (INPUT,STUDYFILE);
            CAPIT   (STUDYFILE);
            GOTOXY(1,24);
            DELLINE;
            GOTOXY(1,23);
            DELLINE;
            GOTOXY(1,22);
            DELLINE;
            LINE_OUT(30,6,SPACE15);
            LINE_OUT(30,6,STUDYFILE);
            END;
        3 : BEGIN
            LINE_OUT(1,22,'様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様');
            LINE_OUT(1,23,' Enter the name of the PLOT REPLAY file: ');
            READLN    (INPUT,REPLAYFILE);
            CAPIT   (REPLAYFILE);
            GOTOXY(1,24);
            DELLINE;
            GOTOXY(1,23);
            DELLINE;
            GOTOXY(1,22);
            DELLINE;
            LINE_OUT(31,8,SPACE15);
            LINE_OUT(31,8,REPLAYFILE);
            END;
        4 : BEGIN
            LINE_OUT(1,22,'様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様');
            LINE_OUT(1,23,' Display text on D - SCREEN, (P)RINTER, (B)OTH: ');
            PRINTCHAR := ' ';
            WHILE NOT (UPCASE(PRINTCHAR) IN ['D','P','B']) DO
              READ (KBD,PRINTCHAR);
            PRINTCHAR := UPCASE(PRINTCHAR);
            GOTOXY(1,24);
            DELLINE;
            GOTOXY(1,23);
            DELLINE;
            GOTOXY(1,22);
            DELLINE;
            CASE PRINTCHAR OF
              'D' : PRINTSTR := 'DISPLAY ONLY';
              'P' : PRINTSTR := 'PRINTER ONLY';
              'B' : PRINTSTR := 'BOTH DISPLAY AND PRINTER';
            END;
            LINE_OUT(39,10,SPACE30);
            LINE_OUT(39,10,PRINTSTR);
            END;
        5 : BEGIN
            LINE_OUT(1,22,'様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様');
            LINE_OUT(1,23,' Display graphics on the screen? (Y|N): ');
            DRAWCHAR := ' ';
            WHILE NOT (UPCASE(DRAWCHAR) IN ['N','Y']) DO
              READ (KBD,DRAWCHAR);
            GOTOXY(1,24);
            DELLINE;
            GOTOXY(1,23);
            DELLINE;
            GOTOXY(1,22);
            DELLINE;
            DRAWCHAR := UPCASE(DRAWCHAR);
            IF DRAWCHAR = 'N'
              THEN DRAWSTR := 'NO'
              ELSE DRAWSTR := 'YES';
            LINE_OUT(49,12,SPACE15);
            LINE_OUT(49,12,DRAWSTR);
            END;
        6 : BEGIN
            LINE_OUT(1,22,'様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様');
            LINE_OUT(1,23,' Calculate the area by (i)ntegration or (g)rid cell count: ');
            PRECISION := ' ';
            WHILE NOT (UPCASE(PRECISION) IN ['I','G']) DO
              READ    (KBD,PRECISION);
            PRECISION := UPCASE(PRECISION);
            GOTOXY(1,24);
            DELLINE;
            GOTOXY(1,23);
            DELLINE;
            GOTOXY(1,22);
            DELLINE;
            LINE_OUT(41,14,SPACE32);
            IF PRECISION = 'I'
              THEN LINE_OUT(41,14,'INTEGRATION')
              ELSE LINE_OUT(41,14,'GRID CELL COUNT');
            END;
        7 : BEGIN
            LINE_OUT(1,22,'様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様');
            LINE_OUT(1,23,' Enter the width of any one grid cell (in meters): ');
            READLN  (INPUT,SECTION_VALUE);
            GOTOXY(1,24);
            DELLINE;
            GOTOXY(1,23);
            DELLINE;
            GOTOXY(1,22);
            DELLINE;
            LINE_OUT(45,16,SPACE15);
            GOTOXY(45,16);
            WRITE (SECTION_VALUE:8:4);
            END;
        8 : BEGIN
            LINE_OUT(1,22,'様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様');
            LINE_OUT(1,23,' Enter the distance in meters between any two adjacent full coordinates, i.e.');
            LINE_OUT(1,24,' coordinates 1|0 and 2|0 or 1456.87|999.01 and 1457.87|999.01: ');
            READLN  (INPUT,METER_VALUE);
            GOTOXY(1,24);
            DELLINE;
            GOTOXY(1,23);
            DELLINE;
            GOTOXY(1,22);
            DELLINE;
            LINE_OUT(69,18,SPACE15);
            GOTOXY(69,18);
            WRITE (METER_VALUE:8:4);
            END;

      END;  { CASE REQUESTED_SELECTION OF }

    END;  { MENU_CALL PROCEDURE }

  PROCEDURE DISPLAY_COLOR(COLOUR : INTEGER);

    { Sets the display output to the color in the argument if colorchar is Y }

    BEGIN

      IF COLORCHAR = 'Y'
        THEN TEXTCOLOR(COLOUR)
        ELSE TEXTCOLOR(WHITE);

    END;  { DISPLAY_COLOR PROCEDURE }

  PROCEDURE KEYBOARD_PAUSE;

    { Displays 'press any key' message and waits for user to press a key. }

    BEGIN
      LINE_OUT(1,25,SPACE79);
      GOTOXY(1,25);
      WRITE (OUTPUT,'Press any key to continue.');
      READ  (KBD,KEYVALUE);
    END;  { KEYBOARD_PAUSE }


  PROCEDURE CURVE_AREA(VAR X1,Y1,X2,Y2,SUM : REAL);

    { THIS PROCEDURE GETS THE AREA UNDER A STRAIGHT LINE CURVE BY
      INTEGRATION. THE (X1,Y1) IS THE BEGINNING POINT AND THE (X2,Y2)
      IS THE ENDING POINT. THE AREA UNDER THE CURVE IS PASSED BACK IN
      THE VARIABLE SUM. }

    VAR
      INTERCEPT : REAL;           { Y INTERCEPT OF THE LINE }
      SLOPE   : REAL;             { SLOPE OF THE LINE }

    BEGIN  { CURVE_AREA PROCEDURE }

      { CALCULATE THE SLOPE AND THE INTERCEPT }

      IF X2 = X1 THEN
        SUM := 0
      ELSE
        BEGIN
          SLOPE := ( Y2 - Y1 ) / ( X2 - X1 );
          IF SLOPE = 0 THEN
            SUM := ABS(( X2 - X1 ) * Y1)
          ELSE
            BEGIN
              INTERCEPT := Y1 - ( SLOPE * X1 );
              SUM := (SLOPE*(X2 * X2)/2 + INTERCEPT*X2);
              SUM := ABS(SUM - (SLOPE*(X1 * X1)/2 + INTERCEPT * X1));
            END;
        END;

    END;  { CURVE_AREA PROCEDURE }


  PROCEDURE REVERSE(VAR RSTRING : TXT);

    { Reverses the order of the characters in the string RSTRING }

    VAR
      LEN_RSTRING : INTEGER;      { LENGTH OF ARGUMENT }
      LEN_PLUS1   : INTEGER;      { LENGTH OF ARGUMENT + 1 }
      I           : INTEGER;      { A WORK VARIABLE }
      WSTRING     : TXT;          { A WORK STRING VARIABLE }

    BEGIN  { REVERSE }

      WSTRING     := RSTRING;
      LEN_RSTRING := LENGTH(RSTRING);
      LEN_PLUS1   := LEN_RSTRING + 1;
      FOR I := LEN_RSTRING DOWNTO 1 DO
        WSTRING[LEN_PLUS1 - I] := RSTRING[I];
      RSTRING     := WSTRING;

    END;  { REVERSE PROCEDURE }

  PROCEDURE BLANK_TRIM(VAR BSTRING : TXT);

    { Procedure to trim the leading and trailing blanks from a value.}

    VAR
      R_FLAG  : BOOLEAN;          { TRUE IF BSTRING IS REVERSED }

      B_POS   : INTEGER;          { POSITION OF A BLANK IN BSTRING }
      B_LEN   : INTEGER;          { LENGTH OF THE BSTRING }

    BEGIN  { BLANK_TRIM }

      R_FLAG     := FALSE;

      B_POS := POS(' ',BSTRING);
      B_LEN := LENGTH(BSTRING);

      WHILE (B_POS > 0) AND (GOODRECORD) DO
        BEGIN
          IF B_POS > 1 THEN
            BEGIN
              REVERSE(BSTRING);
              R_FLAG := TRUE;
              B_POS  := POS(' ',BSTRING);
              IF B_POS > 1
                THEN GOODRECORD := FALSE
                ELSE BSTRING := COPY(BSTRING,2,B_LEN-1);
            END
          ELSE
            BSTRING := COPY(BSTRING,2,B_LEN-1);
          B_POS := POS(' ',BSTRING);
          B_LEN := LENGTH(BSTRING);

        END;  { WHILE B_POS > 0 AND GOODRECORD }

      IF R_FLAG THEN REVERSE(BSTRING);

    END;  { BLANK_TRIM }

  PROCEDURE COLOR_QUESTION;

    { ASK USER IF HE HAS A COLOR MONITOR. RESPONSE IS USED TO CONTROL
      COLOR ON OTHER SCREENS }

    BEGIN
      CLRSCR;
      GOTOXY(5,10);
      WRITE ('Are you using a color monitor (Y|N) ');
      COLORCHAR := ' ';
      WHILE NOT (UPCASE(COLORCHAR) IN ['Y','N']) DO
        READ (KBD,COLORCHAR);
      COLORCHAR := UPCASE(COLORCHAR);
    END; { COLOR_QUESTION PROCEDURE }

  PROCEDURE GRID_CALCULATIONS;

    { Common routine to get the plotting factors to put out a square grid
      of a plot on the screen. }

    BEGIN  { GRID_CALCULATIONS PROCEDURE }

      XDELTA := XHIGH - XLOW;
      YDELTA := YHIGH - YLOW;

      IF XDELTA > YDELTA THEN
        BEGIN
          GRID_SPAN := XDELTA;
          GRIDLOW   := XLOW;
          GRIDHIGH  := XHIGH;
        END
      ELSE
        BEGIN
          GRID_SPAN := YDELTA;
          GRIDLOW   := YLOW;
          GRIDHIGH  := YHIGH;
        END;

      XOFFSET := -( XLOW - 0.5 * ( GRID_SPAN - XDELTA ));
      YOFFSET := -( YLOW - 0.5 * ( GRID_SPAN - YDELTA ));

      IF XHIGH = XLOW
        THEN XFACTOR := 1
        ELSE XFACTOR := 600 / (( GRID_SPAN * 16 / 5 ));

      IF YHIGH = YLOW
        THEN YFACTOR := 1
        ELSE YFACTOR := 180 / (( GRID_SPAN * 4 / 3 ));

      IF XFACTOR < YFACTOR
        THEN GRIDFACTOR := XFACTOR
        ELSE GRIDFACTOR := YFACTOR;

    END;  { GRID_CALCULATIONS PROCEDURE }

  PROCEDURE HIRES_POINT ( X1      : REAL;
                          Y1      : REAL;
                          XOFFSET : REAL;
                          YOFFSET : REAL;
                          FACTOR  : REAL);

    { Procedure to plot one point in high resolution graphics }

    VAR
      X1I     : INTEGER;          { X VALUE TO BE PLOTTED }
      Y1I     : INTEGER;          { Y VALUE TO BE PLOTTED }

    BEGIN  { HIRES_POINT }

      X1  := ( X1 + XOFFSET ) * 16 / 5 * FACTOR;
      Y1  := ( Y1 + YOFFSET ) *  4 / 3 * FACTOR;
      X1I := ROUND(X1 + 20);
      Y1I := 180 - ROUND(Y1);
      Y1I := Y1I + 10;
      PLOT(X1I,Y1I,1);

    END;  { HIRES_POINT }

  PROCEDURE HIRES_VECTOR( X1      : REAL;
                          Y1      : REAL;
                          X2      : REAL;
                          Y2      : REAL;
                          XOFFSET : REAL;
                          YOFFSET : REAL;
                          FACTOR  : REAL);

    { Procedure to draw a high resolution vector from the point X1,Y1
      to the point X2,Y2. The factor and offset values are scaling
      factors used to get the diagram into the window. }

    VAR
      X1I     : INTEGER;          { X1 TO BE PLOTTED }
      X2I     : INTEGER;          { X2 TO BE PLOTTED }
      Y1I     : INTEGER;          { Y1 TO BE PLOTTED }
      Y2I     : INTEGER;          { Y2 TO BE PLOTTED }

    BEGIN  { HIRES_VECTOR PROCEDURE }
      X1  := (X1 + XOFFSET) * 16 / 5 * FACTOR;
      X2  := (X2 + XOFFSET) * 16 / 5 * FACTOR;
      Y1  := (Y1 + YOFFSET) * 4  / 3 * FACTOR;
      Y2  := (Y2 + YOFFSET) * 4  / 3 * FACTOR;
      X1I := ROUND(X1 + 20);
      Y1I := 180 - ROUND(Y1);
      X2I := ROUND(X2 + 20);
      Y2I := 180 - ROUND(Y2);
      Y1I := Y1I + 10;
      Y2I := Y2I + 10;
      DRAW(X1I,Y1I,X2I,Y2I,1);
    END;  { HIRES_VECTOR PROCEDURE }

  PROCEDURE INT_OUT(SCOL, ECOL, INT_VAL1, INT_VAL2 : NUMS);

    { This procedure displays integer values at the screen position
      given by scol and ecol. The integer values are in the parameters
      int_val1 and int_val2. }

    BEGIN
      GOTOXY(SCOL,ECOL);
      WRITE (OUTPUT,INT_VAL1:3,'         ',INT_VAL2:3);
    END; { INT_OUT PROCEDURE }



  PROCEDURE QUESTION(SCOL         : NUMS;
                     ECOL         : NUMS;
                     MSGTEXT      : TXT;
                     VAR INT_VAL1 : NUMS;
                     VAR INT_VAL2 : NUMS);

    { This procedure asks for the start and end columns of text and
      then displays the result inthe correct location. }

    BEGIN  { QUESTION PROCEDURE }
      KEEP_GOING := FALSE;
      GOTOXY(1,23);
      WRITE ('Enter the start and end columns for the ',MSGTEXT,' value  ');
      WHILE NOT KEEP_GOING DO
        BEGIN
          KEEP_GOING := TRUE;
          READLN  (INPUT,INT_VAL1,INT_VAL2);
          GOTOXY(1,23);
          DELLINE;
          INT_OUT(SCOL,ECOL,INT_VAL1,INT_VAL2);

          IF (INT_VAL1 < 0) OR (INT_VAL2 < 0)
            THEN KEEP_GOING := FALSE;

          IF (INT_VAL1 > INT_VAL2)
            THEN KEEP_GOING := FALSE;

          IF NOT KEEP_GOING THEN
            BEGIN
              LINE_OUT(1,23,SPACE79);
              GOTOXY(1,23);
              WRITE('Invalid column range. Please reenter columns for ',MSGTEXT,'  ');
            END;

        END;  { WHILE NOT KEEP_GOING }

    END;  { QUESTION PROCEDURE }

  PROCEDURE CON_VERT_I(     VBEGIN    : INTEGER;
                            VLEN      : INTEGER;
                            NPOINT    : INTEGER;
                       VAR  VREC      : INTEGER);

    { Procedure to convert input file string value to integer value. }

    VAR
      ERRCODE : INTEGER;          { RETURN CODE FROM STRING TO INT CONVERSION }
      VSTRING : TXT;              { A WORK STRING AREA }

    BEGIN  { CON_VERT_I PROCEDURE }
      VSTRING := COPY(LINE1,VBEGIN,VLEN);
      BLANK_TRIM(VSTRING);
      VAL(VSTRING,VREC,ERRCODE);
      IF ERRCODE > 0 THEN
        BEGIN
          GOODRECORD := FALSE;
          LINE_OUT(1,22,'Error, non-numeric values found in the input data.');
          GOTOXY(1,23);
          WRITELN('Record number ',NPOINT,' is dropped.');
          WRITE  ('Press any key to continue or Q to stop processing.');
          READ   (KBD,KEYVALUE);
          IF UPCASE(KEYVALUE) = 'Q' THEN KEEP_GOING := FALSE;
          GOTOXY(1,22);
          DELLINE;
          DELLINE;
          DELLINE;
        END;

    END;  { CON_VERT_I PROCEDURE }

  PROCEDURE CON_VERT_R(     VBEGIN    : INTEGER;
                            VLEN      : INTEGER;
                            NPOINT    : INTEGER;
                       VAR  VREC      : REAL);

    { Procedure to convert input file string values to real values. }

    VAR
      VSTRING : TXT;              { A WORK STRING AREA }
      ERRCODE : INTEGER;          { RETURN CODE FROM STRING TO REAL CONVERSION }

    BEGIN  { CON_VERT_R PROCEDURE }
      VSTRING := COPY(LINE1,VBEGIN,VLEN);
      BLANK_TRIM(VSTRING);
      VAL(VSTRING,VREC,ERRCODE);
      IF ERRCODE > 0 THEN
        BEGIN
          GOODRECORD := FALSE;
          LINE_OUT(1,22,'Error, non-numeric values found in the input data.');
          GOTOXY(1,23);
          WRITELN('Record number ',NPOINT,' is dropped.');
          WRITE  ('Press any key to continue or Q to stop processing.');
          READ   (KBD,KEYVALUE);
          IF UPCASE(KEYVALUE) = 'Q' THEN KEEP_GOING := FALSE;
          GOTOXY(1,22);
          DELLINE;
          DELLINE;
          DELLINE;
        END;

    END;  { CON_VERT_R PROCEDURE }


PROCEDURE READ_MCPAAL_CONFIGURE_FILE; { READ CONFIG.MCP FILE IF AVAILABLE }

VAR
   STUDYFILEVAR: STRING[12];

BEGIN
ASSIGN (FILEVAR7,CONFIGFILE);
RESET (FILEVAR7);

     BEGIN
          READLN(FILEVAR7);
          READLN(FILEVAR7);
          READLN(FILEVAR7);
          READLN(FILEVAR7);
          READLN(FILEVAR7);
          READLN(FILEVAR7);
          READLN(FILEVAR7);
          READLN(FILEVAR7,STUDYFILEVAR);
          READLN(FILEVAR7,METER_VALUE);
          READLN(FILEVAR7,SECTION_VALUE);
          READLN(FILEVAR7,XBEGIN);
          READLN(FILEVAR7,XEND);
          READLN(FILEVAR7,YBEGIN);
          READLN(FILEVAR7,YEND);
          READLN(FILEVAR7,X1BEGIN);
          READLN(FILEVAR7,X1END);
          READLN(FILEVAR7,X2BEGIN);
          READLN(FILEVAR7,X2END);
          READLN(FILEVAR7,Y1BEGIN);
          READLN(FILEVAR7,Y1END);
          READLN(FILEVAR7,Y2BEGIN);
          READLN(FILEVAR7,Y2END);
          READLN(FILEVAR7,LINEBEGIN);
          READLN(FILEVAR7,LINEEND);
     END;                            { FINISHED READING CONFIG.MCP FILE }
CLOSE (FILEVAR7);
      STUDYFILE := STUDYFILEVAR;     { NAME STUDYFILE AS DEFINED BY CONFIG.MCP }
      IF STUDYFILEVAR = '            ' THEN
         STUDYFILE := '';
END;                                 { MCPAAL_CONFIGURE_FILE PROCEDURE }

  PROCEDURE MAINMENU;

    { This procedure displays the main menu. }

    BEGIN
      CLRSCR;

      DISPLAY_COLOR(CYAN);
      TEXTBACKGROUND(BLACK);

      LINE_OUT( 8,1,' 浜様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様融');
      LINE_OUT( 8,2,'                          M c P A A L                          ');
      LINE_OUT( 8,3,' 麺様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様郵');
      LINE_OUT( 8,4,'  Micro-computer Programs for the Analysis of Animal Locations ');
      LINE_OUT( 8,5,'                version 1.22, (c) Michael Stwe                ');
      LINE_OUT( 1,6,'様様様様瞥様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様擁様様様様');

      LINE_OUT(2, 8,'1');
      LINE_OUT(2,10,'2  Format Location Coordinates');
      LINE_OUT(2,12,'3  Format Study Area Coordinates');
      LINE_OUT(2,14,'4');
      LINE_OUT(2,16,'5  Location Scatter and Histogram');
      LINE_OUT(2,18,'6  Minimum Convex Polygon');
      LINE_OUT(2,20,'7  Concave Polygon');
      LINE_OUT(2,22,'8  95% Ellipse');
      LINE_OUT(40,8,'9  Fourier Transformation');
      LINE_OUT(40,10,'A  Harmonic Mean Transformation');
      LINE_OUT(40,12,'B  Draw Replay File');
      LINE_OUT(40,14,'');
      LINE_OUT(40,16,'');
      LINE_OUT(40,18,'');
      LINE_OUT(40,20,'');
      LINE_OUT(40,22,'');

      DISPLAY_COLOR(RED);

      LINE_OUT(40,24,'T  Terminate Program');
      GOTOXY(1,24);
    END;

{ ************************************************************************ }
{ ************************************************************************ }

    {$I STUDY    }
    {$I RAWDATA  }
    {$I HISTO    }
    {$I CONVEX   }
    {$I CONCAVE   }
    {$I FFT      }
    {$I ELLIPSE  }
    {$I HARMONIC }

{ ************************************************************************ }
{ ************************************************************************ }

  BEGIN { RADIO TRACKING PROGRAM }

    { SET UP THE SCREEN }

      TEXTMODE(C80);

    { INITIALIZE SOME VARIABLES }

    RELEASE_FLAG := FALSE;
    CONFIGFILE  := 'CONFIG.MCP';
    FILEIN      := 'SAMPLDAT.ASC';
    FILEOUT     := 'SAMPLDAT.MCP';
    REPLAYFILE  := '';
    MAPFILE     := '';
    STUDYIN     := 'AREAMAP.ASC';
    STUDYFILE   := '';
    POINTFILE   := '';
    UDRESTART   := '';
    KEYVALUE    := ' ';
    MODULE      := ' ';
    ACTBEGIN    := 0;
    ACTEND      := 0;
    DATEBEGIN   := 0;
    DATEEND     := 0;
    GRIDSIZE    := 10;
    HOURBEGIN   := 0;
    HOUREND     := 0;
    LINEBEGIN   := 0;
    LINEEND     := 0;
    LOCBEGIN    := 0;
    LOCEND      := 0;
    RECBEGIN    := 0;
    RECEND      := 0;
    SEXBEGIN    := 0;
    SEXEND      := 0;
    SUBNOBEGIN  := 0;
    SUBNOEND    := 0;
    TIMEBEGIN   := 0;
    TIMEEND     := 0;
    XBEGIN      := 0;
    XEND        := 0;
    X1BEGIN     := 0;
    X1END       := 0;
    X2BEGIN     := 0;
    X2END       := 0;
    YBEGIN      := 0;
    YEND        := 0;
    Y1BEGIN     := 0;
    Y1END       := 0;
    Y2BEGIN     := 0;
    Y2END       := 0;
    ZBEGIN      := 0;
    ZEND        := 0;
    Z1BEGIN     := 0;
    Z1END       := 0;
    Z2BEGIN     := 0;
    Z2END       := 0;
    METER_VALUE := 0;
    SECTION_VALUE := 0;
    PRINTCHAR   := 'D';
    DRAWCHAR    := 'Y';
    GRIDCHAR    := 'N';
    PRECISION   := 'I';


IF EXIST (CONFIGFILE) THEN
     BEGIN
          READ_MCPAAL_CONFIGURE_FILE;
     END;                       { READ CONFIGFILE }


    COLOR_QUESTION;

    WHILE KEYVALUE <> 'T' DO
      BEGIN

        MAINMENU;

        KEYVALUE := ' ';

        WHILE NOT (UPCASE(KEYVALUE) IN ['1'..'9','A'..'G','T']) DO
          READ (KBD,KEYVALUE);
        KEYVALUE := UPCASE(KEYVALUE);
        MODULE   := KEYVALUE;

        CASE KEYVALUE OF
          '1': BEGIN
               CLRSCR;
               LINE_OUT(5,5,'Bearing data conversion due in a future release of McPAAL');
               WRITELN;
               KEYBOARD_PAUSE;
               END;
          '2': RAWDATA_INPUT;
          '3': STUDYFILE_MENU;
          '4': BEGIN
               CLRSCR;
               LINE_OUT(5,5,'File review code is due in a future release of McPAAL.');
               WRITELN;
               KEYBOARD_PAUSE;
               END;
          '5': HISTOGRAM_MENU;
          '6': CONVEX_HULL_MENU;
          '7': CONCAVE_HULL_MENU;
          '8': ELLIPSE_MENU;
          '9': FFT_MENU;
          'A': HARMONIC_MENU;
          'B': BEGIN
               CLRSCR;
               LINE_OUT(5,5,'Replay of graph files code is due in a future release of McPAAL');
               WRITELN;
               KEYBOARD_PAUSE;
               END;
          'C': BEGIN
               CLRSCR;
               LINE_OUT(5,5,'Habitat overlay options are due in a future release of McPAAL');
               WRITELN;
               KEYBOARD_PAUSE;
               END;

        END; { CASE KEYVALUE }

     END; { WHILE KEYVALUE }

    CLRSCR;
    NORMVIDEO;

    { Display the closing logo }

    GOTOXY(1,5);
    WRITELN('                      浜様様様様様様様様様様様様様様様様様融');
    WRITELN('                                                          ');
    WRITELN('                                  M c P A A L             ');
    WRITELN('                                                          ');
    WRITELN('                                 version  1.22            ');
    WRITELN('                                  March, 1992             ');
    WRITELN('                                                          ');
    WRITELN('                               (c) Michael Stwe          ');
    WRITELN('                                                          ');
    WRITELN('                       System Analysis: Charles Blohowiak ');
    WRITELN('                                                          ');
    WRITELN('                      藩様様様様様様様様様様様様様様様様様夕');
    GOTOXY(1,22);

    LOWVIDEO;

  END.  { RADIO TRACKING PROGRAM }I

