OVERLAY PROCEDURE STUDYFILE_MENU;

  { This module converts an unformatted study area file to a McPAAL
    formatted study area file. }

  TYPE
    STUDY_POINTER = ^ STUDY_MEM_REC;
    STUDY_MEM_REC = RECORD
                    XP1 : REAL;
                    YP1 : REAL;
                    ZP1 : REAL;
                    XP2 : REAL;
                    YP2 : REAL;
                    ZP2 : REAL;
                    LINE_TYPEP   : INTEGER;
                    NEXT_MEM_REC : STUDY_POINTER;
                    END;

  VAR
    FIRST_RECORD   : STUDY_POINTER;
    LAST_RECORD    : STUDY_POINTER;
    NEW_RECORD     : STUDY_POINTER;

    HEAP_TOP       : ^INTEGER;

  PROCEDURE INIT_STUDY_POINTER;

    { PROCEDURE TO ZERO OUT THE VALUE IN THE STUDY RECORD POINTER }

    BEGIN  { INIT_STUDY_POINTER  PROCEDURE }
      WITH NEW_RECORD^ DO
        BEGIN
          XP1          := 0.0;
          YP1          := 0.0;
          ZP1          := 0.0;
          XP2          := 0.0;
          YP2          := 0.0;
          ZP2          := 0.0;
          LINE_TYPEP   := 0;
          NEXT_MEM_REC := NIL;
        END;

    END;  { INIT_STUDY_POINTER PROCEDURE }

  PROCEDURE INIT_STUDYREC;

    { PROCEDURE TO ZERO OUT THE VALUES IN THE STUDY RECORD }

    BEGIN
      WITH FILE3REC DO
        BEGIN
          X1        := 0.0;
          Y1        := 0.0;
          X2        := 0.0;
          Y2        := 0.0;
          Z1        := 0.0;
          Z2        := 0.0;
          LINE_TYPE := 0;
        END;

    END;  { INIT_STUDYREC PROCEDURE }

  PROCEDURE CONVERT_STUDYAREA;

    { Reads the unformatted file and validates the data. Validated
      data are formatted and written to the study area output file. }

    VAR
      GOODPT  : INTEGER;          { THE NUMBER OF UNREJECTED POINTS }
      LLEN    : INTEGER;          { LENGTH OF THE LINE TYPE COLUMNS }
      NPOINT  : INTEGER;          { NUMBER OF OBSERVATIONS read }
      X1LEN   : INTEGER;          { LENGTH OF THE X1 DATA COLUMNS }
      X2LEN   : INTEGER;          { LENGTH OF THE X2 DATA COLUMNS }
      Y1LEN   : INTEGER;          { LENGTH OF THE Y1 DATA COLUMNS }
      Y2LEN   : INTEGER;          { LENGTH OF THE Y2 DATA COLUMNS }
      Z1LEN   : INTEGER;          { LENGTH OF THE Z1 DATA COLUMNS }
      Z2LEN   : INTEGER;          { LENGTH OF THE Z2 DATA COLUMNS }

    PROCEDURE DUMP_RECORDS;

      { PROCEDURE TO DUMP THE HEAP RECORDS INTO THE FILE3VAR FILE }

      BEGIN  { DUMP_RECORDS PROCEDURE }
        NEW_RECORD := FIRST_RECORD;
        WHILE NEW_RECORD <> NIL DO
          BEGIN
            FILE3REC.X1 := NEW_RECORD^.XP1;
            FILE3REC.Y1 := NEW_RECORD^.YP1;
            FILE3REC.Z1 := NEW_RECORD^.ZP1;
            FILE3REC.X2 := NEW_RECORD^.XP2;
            FILE3REC.Y2 := NEW_RECORD^.YP2;
            FILE3REC.Z2 := NEW_RECORD^.ZP2;
            FILE3REC.LINE_TYPE := NEW_RECORD^.LINE_TYPEP;
            GOODPT := GOODPT + 1;
            WRITE (FILEVAR3,FILE3REC);
            NEW_RECORD := NEW_RECORD^.NEXT_MEM_REC;
          END;  { WHILE NEW_RECORD <> NIL }

        RELEASE(HEAP_TOP);
        FIRST_RECORD := NIL;

      END;  { DUMP_RECORDS PROCEDURE }

    BEGIN  { CONVERT_STUDYAREA PROCEDURE }

      { Open and set the files }

      ASSIGN  (FILEVAR1,STUDYIN);
      RESET   (FILEVAR1);              { POSITION POINTER TO FILE BEGINNING }
      ASSIGN  (FILEVAR3,STUDYFILE);
      REWRITE (FILEVAR3);              { ERASE ANY EXISTING DATA IN THIS FILE }

      { CALCULATE LENGTHS OF THE VARIOUS VALUES }

      LLEN   := LINEEND - LINEBEGIN + 1;
      X1LEN  := X1END - X1BEGIN + 1;
      X2LEN  := X2END - X2BEGIN + 1;
      Y1LEN  := Y1END - Y1BEGIN + 1;
      Y2LEN  := Y2END - Y2BEGIN + 1;
      Z1LEN  := Z1END - Z1BEGIN + 1;
      Z2LEN  := Z2END - Z2BEGIN + 1;
      NPOINT := 0;
      GOODPT := 0;
      XHIGH  := 0.0;
      XLOW   := 0.0;
      YHIGH  := 0.0;
      YLOW   := 0.0;
      ZHIGH  := 0.0;
      ZLOW   := 0.0;

      { PLACE A BLANK RECORDS AT THE BEGINNING OF THE OUTPUT FILE. THIS RECORD
        IS FOR THE X,Y,Z HIGH AND LOW VALUES AS WELL AS THE NUMBER OF POINTS }

      INIT_STUDYREC;
      WRITE (FILEVAR3,FILE3REC);       { THE FIRST TWO RECORDS ARE USED FOR }
      WRITE (FILEVAR3,FILE3REC);       { FILE TYPE AND DATA HIGH AND LOW VALUES }

      { CONVERT THE INPUT VALUES AND WRITE THEM TO THE FORMATTED FILE }

      MARK(HEAP_TOP);
      FIRST_RECORD := NIL;
      GOODRECORD   := TRUE;
      LINE_OUT(1,23,'Processing Number: ');
      LINE_OUT(7,19,'Memory left:            paragraphs.');

      WHILE (NOT EOF(FILEVAR1)) AND (KEEP_GOING) DO
        BEGIN
          IF GOODRECORD = TRUE
            THEN NEW(NEW_RECORD)
            ELSE GOODRECORD := TRUE;
          READLN (FILEVAR1,LINE1);
          NPOINT := NPOINT + 1;
          GOTOXY(20,23);
          WRITE(NPOINT:5);
          INIT_STUDY_POINTER;
          WITH NEW_RECORD^ DO
            BEGIN
              CON_VERT_R(X1BEGIN,X1LEN,NPOINT,XP1);
              IF GOODRECORD THEN CON_VERT_R(Y1BEGIN,Y1LEN,NPOINT,YP1);
              IF GOODRECORD THEN CON_VERT_R(X2BEGIN,X2LEN,NPOINT,XP2);
              IF GOODRECORD THEN CON_VERT_R(Y2BEGIN,Y2LEN,NPOINT,YP2);
              IF (GOODRECORD) AND (Z1BEGIN > 0)
                THEN CON_VERT_R(Z1BEGIN,Z1LEN,NPOINT,ZP1);
              IF (GOODRECORD) AND (Z2BEGIN > 0)
                THEN CON_VERT_R(Z2BEGIN,Z2LEN,NPOINT,ZP2);
              IF GOODRECORD THEN CON_VERT_I(LINEBEGIN,LLEN,NPOINT,LINE_TYPEP);

              { GET MAX AND MIN VALUES }

              IF GOODRECORD THEN
              BEGIN
              IF (NPOINT = 1) OR (XP1 < XLOW)  THEN XLOW  := XP1;
              IF (NPOINT = 1) OR (XP1 > XHIGH) THEN XHIGH := XP1;
              IF (NPOINT = 1) OR (YP1 < YLOW)  THEN YLOW  := YP1;
              IF (NPOINT = 1) OR (YP1 > YHIGH) THEN YHIGH := YP1;
              IF (NPOINT = 1) OR (ZP1 < ZLOW)  THEN ZLOW  := ZP1;
              IF (NPOINT = 1) OR (ZP1 > ZHIGH) THEN ZHIGH := ZP1;

              IF XP2 < XLOW  THEN XLOW  := XP2;
              IF XP2 > XHIGH THEN XHIGH := XP2;
              IF YP2 < YLOW  THEN YLOW  := YP2;
              IF YP2 > YHIGH THEN YHIGH := YP2;
              IF ZP2 < ZLOW  THEN ZLOW  := ZP2;
              IF ZP2 > ZHIGH THEN ZHIGH := ZP2;
              END;  { IF GOODRECORD }

            END;  { WITH NEW_RECORD^ DO }

          { IF THE RECORD IS GOOD, ADD IT TO THE CHAIN }

          IF GOODRECORD THEN
            BEGIN
              IF FIRST_RECORD = NIL
                THEN FIRST_RECORD              := NEW_RECORD
                ELSE LAST_RECORD^.NEXT_MEM_REC := NEW_RECORD;
              LAST_RECORD                      := NEW_RECORD;
              LAST_RECORD^.NEXT_MEM_REC        := NIL;
            END;

          { SEE IF MEMORY IS RUNNING OUT }

          GOTOXY(20,19);
          WRITE (MEMORY_LEFT:8:2);

          IF MEMORY_LEFT < 300 THEN DUMP_RECORDS;

        END;  { WHILE NOT EOF FILEVAR1  AND KEEP_GOING }

      { END OF INPUT FILE, NOW WRITE OUT ANY RECORDS LEFT IN MEMORY }

      IF FIRST_RECORD <> NIL THEN DUMP_RECORDS;

      { RIGHT OUT THE EXTREME VALUES }

      SEEK(FILEVAR3,0);           { GET THE FIRST RECORD IN THE FILE }
      INIT_STUDYREC;
      WITH FILE3REC DO
        BEGIN
          X1 := -5.0;             { VALUES TO IDENTIFY THIS FILE AS A }
          X2 := -7.0;             { MAP FILE. }
          Y1 := -3.0;
          Y2 := -9.0;
        END;
      WRITE (FILEVAR3,FILE3REC);

      WITH FILE3REC DO
        BEGIN
          X1 := XLOW;             { SECOND RECORD HAS THE HIGH AND LOW VALUES }
          X2 := XHIGH;            { FOR EACH OF THE 3 COORDINATES. }
          Y1 := YLOW;             { LINE_TYPE HAS THE NUMBER OF POINTS }
          Y2 := YHIGH;
          Z1 := ZLOW;
          Z2 := ZHIGH;
          LINE_TYPE := GOODPT;    { NUMBER OF POINTS IN THE FILE }
        END;
      WRITE (FILEVAR3,FILE3REC);

      RELEASE(HEAP_TOP);
      GOTOXY(1,24);
      WRITE('Formatting of the study file complete. There are ',GOODPT:5,' locations.');

      { CLOSE ALL FILES }

      CLOSE (FILEVAR1);
      CLOSE (FILEVAR3);

    END;  { CONVERT_STUDYAREA PROCEDURE }

  BEGIN  { STUDYFILE_MENU PROCEDURE }

    { Display the options menu for the convert study file menu }

    KEYVALUE := 'R';

    WHILE KEYVALUE = 'R' DO
    BEGIN

    CLRSCR;
    DISPLAY_COLOR(CYAN);

    LINE_OUT(18,2,'(3) Format ASCII File with Study Area Coordinates');
    LINE_OUT(7,4,'1  Input File:');
    LINE_OUT(38,4,'2  Output File:');
    LINE_OUT(17,6,'First Column  Last Column');
    LINE_OUT(7,8,'3  X1:');
    LINE_OUT(7,10,'4  Y1:');
    LINE_OUT(7,12,'5  X2:');
    LINE_OUT(7,14,'6  Y2:');
    LINE_OUT(7,16,'7  Line Type:');

    DISPLAY_COLOR(RED);

    LINE_OUT(7,21,'P  Process Data');
    LINE_OUT(37,21,'E  Exit to Main Menu');

    TEXTCOLOR(YELLOW);

    LINE_OUT(22,4,STUDYIN);
    LINE_OUT(54,4,STUDYFILE);
    INT_OUT(21,8,X1BEGIN,X1END);
    INT_OUT(21,10,Y1BEGIN,Y1END);
    INT_OUT(21,12,X2BEGIN,X2END);
    INT_OUT(21,14,Y2BEGIN,Y2END);
    INT_OUT(21,16,LINEBEGIN,LINEEND);

    GOTOXY(1,25);
    KEYVALUE := ' ';
    WHILE UPCASE(KEYVALUE) <> 'E' DO
      BEGIN

        KEYVALUE := ' ';

        WHILE NOT (UPCASE(KEYVALUE) IN ['1'..'7','E','P']) DO
          READ    (KBD,KEYVALUE);
        KEYVALUE := UPCASE(KEYVALUE);

        GOTOXY(1,23);
        DELLINE;
        DELLINE;

        CASE KEYVALUE OF
          '1': BEGIN
               LINE_OUT(1,23,'Enter the name of the unformatted study area INPUT file. ');
               READLN  (INPUT,STUDYIN);
               GOTOXY(1,23);
               DELLINE;
               CAPIT(STUDYIN);
               LINE_OUT(22,4,SPACE15);
               LINE_OUT(22,4,STUDYIN);
               END;
          '2': BEGIN
               LINE_OUT(1,23,'Enter the name of the formatted study area OUTPUT file. ');
               READLN  (INPUT,STUDYFILE);
               GOTOXY(1,23);
               DELLINE;
               CAPIT(STUDYFILE);
               LINE_OUT(54,4,SPACE15);
               LINE_OUT(54,4,STUDYFILE);
               END;
          '3': QUESTION(21,8,'X1',X1BEGIN,X1END);
          '4': QUESTION(21,10,'Y1',Y1BEGIN,Y1END);
          '5': QUESTION(21,12,'X2',X2BEGIN,X2END);
          '6': QUESTION(21,14,'Y2',Y2BEGIN,Y2END);
          '7': QUESTION(21,16,'Line Type',LINEBEGIN,LINEEND);
          'P': BEGIN
               KEEP_GOING := TRUE;

               IF (STUDYIN = '') OR ( STUDYFILE = '' ) THEN
                 BEGIN
                   LINE_OUT(1,23,'Both files must be defined.');
                   KEEP_GOING := FALSE;
                 END;

               IF (KEEP_GOING) AND (NOT EXIST(STUDYIN)) THEN
                 BEGIN
                   LINE_OUT(1,23,'The input study area file does not exist.');
                   KEEP_GOING := FALSE;
                 END;

               IF (KEEP_GOING) THEN
                 IF ( X1BEGIN = 0 ) OR ( X1END = 0 ) THEN
                   BEGIN
                     LINE_OUT(1,23,'All fields must have a non-zero value.');
                     LINE_OUT(1,24,'The X1 columns are invalid.');
                     KEEP_GOING := FALSE;
                   END;

               IF (KEEP_GOING) THEN
                 IF ( Y1BEGIN = 0 ) OR ( Y1END = 0 ) THEN
                   BEGIN
                     LINE_OUT(1,23,'All fields must have a non-zero value.');
                     LINE_OUT(1,24,'The Y1 columns are invalid.');
                     KEEP_GOING := FALSE;
                   END;

               IF (KEEP_GOING) THEN
                 IF ( X2BEGIN = 0 ) OR ( X2END = 0 ) THEN
                   BEGIN
                     LINE_OUT(1,23,'All fields must have a non-zero value.');
                     LINE_OUT(1,24,'The X2 columns are invalid.');
                     KEEP_GOING := FALSE;
                   END;

               IF (KEEP_GOING) THEN
                 IF ( Y2BEGIN = 0 ) OR ( Y2END = 0 ) THEN
                   BEGIN
                     LINE_OUT(1,23,'All fields must have a non-zero value.');
                     LINE_OUT(1,24,'The Y2 columns are invalid.');
                     KEEP_GOING := FALSE;
                   END;

               IF (KEEP_GOING) THEN
                 IF ( LINEBEGIN = 0 ) OR ( LINEEND = 0 ) THEN
                   BEGIN
                     LINE_OUT(1,23,'All fields must have a non-zero value.');
                     LINE_OUT(1,24,'The LINE TYPE columns are invalid.');
                     KEEP_GOING := FALSE;
                   END;

               IF KEEP_GOING THEN CONVERT_STUDYAREA;

               END; { CASE P }

        END;  { CASE KEYVALUE OF }

        GOTOXY(1,25);

      END;  { WHILE UPCASE KEYVALUE <> E }

    END;  { WHILE KEYVALUE = R }

    KEYVALUE := ' ';

  END;  { STUDYFILE_MENU PROCEDURE }

