OVERLAY PROCEDURE HISTOGRAM_MENU;

  { This procedure displays the driving menu for the histogram algorithm.
    The histogram procedure is called from this menu. }

PROCEDURE HISTOGRAM;

  {  HRMAP  12/17/84        -BLOHOWIAK

     THIS PROGRAM TAKES X AND Y CO-ORDINATES AND CONSTRUCTS AN n BY n
     GRID THAT COVERS ALL POINTS READ FROM THE DATAIN FILE.

     THE OUTPUT FILE IS EFFECTIVELY A FREQUENCY MATRIX OF HOW MANY POINTS
     HAVE FALLEN WITHIN EACH GRID CELL. THE OUTPUT FILE CONSISTS OF
     THE CELL CO-ORDINATES, THE X AND Y CO-ORDINATES, AND THE FINAL COUNT
     IN THE CELL (THE Z OR ZED CO-ORDINATE).     }


VAR
  ASKOVERLAY  : BOOLEAN;   { ASK USER IF DRAW STUDY AREA ON THE GRID }

  GRID : ARRAY[1..80,1..80] OF INTEGER;  { THE FREQUENCY ARRAY }
  GRID_VALUE  : REAL;      { DISTANCE VALUE OF EACH GRID }
  XVALUE      : REAL;      { X CO-ORDINATE READ IN FROM THE DATA FILE }
  YVALUE      : REAL;      { Y CO-ORDINATE READ IN FROM THE DATA FILE }
  WORK1       : REAL;      { A WORK REAL }
  FLAG1       : INTEGER;   { USED TO CONTROL LOGIC FLOW WITH ERRORS }
  FLAG2       : INTEGER;   { USED TO CONTROL USER INPUT OF GRID POINTS }
  I1          : INTEGER;   { A WORK INTEGER }
  I2          : INTEGER;   { A WORK INTEGER }
  NPOINTS     : INTEGER;   { NUMBER OF OBSERVATIONS READ }
  XINDEX      : INTEGER;   { INDEX TO THE ARRAY GRID }
  YINDEX      : INTEGER;   { INDEX TO THE ARRAY GRID }
  ANSWER      : CHAR;      { YES OR NO RESPONSE FOR GRID POINTS }

BEGIN   { HISTOGRAM }

  { THE MAIN PROCEDURE FOR HRMAP }

  ASKOVERLAY := FALSE;                 { TRUE IF STUDY FILE IS USED ON GRID BOUNDRIES }

  {OPEN THE FILES}

  ASSIGN  (FILEVAR2,FILEOUT);
  RESET   (FILEVAR2);               { POSTION POINTER TO BEGIN OF INPUT FILE }

  { LOADT THE MINIMUM AND MAXIMUM POINTS FROM THE FILE }

  WRITELN (OUTPUT,' ');
  WRITELN (OUTPUT,'Loading the outer limits of the animal locations.');

  SEEK (FILEVAR2,1);
  READ (FILEVAR2,FILE2REC);

  XLOW := FILE2REC.X;
  YLOW := FILE2REC.Y;
  ZLOW := FILE2REC.Z;
  NPOINTS := FILE2REC.RECORD_NO;

  READ (FILEVAR2,FILE2REC);

  XHIGH := FILE2REC.X;
  YHIGH := FILE2REC.Y;
  ZHIGH := FILE2REC.Z;


  WRITELN (OUTPUT,' ');
  WRITELN (OUTPUT,'Outer limits of the grid are:');
  WRITELN (OUTPUT,'   X: ',XLOW:10:5,' TO ',XHIGH:10:5);
  WRITELN (OUTPUT,'   Y: ',YLOW:10:5,' TO ',YHIGH:10:5);
  WRITELN (OUTPUT,'There are ',NPOINTS,' data points.');

  IF STUDYFILE = '' THEN KEYBOARD_PAUSE;

  { If a study file is given, ask user if he wants to use it. }

  IF (STUDYFILE <> '') THEN
    BEGIN
      GOTOXY(1,25);
      WRITE   (OUTPUT,'Do you want to use the STUDY FILE for grid boundry definition (Y|N) ');

      YES_NO(KEYVALUE);

      IF KEYVALUE = 'Y' THEN
        BEGIN

          ASSIGN (FILEVAR3,STUDYFILE);
          RESET  (FILEVAR3);
          STUDYOPEN := TRUE;

          SEEK   (FILEVAR3,1);         { GET THE SECOND RECORD }
          READ   (FILEVAR3,FILE3REC);

          WITH FILE3REC DO
            BEGIN
              XLOW := MIN_VAL(X1,XLOW);
              YLOW := MIN_VAL(Y1,YLOW);
              ZLOW := MIN_VAL(Z1,ZLOW);
              XHIGH := MAX_VAL(X2,XHIGH);
              YHIGH := MAX_VAL(Y2,YHIGH);
              ZHIGH := MAX_VAL(Z2,ZHIGH);
            END;  { WITH FILE3REC DO }

          ASKOVERLAY := TRUE;

        END;  { IF KEYVALUE = Y }

    END;  { IF STUDYFILE <> '' }

  { DETERMINE THE DELTA X AND DELTA Y FOR THE GRID }

  CLRSCR;

  XDELTA := XHIGH - XLOW;
  YDELTA := YHIGH - YLOW;

  METERS_TO_GRIDS(XDELTA,XGRID_NUM);
  METERS_TO_GRIDS(YDELTA,YGRID_NUM);

  XHIGH := XLOW + XDELTA;
  YHIGH := YLOW + YDELTA;

  GRID_CALCULATIONS;

  IF XGRID_NUM > YGRID_NUM
    THEN GRIDSIZE := XGRID_NUM
    ELSE GRIDSIZE := YGRID_NUM;

  { SET THE FREQUENCY ARRAY -GRID- TO ZERO COUNTS }

  FOR I1 := 1 TO GRIDSIZE DO
    FOR I2 := 1 TO GRIDSIZE DO
      GRID[I1,I2] := 0;

  {SECOND PASS IS TO PUT THE ELEMENTS INTO THE GRID }

  WRITELN (OUTPUT,' ');
  WRITELN (OUTPUT,'Reading data file and totaling the frequency of cell counts.');

  SEEK (FILEVAR2,3);                   { DATA BEGINS AT RECORD 4 }

  WHILE NOT EOF(FILEVAR2) DO
    BEGIN
      READ  (FILEVAR2,FILE2REC);
      WITH FILE2REC DO
        BEGIN
          XVALUE := X + XOFFSET;
          XVALUE := XVALUE * GRIDSIZE / GRID_SPAN;
          XINDEX := TRUNC(XVALUE) + 1;
          IF XINDEX > GRIDSIZE THEN XINDEX := GRIDSIZE;
          YVALUE := Y + YOFFSET;
          YVALUE := YVALUE * GRIDSIZE / GRID_SPAN;
          YINDEX := TRUNC(YVALUE) + 1;
          IF YINDEX > GRIDSIZE THEN YINDEX := GRIDSIZE;

          { INCREMENT THE GRID COUNT AT THIS POINT }

          GRID[XINDEX,YINDEX] := GRID[XINDEX,YINDEX] + 1;

       END; { WITH FILE2REC DO }

    END; { WHILE NOT EOF(FILEVAR2) }

  IF DRAWCHAR = 'Y' THEN
    BEGIN

      { GRAPH THE OBSERVATION DISTRIBUTION }
      { FIRST, DRAW THE GRID }

      HIRES;
      HIRESCOLOR(YELLOW);

      LINE_OUT(1,1,'Observation distribution:');

      FOR I1 := 0 TO GRIDSIZE DO
        BEGIN

          WORK1 := I1 * GRID_SPAN /GRIDSIZE;
          HIRES_VECTOR(WORK1,0,WORK1,GRID_SPAN,0,0,GRIDFACTOR);
          HIRES_VECTOR(0,WORK1,GRID_SPAN,WORK1,0,0,GRIDFACTOR);

        END;  { I1 = 0 TO GRIDSIZE + 1 }

      SEEK (FILEVAR2,3);               { BACK TO THE FOURTH RECORD }

      WHILE NOT EOF(FILEVAR2) DO
        BEGIN
          READ (FILEVAR2,FILE2REC);
          WITH FILE2REC DO
            HIRES_POINT(X,Y,XOFFSET,YOFFSET,GRIDFACTOR);
        END;  { WHILE NOT EOF(FILEVAR2) }

      { PUT IN THE FILE INFORMATION }

      LINE_OUT(60,4,'Data file:');
      LINE_OUT(64,5,FILEOUT);

      IF STUDYFILE <> '' THEN
        BEGIN
          LINE_OUT(60,7,'Map file:');
          LINE_OUT(64,8,STUDYFILE);
        END;

      IF REPLAYFILE <> '' THEN
        BEGIN
          LINE_OUT(60,10,'Replay file:');
          LINE_OUT(64,11,REPLAYFILE);
        END;

      GRID_VALUE := (GRID_SPAN / GRIDSIZE) * METER_VALUE;
      GOTOXY(60,15);
      WRITE('Each grid cell width');
      GOTOXY(60,16);
      WRITE('is ',GRID_VALUE:8:2);
      GOTOXY(60,17);
      WRITE('meters.');

      IF ASKOVERLAY THEN
        BEGIN
          LINE_OUT(1,25,'Draw the study file area overlay? (Y|N) ');
          YES_NO(STUDYDRAWN);
          LINE_OUT(1,25,SPACE79);

          IF STUDYDRAWN = 'Y' THEN
            BEGIN                      { DRAW THE STUDY AREA ON THE GRID }

              SEEK (FILEVAR3,2);       { DATA BEGIN AT THE THIRD RECORD }

              WHILE NOT EOF(FILEVAR3) DO
                BEGIN
                  READ (FILEVAR3,FILE3REC);
                  WITH FILE3REC DO
                    HIRES_VECTOR(X1,Y1,X2,Y2,XOFFSET,YOFFSET,GRIDFACTOR);
                END;  { WHILE NOT EOF (FILEVAR3) }

            END;  { IF STUDYDRAWN = Y }

        END;  { IF ASKOVERLAY }

      IF REPLAYFILE <> '' THEN
        BEGIN
          LINE_OUT(1,25,SPACE79);
          LINE_OUT(1,25,'Do you want to add this graph to the replay file? (Y|N) ');

          YES_NO(KEYVALUE);

          IF KEYVALUE = 'Y' THEN
            BEGIN

              IF NOT EXIST(REPLAYFILE) THEN INIT_REPLAY_FILE;
              ASSIGN (FILEVAR4,REPLAYFILE);
              RESET  (FILEVAR4);
              REPLAYOPEN := TRUE;

              { WRITE OUT THIS PLOT. WILL INCLUDE POINTS AND MAYBE STUDY FILE }

              IF STUDYDRAWN = 'Y' THEN
                IF NOT STUDY_IN_REPLAY THEN
                    ADD_GRAPH('STUDYFILE');      { PUT STUDY FILE IN REPLAY }
              ADD_GRAPH('DATAFILE');             { PUT DATA FILE IN REPALY }

            END;  { KEYVALUE = Y }

          IF REPLAYOPEN THEN CLOSE(FILEVAR4);
          IF STUDYOPEN  THEN CLOSE(FILEVAR3);

        END;  { IF REPLAY FILE <> '' }

      LINE_OUT(1,25,SPACE79);
      GOTOXY(1,25);
      KEYBOARD_PAUSE;

      TEXTMODE;

    END;  { IF DRAWCHAR = Y }

  IF (PRINTCHAR = 'D') OR (PRINTCHAR = 'B') THEN
    BEGIN
      WRITELN (OUTPUT,' ');
      WRITE   (OUTPUT,'Grid frequency- X horizontal, Y vertical.    Cell width: ',GRID_VALUE:8:4,' meters.');
      WRITELN (OUTPUT,' ');
      WRITE   (OUTPUT,'    ');

      FOR I1 := 1 TO GRIDSIZE DO
        WRITE (OUTPUT,I1:4);

      WRITELN (OUTPUT,' ');
      WRITE   ('   (',GRIDLOW:5:2,',',GRIDHIGH:5:2,')');
      IF GRIDSIZE > 8 THEN
        FOR FLAG2 := 8 TO GRIDSIZE DO
          WRITE (OUTPUT,'    ');
      WRITE   ('   (',GRIDHIGH:5:2,',',GRIDHIGH:5:2,')');

      WRITELN (OUTPUT,' ');
      WRITE   (OUTPUT,'    ');


      FOR I1 := 1 TO GRIDSIZE DO
        WRITE (OUTPUT,'____');

      WRITELN (OUTPUT,'');

      FOR I1 := GRIDSIZE DOWNTO 1 DO
        BEGIN
        WRITE (OUTPUT,I1:2,' |');
        FOR I2 := 1 TO GRIDSIZE DO
          IF GRID[I2,I1] > 0 THEN
            WRITE (OUTPUT,GRID[I2,I1]:4)
          ELSE
            WRITE (OUTPUT,'   .');
          WRITELN (OUTPUT,'');
        END; {FOR BEGIN }

      WRITE ('   (',GRIDLOW:5:2,',',GRIDLOW:5:2,')');
      IF GRIDSIZE > 8 THEN
        FOR FLAG2 := 8 TO GRIDSIZE DO
          WRITE (OUTPUT,'    ');
      WRITE('   (',GRIDHIGH:5:2,',',GRIDLOW:5:2,')');

    END; { IF PRINTCHAR = D OR B }

  IF (PRINTCHAR = 'P') OR (PRINTCHAR = 'B') THEN
    BEGIN

      { WRITE EVERYTHING TO THE PRINTER ALSO. }

      WRITELN (LST,' ');
      WRITELN (LST,' ');
      WRITELN (LST,'Data file: ',FILEOUT);
      WRITELN (LST,' ');
      WRITELN (LST,' ');
      WRITELN (LST,'   GRID FREQUENCY- X ACROSS THE TOP, Y DOWN THE SIDE');
      WRITELN (LST,' ');
      WRITE   (LST,'    ');

      FOR I1 := 1 TO GRIDSIZE DO
        WRITE (LST,I1:4);

      WRITELN (LST,' ');
      WRITE   (LST,'   (',GRIDLOW:5:2,',',GRIDHIGH:5:2,')');
      IF GRIDSIZE > 8 THEN
        FOR FLAG2 := 8 TO GRIDSIZE DO
          WRITE (LST,'    ');
      WRITE   (LST,'   (',GRIDHIGH:5:2,',',GRIDHIGH:5:2,')');

      WRITELN (LST,' ');
      WRITE   (LST,'    ');

      FOR I1 := 1 TO GRIDSIZE DO
        WRITE (LST,'____');

      WRITELN (LST,'');

      FOR I1 := GRIDSIZE DOWNTO 1 DO
        BEGIN
          WRITE (LST,I1:2,' |');
          FOR I2 := 1 TO GRIDSIZE DO
            IF GRID[I2,I1] > 0 THEN
              WRITE (LST,GRID[I2,I1]:4)
            ELSE
              WRITE (LST,'   .');
          WRITELN (LST,'');
        END;  {FOR BEGIN }

      WRITE (LST,'   (',GRIDLOW:5:2,',',GRIDLOW:5:2,')');
      IF GRIDSIZE > 8 THEN
        FOR FLAG2 := 8 TO GRIDSIZE DO
          WRITE (LST,'    ');
      WRITE (LST,'   (',GRIDHIGH:5:2,',',GRIDLOW:5:2,')');

      WRITELN (LST,' ');
      WRITELN (LST,' ');

      WRITELN(LST,'Each cell width is ',grid_value:8:2,' meters.');

      WRITELN (LST,' ');

    END;  { IF PRINTCHAR = P OR B }

  KEYBOARD_PAUSE;

  { CLOSE THE REST OF THE FILES }

  CLOSE   (FILEVAR2);

  KEYVALUE := 'R';

END;  { HISTOGRAM }

BEGIN  { HISTOGRAM_MENU }

  { Display the options menu for the histogram procedure }

  KEYVALUE := 'R';

  WHILE KEYVALUE = 'R' DO
  BEGIN

  CLRSCR;
  DISPLAY_COLOR(CYAN);

  LINE_OUT(30,2,'(5) Histogram  Algorithm');
  LINE_OUT(10,4,'1  Data file:');
  LINE_OUT(10,6,'2  Study area file:');
  LINE_OUT(10,8,'3  Plot replay file:');
  LINE_OUT(10,10,'4  Text output displayed on:');
  LINE_OUT(10,12,'5  Graphics displayed on screen (Y|N)');
  LINE_OUT(10,14,'6  ');
  LINE_OUT(10,16,'7  Width of a grid cell in meters:');
  LINE_OUT(10,18,'8  Scale of your map as meters between adjacent coordinates: ');


  TEXTCOLOR(YELLOW);
  LINE_OUT(24,4,FILEOUT);
  LINE_OUT(30,6,STUDYFILE);
  LINE_OUT(31,8,REPLAYFILE);

  CASE UPCASE(PRINTCHAR) OF
    'D' : PRINTSTR := 'DISPLAY ONLY';
    'P' : PRINTSTR := 'PRINTER ONLY';
    'B' : PRINTSTR := 'BOTH DISPLAY AND PRINTER';
  END;

  LINE_OUT(39,10,PRINTSTR);

  IF DRAWCHAR = 'N'
    THEN DRAWSTR := 'NO'
    ELSE DRAWSTR := 'YES';

  LINE_OUT(49,12,DRAWSTR);

  GOTOXY(45,16);
  WRITE (SECTION_VALUE:8:4);

  GOTOXY(71,18);
  WRITE (METER_VALUE:8:4);

  DISPLAY_COLOR(RED);

  LINE_OUT(7,21,'P  Process Data');
  LINE_OUT(37,21,'E  Exit to Main Menu');
  TEXTCOLOR(YELLOW);
  GOTOXY(1,24);

  KEYVALUE := ' ';

  WHILE NOT (UPCASE(KEYVALUE) IN ['E','R']) DO
    BEGIN

      KEYVALUE := ' ';
      WHILE NOT (UPCASE(KEYVALUE) IN ['1'..'5','7','8','E','P'] ) DO
        READ (KBD,KEYVALUE);
      KEYVALUE := UPCASE(KEYVALUE);

      GOTOXY(1,23);
      DELLINE;
      DELLINE;

      CASE KEYVALUE OF
        '1': MENU_CALL(1);        { INPUT DATA FILE }
        '2': MENU_CALL(2);        { STUDY AREA FILE }
        '3': MENU_CALL(3);        { REPLAY FILE }
        '4': MENU_CALL(4);        { TEXT ON B, D, P }
        '5': MENU_CALL(5);        { GRAPHICS ON SCREEN? }
        '7': MENU_CALL(7);        { WIDTH OF GRID CELL }
        '8': MENU_CALL(8);        { DISTANCE FROM 1.0 TO 2.0 }
        'P': BEGIN
             KEEP_GOING := TRUE;
             STUDYOPEN := FALSE;
             REPLAYOPEN := FALSE;

             PROCESSING_VERIFY;

             IF (KEEP_GOING) AND (SECTION_VALUE <= 0) THEN
               BEGIN
                 LINE_OUT(1,23,'A grid cell width greater than 0 must be given.');
                 KEEP_GOING := FALSE;
               END;

             IF (KEEP_GOING) AND (METER_VALUE <= 0) THEN
               BEGIN
                 LINE_OUT(1,23,'The distance from 1.0 to 2.0 must be given.');
                 KEEP_GOING := FALSE;
               END;

             IF KEEP_GOING THEN             { SEE IF TOO MANY GRIDS FOR A GOOD DISPLAY }
               BEGIN
                 IF STUDYFILE <> '' THEN
                   BEGIN
                     XLOW := MIN_VAL(XLOW,SXLOW);
                     YLOW := MIN_VAL(YLOW,SYLOW);
                     ZLOW := MIN_VAL(ZLOW,SZLOW);
                     XHIGH := MAX_VAL(XHIGH,SXHIGH);
                     YHIGH := MAX_VAL(YHIGH,SYHIGH);
                     ZHIGH := MAX_VAL(ZHIGH,SZHIGH);
                     XDELTA := XHIGH - XLOW;
                     YDELTA := YHIGH - YLOW;
                   END;
                 METERS_TO_GRIDS(XDELTA,XGRID_NUM);
                 METERS_TO_GRIDS(YDELTA,YGRID_NUM);
                 IF XGRID_NUM > YGRID_NUM THEN
                   BEGIN
                     YGRID_NUM := XGRID_NUM;
                     YDELTA    := XDELTA;
                   END
                 ELSE
                   BEGIN
                     XGRID_NUM := YGRID_NUM;
                     XDELTA    := YDELTA;
                   END;

                 IF XGRID_NUM > 80 THEN
                   BEGIN
                     CLRSCR;
                     LINE_OUT(5,10,'There are more than 80 grid cells required to span your home range');
                     LINE_OUT(5,11,'or study area. The program can only handle a maximum of 80 grid cells');
                     LINE_OUT(5,12,'in one direction.');
                     XDELTA := XDELTA * METER_VALUE / 80;
                     GOTOXY(5,14);
                     WRITELN('With a distance from 1.0 to 2.0 of ',METER_VALUE:8:4,' meters, you need to');
                     WRITELN('    specify a grid cell width of at least ',XDELTA:8:4,' meters.');
                     KEEP_GOING := FALSE;
                     KEYBOARD_PAUSE;
                   END;  { IF XGRID_NUM > 80 }

                 IF (KEEP_GOING) AND (XGRID_NUM > 17) THEN
                   BEGIN
                     CLRSCR;
                     GOTOXY(5,10);
                     WRITE ('There are ',XGRID_NUM:5,' cells required to cover your home range.');
                     LINE_OUT(5,12,'The screen can only display 17 cells without wrapping.');
                     XDELTA := XDELTA * METER_VALUE / 17;
                     GOTOXY(5,14);
                     WRITE  ('To display without wrapping, use a grid cell width of',XDELTA:8:3,'.');
                     GOTOXY(1,24);
                     WRITE ('Press any key to continue or Q to stop processing.');
                     READ  (KBD,KEYVALUE);
                     IF UPCASE(KEYVALUE) = 'Q' THEN KEEP_GOING := FALSE;
                   END;  { XGRID_NUM > 17 }

                 KEYVALUE := 'R';

               END;  { CODE TO CHECK NUMBER OF GRID CELLS }

             IF KEEP_GOING THEN
               BEGIN
                 CLRSCR;
                 HISTOGRAM;
               END;

             END;  { CASE 5 }

      END;  { CASE KEYVALUE }

      GOTOXY(1,25);

    END; { WHILE NOT (KEYVALUE IN ['E','R']) }

  END; { WHILE KEYVALUE = 'R' }

  KEYVALUE := ' ';

END;  { HISTOGRAM_MENU PROCEDURE }

