

{$M+}
{$E+}

PROGRAM name;

{$I i:\opus.i}
{$I i:\gctv.inc}

{$I i:\gemsubs.def}
{$I i:\vdi_aes.def}

PROCEDURE HELP ( what : INTEGER );
   EXTERNAL;
FUNCTION VALID_NUMBER ( VAR str : LorFstr ) : StatusType;
   EXTERNAL;
PROCEDURE CELL_ON_SCREEN ( a,b,c : INTEGER; d : BOOLEAN );
   EXTERNAL;
PROCEDURE WRITE_CELL_NAME;
   EXTERNAL;
PROCEDURE DELETE_CELL ( row,col : INTEGER; total_kill : BOOLEAN );
   EXTERNAL;
FUNCTION LOCATE_CELL ( row,col : INTEGER ) : CellPtr;
   EXTERNAL;
FUNCTION MOUSE_ROW_COL ( mouse_x,mouse_y     : INTEGER;
                         VAR new_row,new_col : INTEGER ) : BOOLEAN;
   EXTERNAL;
PROCEDURE DEFAULT_DRAW_ATTRIBUTES;
   EXTERNAL;
PROCEDURE INT_TO_STRING ( a : INTEGER; VAR b : STR10 );
   EXTERNAL; { found in NUM_CON.PAS }
PROCEDURE UNHIDE ( menu : Tree_Index );
   EXTERNAL;
PROCEDURE HIDE;
   EXTERNAL;

PROCEDURE WINDOW_INPUT ( max_length     : INTEGER;
                         str_type       : InpType; { Alphanumeric,FloatingPoint
                                                     AnInteger ( not used ) }
                         VAR str        : STR255 );

{ expects a visible mouse }
{ global variables used:
     msg_area,too_long,float,area_x,area_y,area_w,area_h,
     null_input,inp_code,column,char_count,key,
     x_pix,mx,my,bad_str,event,alert,pos_in_str,btn_state,b_cnt,
     edit_x,edit_y
}


{ null_input & inp_code are specific parms I added to this general-purpose
  routine. null_input as passed represents whether or not the passed formula
  is valid or not. It returns TRUE if the user made no changes,
  regardless of str-type.
  inp_code
  is a variable which returns various key actions independent of str, i.e.
  a cursor key or RETURN was pressed, and also all other key actions
  defined in CHECK_KEY. adding new key functions requires:
     1. defining new constant in file windinp.cns,
     2. updating CHECK_KEY,
     3. updating NOT_EXIT_KEY.
  For this application, the LEFT_ARROW, etc. functions are invoked by
  CNTL-cursor instead of just the cursor. Need to keep this in mind for
  using this routine elsewhere }

  { we could check for invalid numbers on the fly, as they are entered,
    character by character, but suppose the user isn't paying attention
    to what he has entered. A misplaced - sign or decimal could be entered, &
    he would continue. Then he goes on to complete the number, tries to enter
    the - sign or decimal where he intended, and isn't allowed to because
    it would be invalid; moreover he isn't alerted to this- he wouldn't want an
    alert box every time he made a mistake. He
    has made an error and doesn't know it. So, to avoid this, we allow only
    valid digits in the number, and once the number is locked in, we check
    its validity; if invalid, i.e. > 1 dec points, > 1 E's, etc.,
    an alert box appears. }

  LABEL 5,100;
  CONST line_length = 31;
  VAR
        i,j,dummy,str_pos,
        line_count,y_pix,y_dis  : INTEGER;
        first,quit,ins          : BOOLEAN;

FUNCTION ANIMATE_MENU ( item,pull_down : Tree_Index ) : Tree_Index;
   VAR x,y,w,h     : INTEGER;
       dummy       : BOOLEAN;
       sel,old_sel : Tree_Index;
   BEGIN
      Obj_SetState(new_desk_ptr,item,Selected,TRUE);
      Obj_Size(new_desk_ptr,pull_down,x,y,w,h);
      x := x-1;
      y := y-1;
      w := w+2;
      h := h+2;
      Hide_Mouse;
      Blit(screen_mfdb,mem_mfdb,x,y,x,y,w,h);
      unhide(pull_down);
      Obj_Draw(new_desk_ptr,pull_down,Max_Depth,x,y,w,h);
      Show_Mouse;
      sel := Null_Index;
      old_sel := sel;
      Graf_MKState(mx,my,btn_state,kbd_state);
      WHILE btn_state & 1 <> 0 DO BEGIN
         dummy := Obj_Find(new_desk_ptr,pull_down,Max_Depth,mx,my,sel);
         IF sel <> old_sel THEN BEGIN
            IF old_sel <> Null_Index THEN
               Obj_SetState(new_desk_ptr,old_sel,Normal,TRUE);
            IF sel <> Null_Index THEN
               Obj_SetState(new_desk_ptr,sel,Selected,TRUE);
            old_sel := sel
         END;
         Graf_MKState(mx,my,btn_state,kbd_state)
      END;
      IF sel <> Null_Index THEN
         Obj_SetState(new_desk_ptr,sel,Normal,FALSE);
      hide;
      Hide_Mouse;
      Blit(mem_mfdb,screen_mfdb,x,y,x,y,w,h);
      Show_Mouse;
      Obj_SetState(new_desk_ptr,item,Normal,TRUE);
      animate_menu := sel
   END; { ANIMATE_MENU }

  FUNCTION IN_EDIT_AREA ( x,y : INTEGER ) : BOOLEAN;
     BEGIN
        IF (x >= area_x) AND (y > area_y) AND (y < area_y+area_h) THEN
           in_edit_area := TRUE
        ELSE
           in_edit_area := FALSE
     END; { IN_EDIT_AREA }

  PROCEDURE DECODE_POS ( x,y : INTEGER );
     VAR char_pos,col,line_c : INTEGER;
     BEGIN
        col := (x-edit_x) DIV 8 + 1;
        IF col < 1 THEN
           col := 1
        ELSE IF col > line_length THEN
           col := line_length;
        line_c := (y-(area_y-1)) DIV y_dis;
        IF line_c < 0 THEN
           line_c := 0
        ELSE IF line_c > char_count DIV line_length THEN
           line_c := line_count;
        char_pos := line_c*line_length+col;
        IF char_pos > char_count THEN BEGIN
           char_pos := char_count+1;
           col := char_pos-line_c*line_length
        END;
        Hide_Mouse;
        IF pos_in_str = char_count+1 THEN
           Draw_String(x_pix,y_pix,' ')
        ELSE
           Draw_String(x_pix,y_pix,str[pos_in_str]);
        Show_Mouse;
        column := col;
        line_count := line_c;
        pos_in_str := char_pos
     END; { DECODE_POS }
     
  PROCEDURE CURSOR_LEFT;
     BEGIN
         IF pos_in_str > 1 THEN BEGIN
            Hide_Mouse;
            IF pos_in_str = char_count+1 THEN
               Draw_String(x_pix,y_pix,' ')
            ELSE
               Draw_String(x_pix,y_pix,str[pos_in_str]);
            IF (column = 1) AND (line_count > 0) THEN BEGIN
               column := line_length;
               line_count := line_count-1;
               pos_in_str := pos_in_str-1
            END
            ELSE IF column > 1 THEN BEGIN
               column := column-1;
               pos_in_str := pos_in_str-1
            END;
            Show_Mouse
         END
    END; (* CURSOR_LEFT *)
  PROCEDURE CURSOR_RIGHT;
     BEGIN
         Hide_Mouse;
         Draw_String(x_pix,y_pix,str[pos_in_str]); (* get rid of    *)
         Show_Mouse;                               (* inverse video *)
         column := column+1;
         pos_in_str := pos_in_str+1
    END; (* CURSOR_RIGHT *)
  PROCEDURE INSERT_CHAR;
     VAR i,col,l_c : INTEGER;
     BEGIN
         char_count := char_count+1;
         INSERT(CHR(key),str,pos_in_str);
         l_c := line_count;
         col := column;
         Hide_Mouse;
         FOR i := pos_in_str TO char_count DO BEGIN
             IF col > line_length THEN BEGIN
                col := 1;
                l_c := l_c+1
             END;
             x_pix := edit_x+8*(col-1);
             y_pix := edit_y+l_c*y_dis;
             Draw_String(x_pix,y_pix,str[i]);
             col := col+1
         END; (* FOR i *)
         Show_Mouse;
         column := column+1;
         pos_in_str := pos_in_str+1
     END; (* INSERT_CHAR *)
  PROCEDURE DELETE_CHAR;
     VAR i,col,loop_limit,l_c : INTEGER;
     BEGIN
         DELETE(str,pos_in_str,1);
         l_c := line_count;
         col := column;
         char_count := char_count-1;
         { now redraw the remaining portion of the screen, starting with the
           position of the deleted character }
         loop_limit := char_count+1;
         Hide_Mouse;
         FOR i := pos_in_str TO loop_limit DO BEGIN
             IF col > line_length THEN BEGIN
                col := 1;
                l_c := l_c+1
             END;
             x_pix := edit_x+8*(col-1);
             y_pix := edit_y+y_dis*l_c;
             IF i = loop_limit THEN
                Draw_String(x_pix,y_pix,' ')
             ELSE
                Draw_String(x_pix,y_pix,str[i]);
             col := col+1
         END; (* FOR i *)
         Show_Mouse
    END; (* DELETE_CHAR *)
  PROCEDURE BACKSPACE;
     { caller must check if cursor is not in first position }
     BEGIN
         (* if backspacing from end of line, remove cursor *)
         IF pos_in_str = char_count+1 THEN BEGIN
            Hide_Mouse;
            Draw_String(x_pix,y_pix,' ');
            Show_Mouse
         END;
         column := column-1;            { move to last character }
         pos_in_str := pos_in_str-1;
         IF column = 0 THEN BEGIN
            column := line_length;
            line_count := line_count-1
         END;
         delete_char
     END; (* BACKSPACE *)
  PROCEDURE RESET_PARMS;
     { called when ESC is pressed; also when invalid number is entered }
     BEGIN
         default_draw_attributes;
         Text_Alignment(VDI_Left,0); { standard Draw_String values }
         Set_Clip(0,0,screen_width,screen_height);
         char_count := 0;
         line_count := 0;
         pos_in_str := 1;
         column := 1;
         str := '';
         Hide_Mouse;
         Paint_Rect(area_x,area_y,area_w,area_h);
         Show_Mouse
     END; { RESET_PARMS }
  PROCEDURE CHECK_VALIDITY;
     VAR result : StatusType;
         ptr    : CellPtr;
     BEGIN
        { no INTs in this application!
        IF str_type = AnInteger THEN
           IF (str = '+') OR (str = '-') OR (LENGTH(str) = 0) THEN
              GOTO 5;
        }
        str_pos := 1;
        IF str_type = FloatingPoint THEN
           IF str = '' THEN
              null_input := TRUE
           ELSE BEGIN
              result := valid_number(str);
              IF result <> OK THEN BEGIN
                 alert := Do_Alert('[3][Error in number!][  OK  ]',1);
                 ptr := locate_cell(data_row,data_col);
                 IF ptr <> NIL THEN
                    ptr^.status := result;
                 IF small_text THEN
                    Set_Char_Height(6);
                 cell_on_screen(1,data_row,data_col,TRUE);
                 IF small_text THEN
                    Set_Char_Height(13);
                 write_cell_name;
                 reset_parms;
                 GOTO 5
              END
           END
        ELSE IF (LENGTH(str) = 0) OR (old_form = str) THEN
           null_input := TRUE;
     END; { CHECK_VALIDITY }

FUNCTION EXIT_KEY : BOOLEAN;
   BEGIN
       exit_key := TRUE;
       IF (inp_code <> w_Message) AND (inp_code <> w_mouse) THEN
             CASE key OF
                $011B : BEGIN { ESC }
                   reset_parms;
                   GOTO 5
                END;
                $4D00 : inp_code := w_RIGHT_ARROW;
                $5000 : inp_code := w_DOWN_ARROW;
                $4800 : inp_code := w_UP_ARROW;
                $4B00 : inp_code := w_LEFT_ARROW;
                $1C0D,$720D : inp_code := w_RETURN;
                $4D36 : inp_code := w_PAGE_RIGHT;
                $5032 : inp_code := w_PAGE_DOWN;
                $4838 : inp_code := w_PAGE_UP;
                $4B34 : inp_code := w_PAGE_LEFT;
                $1E01 : inp_code := w_CNTL_A;
                $2C1A : inp_code := w_CNTL_Z;
                $1414 : inp_code := w_CNTL_T;
                $3002 : inp_code := w_CNTL_B;
                $3B00 : inp_code := w_F1;
                $3C00 : inp_code := w_F2; 
                $5500 : inp_code := w_sF2;
                $3D00 : inp_code := w_F3;
                $5600 : inp_code := w_sF3;
                $3E00 : inp_code := w_F4;
                $3F00 : inp_code := w_F5;
                $4200 : inp_code := w_F8;
                $4300 : inp_code := w_F9;
                $4400 : inp_code := w_F10;
                $1100 : inp_code := w_COLUMN;
                $2400 : inp_code := w_JUSTIFY;
                $1900 : inp_code := w_PRECISION;
                $1E00 : inp_code := w_START_BLOCK;
                $2C00 : inp_code := w_END_BLOCK;
                $2000 : inp_code := w_DESELECT;
                $1300 : inp_code := w_REPLICATE;
                $1F00 : inp_code := w_SORT;
                $2200 : inp_code := w_GOTO;
                $4700 : inp_code := w_HOME;
                $2F00 : inp_code := w_VIEW;
                $1800 : inp_code := w_percent;
                $1500 : inp_code := w_style;
                $7800 : inp_code := alt_1;
                $7900 : inp_code := alt_2;
                $7A00 : inp_code := alt_3;
                $7B00 : inp_code := alt_4;
                $3000 : inp_code := alt_b;
                $3200 : inp_code := alt_m;
                $2100 : inp_code := alt_f;
                $2600 : inp_code := alt_l;
                $1400 : inp_code := alt_t;
                $2106 : inp_code := c_f;
                $260C : inp_code := c_l;
                $2300 : inp_code := alt_h; 
                $1700 : inp_code := alt_i;
                $4000 : inp_code := f6;
                $4100 : inp_code := f7;
                $5900 : inp_code := sf6;
                $5A00 : inp_code := sf7;
                $2E00 : inp_code := alt_c;
                $2D00 : inp_code := alt_x;
                $2500 : inp_code := alt_k;
                $0211 : inp_code := c_1;
                $0300 : inp_code := c_2;
                $0413 : inp_code := c_3;
                $0514 : inp_code := c_4;
                OTHERWISE : exit_key := FALSE
             END { CASE }   
       ELSE
          exit_key := FALSE  
   END; { EXIT_KEY }

PROCEDURE INITIALIZE;
   BEGIN
      y_dis := 16 DIV rez;
      default_draw_attributes;
      Set_Clip(0,0,screen_width,screen_height);
      Text_Alignment(VDI_Left,0); { standard Draw_String values }
      char_count := 0;
      pos_in_str := 1;
      column := 1;
      line_count := 0;
      Hide_Mouse;
      Paint_Rect(area_x,area_y,area_w,area_h);
      IF inp_code <> w_F THEN BEGIN
         old_form := '';
         str := ''
      END
      ELSE BEGIN { a formula or label was passed and should be displayed }
         old_form := str;
         char_count := LENGTH(str);
         IF LENGTH(str) >= line_length THEN BEGIN
            temp_1 := COPY(str,1,line_length);
            Draw_String(edit_x,edit_y,temp_1);
            line_count := 1;
            IF LENGTH(str) > line_length THEN BEGIN
               temp_1 := COPY(str,line_length+1,LENGTH(str)-line_length);
               Draw_String(edit_x,edit_y+y_dis,temp_1);
               column := LENGTH(temp_1)+1
            END
            ELSE
               column := 1
         END
         ELSE BEGIN
            Draw_String(edit_x,edit_y,str);
            column := char_count+1
         END;
         pos_in_str := char_count+1
      END;
      Show_Mouse
   END; { INITIALIZE }

PROCEDURE PREPARE_FOR_NEXT_INPUT;
   BEGIN
      IF column > line_length THEN BEGIN
         column := 1;
         line_count := line_count+1
      END;
      x_pix := edit_x+8*(column-1); (* Get next character pos *)
      y_pix := edit_y+line_count*16 DIV rez;
      (* This prevents 'blinking' of characters if a cursor key or
         backspace is pressed repeatedly when the cursor can not
         advance ( i.e. pressing backspace when the cursor is on the
         first character ). Can NOT be replaced with XOR_Mode *)
      Hide_Mouse;
      Draw_String(x_pix,y_pix,' ');
      Draw_Mode(Rev_Trans_Mode);
      IF pos_in_str <= char_count THEN
         Draw_String(x_pix,y_pix,str[pos_in_str])
      ELSE
         Draw_String(x_pix,y_pix,' ');
      Draw_Mode(Replace_Mode);
      Show_Mouse
   END; { PREPARE_FOR_NEXT_INPUT }
       
PROCEDURE META_INSERT;
   VAR i : INTEGER;
   BEGIN
      IF (pos_in_str > max_length) OR 
         (LENGTH(str)+LENGTH(temp_1) > max_length) THEN BEGIN
         alert := Do_Alert(too_long,1);
         IF pos_in_str > max_length THEN BEGIN
            Hide_Mouse;
            Draw_String(x_pix,y_pix,' ');
            Show_Mouse
         END;   
         GOTO 100
      END;
      i := 1;
      IF pos_in_str <= char_count THEN { insert }
         WHILE i <= LENGTH(temp_1) DO BEGIN
            key := ORD(temp_1[i]);
            insert_char; { insert mode }
            i := i+1;
            IF i <= LENGTH(temp_1) THEN
               prepare_for_next_input
         END
      ELSE 
      WHILE i <= LENGTH(temp_1) DO BEGIN
         str := CONCAT(str,temp_1[i]);
         Hide_Mouse;
         Draw_String(x_pix,y_pix,temp_1[i]);
         Show_Mouse;
         char_count := char_count+1;
         pos_in_str := pos_in_str+1;
         column := column+1;
         i := i+1;
         IF i <= LENGTH(temp_1) THEN
            prepare_for_next_input
      END
   END; { META_INSERT }   
                       
  BEGIN  (* WINDOW_INPUT *)
        quit := FALSE;
        IF small_text THEN
           Set_Char_Height(13);
        IF Front_Window = act_hdl THEN
           initialize;
 5:     null_input := FALSE;
        inp_code := NoCode;
        LOOP (* Main Loop - get keyboard, message, and mouse button events *)
           IF Front_Window = act_hdl THEN BEGIN
              bad_str := FALSE;
              prepare_for_next_input
           END;
           End_Update;
           IF Front_Window = act_hdl THEN
              event := Get_Event ( inp_mask ,
                                   1 , 1 , 1 , 0 ,
                                   FALSE , 0 , 0 , 0 , 0 ,
                                   FALSE , 0 , 0 , 0 , 0 ,
                                   msg_area ,
                                   key, btn_state, b_cnt, mx, my, kbd_state )
           ELSE
              event := Get_Event(E_Message,0,0,0,0,FALSE,0,0,0,0,
                                 FALSE,0,0,0,0,msg_area,dummy,dummy,
                                 dummy,dummy,dummy,dummy);
           Begin_Update;
           IF event & E_Message <> 0 THEN BEGIN
              IF (msg_area[0] = MN_Selected) AND
                 (msg_area[3] = mhelp) THEN BEGIN
                 CASE msg_area[4] OF
                    mkeyboar : help(1);
                    mformula : help(2);
                    mprinth  : help(3);
                    mmouse   : help(4);
                    mcellref : help(5);
                    mrecalcm : help(6)
                 END;
                 Menu_Normal(main_menu,mhelp);
                 GOTO 100
              END;
              inp_code := w_MESSAGE;
              quit := TRUE
           END
           ELSE IF event & E_Button <> 0 THEN
              IF kbd_state & 3 = 0 THEN { neither shift key pressed }
                 IF Obj_Find(new_desk_ptr,menubox,Max_Depth,
                             mx,my,indx) THEN
                    IF str_type = AlphaNumeric THEN BEGIN
                       ins := TRUE;
                       CASE indx OF
                          pullmath : BEGIN
                             indx := animate_menu(pullmath,mathmenu);
                             CASE indx OF
                                pullln    : temp_1 := 'LN(';
                                pullexp   : temp_1 := 'EXP(';
                                pulllog   : temp_1 := 'LOG(';
                                pullsqr   : temp_1 := 'SQR(';
                                pullsqrt  : temp_1 := 'SQRT(';
                                pullfac   : temp_1 := 'FAC(';
                                pulldiv   : temp_1 := 'DIV(';
                                pullmod   : temp_1 := 'MOD(';
                                pullroun  : temp_1 := 'ROUND(';
                                pulltrnc  : temp_1 := 'TRUNC(';
                                pullabs   : temp_1 := 'ABS(';
                                pullrand  : temp_1 := 'RAND(';
                                pullplus  : temp_1 := '+';
                                pullminu  : temp_1 := '-';
                                pullstar  : temp_1 := '*';
                                pullslas  : temp_1 := '/';
                                pullcara  : temp_1 := '^';
                                pullopen  : temp_1 := '(';
                                pullclos  : temp_1 := ')';
                                pullcoln  : temp_1 := ':';
                                pullcomm  : temp_1 := ',';
                                OTHERWISE : ins := FALSE
                             END
                          END;   
                          pulltrig : BEGIN
                             indx := animate_menu(pulltrig,trigmenu);
                             CASE indx OF
                                pullsin   : temp_1 := 'SIN(';
                                pullcos   : temp_1 := 'COS(';
                                pulltan   : temp_1 := 'TAN(';
                                pullasin  : temp_1 := 'ASIN(';
                                pullacos  : temp_1 := 'ACOS(';
                                pullatan  : temp_1 := 'ATAN(';
                                pullrad   : temp_1 := 'RAD(';
                                pulldeg   : temp_1 := 'DEG(';
                                pullpi    : temp_1 := 'PI()';
                                OTHERWISE : ins := FALSE
                             END
                          END;
                          pullstat : BEGIN
                             indx := animate_menu(pullstat,statmenu);
                             CASE indx OF
                                pullsum   : temp_1 := 'SUM(';
                                pullprod  : temp_1 := 'PROD(';
                                pullmean  : temp_1 := 'MEAN(';
                                pullvar   : temp_1 := 'VAR(';
                                pullsdev  : temp_1 := 'SDEV(';
                                pullserr  : temp_1 := 'SERR(';
                                pulllinr  : temp_1 := 'LINR(';
                                pullcorr  : temp_1 := 'CORR(';
                                pullpred  : temp_1 := 'PREDV(';
                                pullmax   : temp_1 := 'MAX(';
                                pullmin   : temp_1 := 'MIN(';
                                pullcoun  : temp_1 := 'COUNT(';
                                OTHERWISE : ins := FALSE
                             END
                          END;
                          pullfin : BEGIN
                             indx := animate_menu(pullfin,finmenu);
                             CASE indx OF
                                pullpv    : temp_1 := 'PV(';
                                pullfv    : temp_1 := 'FV(';
                                pullnper  : temp_1 := 'NPER(';
                                pullpmt   : temp_1 := 'PMT(';
                                OTHERWISE : ins := FALSE
                             END
                          END;
                          pullbool : BEGIN
                             indx := animate_menu(pullbool,boolmenu);
                             CASE indx OF
                                pullif    : temp_1 := 'IF(';
                                pulland   : temp_1 := 'AND(';
                                pullor    : temp_1 := 'OR(';
                                pullnot   : temp_1 := 'NOT(';
                                pulleq    : temp_1 := '=';
                                pullneq   : temp_1 := '<>';
                                pulllt    : temp_1 := '<';
                                pulllteq  : temp_1 := '<=';
                                pullgt    : temp_1 := '>';
                                pullgteq  : temp_1 := '>=';
                                OTHERWISE : ins := FALSE
                             END
                          END;   
                          pulltab : BEGIN
                             indx := animate_menu(pulltab,tabmenu);
                             CASE indx OF
                                pullindx  : temp_1 := 'INDEX(';
                                pullvl    : temp_1 := 'VLOOKUP(';
                                pullhl    : temp_1 := 'HLOOKUP(';
                                OTHERWISE : ins := FALSE
                             END
                          END;
                          OTHERWISE : ins := FALSE
                       END;
                       IF ins THEN 
                          meta_insert;
                       GOTO 100
                    END
                    ELSE
                       GOTO 100
                 ELSE IF Obj_Find(new_desk_ptr,cross,Max_Depth,
                             mx,my,indx) THEN BEGIN
                    delete_cell(data_row,data_col,FALSE);
                    IF small_text THEN
                       Set_Char_Height(6);
                    cell_on_screen(Black,data_row,data_col,TRUE);
                    IF small_text THEN
                       Set_Char_Height(13);
                    key := 0;
                    inp_code := NoCode;
                    quit := TRUE
                 END
                 ELSE IF Obj_Find(new_desk_ptr,check,Max_Depth,
                                  mx,my,indx) THEN
                    key := $1C0D
                 ELSE IF in_edit_area(mx,my) THEN BEGIN
                    decode_pos(mx,my);
                    GOTO 100
                 END
                 ELSE IF Wind_Find(mx,my) = act_hdl THEN BEGIN
                    { the following allows user to get out of "runaway"
                      keypresses by clicking on cell; we must clear
                      AES message pipe-line of keyboard events. The
                      pipe can hold about 8 events and the keyboard
                      buffer holds more than this; however, as event slots
                      become open, the AES fills them and the timer clause
                      assures I get all of the keys in the keyboard buffer }
                    REPEAT
                       event := Get_Event(E_KeyBoard|E_Timer,0,0,0,2,
                                          FALSE,0,0,0,0,FALSE,0,0,0,0,
                                          msg_area,dummy,dummy,dummy,
                                          dummy,dummy,dummy)
                    UNTIL event & E_Timer <> 0;                      
                    inp_code := w_MOUSE;
                    msg_area[0] := b_cnt;
                    msg_area[1] := mx;
                    msg_area[2] := my;
                    quit := TRUE
                 END
                 ELSE
                    GOTO 100
              ELSE IF mouse_row_col(mx,my,my,mx) THEN
                 IF str_type = AlphaNumeric THEN BEGIN
                    int_to_string(my,temp_1);
                    temp_1 := CONCAT(col_name[mx],temp_1);
                    meta_insert;
                    event := Get_Event(E_Timer,0,0,0,200,FALSE,0,0,0,0,
                                       FALSE,0,0,0,0,msg_area,dummy,dummy,
                                       dummy,dummy,dummy,dummy);
                    GOTO 100                 
                 END
                 ELSE 
                    GOTO 100
              ELSE
                 GOTO 100;
           { must have been an E_KeyBoard }
           EXIT IF (exit_key) OR (quit);
           IF Front_Window = act_hdl THEN BEGIN
              IF (key = $7300) AND (char_count > 0) THEN
                 cursor_left
              ELSE IF (key = $7400) AND 
                      (column+line_count*line_length <= char_count) THEN
                 cursor_right
              ELSE IF (key = $537F) AND (pos_in_str <= char_count) THEN
                 delete_char
              ELSE IF (key = $0E08) AND (pos_in_str <= char_count+1) AND
                      (pos_in_str > 1) THEN
                 backspace
              ELSE BEGIN
                 key := key & $00FF; (* convert to ASCII *)
                 IF (pos_in_str > max_length) THEN BEGIN
                    alert := Do_Alert(too_long,1);
                    Hide_Mouse;
                    Draw_String(x_pix,y_pix,' ');
                    Show_Mouse;
                    GOTO 100
                 END;
                 { No INTs in this app! Should pass or delare a set 'digits'
                   to use i.e. ['1'..'9','+','-']
                 IF (str_type = AnInteger) THEN BEGIN
                    IF NOT (CHR(key) IN digits) THEN 
                       bad_str := TRUE;
                    IF (pos_in_str > 1) AND ((key = $2B) OR (key = $2D)) THEN
                       bad_str := TRUE
                 END;
                 }
                 IF (str_type = FloatingPoint) THEN
                    IF NOT (CHR(key) IN float) THEN
                       bad_str := TRUE;
                 IF (str_type = AlphaNumeric) THEN
                    IF NOT ((key >= $20) AND (key <= $7E)) THEN
                       bad_str := TRUE;
                 IF NOT bad_str THEN
                    (* Here, the character retrieved is added
                       or inserted to str. *)
                    IF pos_in_str <= char_count THEN { insert }
                       IF char_count = max_length THEN
                          alert := Do_Alert(too_long,1)
                       ELSE
                          insert_char { insert mode }
                    ELSE BEGIN
                       str := CONCAT(str,CHR(key));
                       Hide_Mouse;
                       Draw_String(x_pix,y_pix,CHR(key));
                       Show_Mouse;
                       char_count := char_count+1;
                       pos_in_str := pos_in_str+1;
                       column := column+1
                    END
              END (* ELSE *)
           END; { IF Front_Window = act_hdl }
100:    END; (* LOOP *)
        IF small_text THEN
           Set_Char_Height(6);
        IF Front_Window = act_hdl THEN
           IF inp_code <= w_return THEN { everything that can assign }
              check_validity
  END; (* WINDOW_INPUT *)

BEGIN  (* dummy program for modular compilation *)
END.


