#include winsmall.sh
#include mew_dlgs.sh
#include mewlist2.sh
#include metools.sh
#include dialog.sh
#include mew_btn.sh
#include mewhelp.sh

#define COPYRECORD_HELPLINK "LIST BOX OPTIONS"

#DEFINE _DB_BUTTON_MAX 15

#DEFINE _DB_EDIT       0
#DEFINE _DB_INSERT     1
#DEFINE _DB_DELETE     2
#DEFINE _DB_COPY       3
#DEFINE _DB_SEARCH     5
#DEFINE _DB_AGAIN      6
#DEFINE _DB_PRINT      7
#DEFINE _DB_SELECT     8
#DEFINE _DB_DONE       9
#DEFINE _DB_HELP       10
#DEFINE _DB_MOVE_UP    11
#DEFINE _DB_MOVE_DN    12

#DEFINE _DB_BTN_ENABLED 0x0001
#DEFINE _DB_BTN_FIXED   0x0002

struct db_button_list
{
  byte count;
  word handle[ _DB_BUTTON_MAX ];
  word status[ _DB_BUTTON_MAX ];
}

#DEFINE _DB_MIN_WIDTH  25


int DB(  str data_file[128] = parse_str("/F=", mparm_str),
         str data_page_title[80] = parse_str("/DPT=", mparm_str),
         str header_file[128] = parse_str("/HF=", mparm_str),
         str header_page_title[80] = parse_str("/HPT=", mparm_str),
         str List_Title[78] = parse_str("/LT=",  mparm_str),
         str Data_Title[78] = parse_str("/DT=", mparm_str),
         str Glo_Str[32] = parse_str("/GLO=", mparm_str),
         int List_Mode = Parse_Int('/LO=',mparm_str),
         str misc_parms = mparm_str
         ) trans2 {
/*******************************************************************************
                                MULTI_EDIT MACRO

Name: DB

Description:  A text database manager, capable of considerable versatility.
              Can be used as for such simple things as establishing a pop-up
              phone list, to much more sophisticated uses as managing the
              filename extension setup parameters.  This macro can actually
              be nested so that editing a field can bring up yet another
              database.

File Format:  The header is composed of one field definition per line as
              follows (except for /DBF, the format is the same as individual
              string fields in DATA_IN):

    /TP=field_type/T=field_name/L=line/C=col/W=field_width/ML=max_field_length/DBF=field_designator
    (any number of repeats of the above line)
    ****START****
    (data records)

              The /DBF field designator must be unique, and represents the
              identifier in each record for that field.

              See PHONE.DB for a sample note card file.

Parameters:
            /F=  The file name of the database file.  If no path is
                 specified, then:
                    A.  the ME_PATH is used if no USER_ID is in use
                    B.  the USER_ID directory is used.
            /CP=  Create Prompt.  If present, will be the prompt when user
                  creates a new record.

            /LD= Leading delimiter for each field.  MUST be the last parameter
                 on the command line.  Default is "".

            /LT=  List title  If present, /LT= will replace the file name

            /DT=  Data title  If present, /DT= will be used in the DATA_IN
                  title instead of the list title.

            /NOALPHA=  If 1, No alphabetic sorting will take place.

            /2TOP= If 1, causes DB to move the selected choice to the top of the
                   list.

            /LO= 1 : List only.  Select with <ENTER>.  No DATA_IN screen.
                 2 : Same as 1 but adds the Modify option.

            /NL= No list.  If 1, the DVMENU of records is bypassed.  Display
                /FV= record.
            /FV=  Field value first field of record to be displayed.  Only
                  used if /NL=1 or /C=1.  If /FV is null, the first record will
                  be displayed.

            /PROTECT1 - nn=  Set of first field values of records to protect against
                              deletion.
                example:  /PROTECT1=TEST1/PROTECT2=TEST2

            /C=  Immediately create a new record if /FV= is not found.  Can be
                 used only with /NL=.

            /HF=str  Specifies a header file.  This allows you to use
                a seperate file for your field definitions.
            /PRE=str Prefix for the ISTR, IPARM and IINT.  Use when nesting
                DB.

            /RR=1 no longer supported

            /GLO= Name of global string to store a found record.  Can be used
              with or without /RR=.

            /DS=str Display string global var name.
                  The display string global should be formatted as follows:
                    /field_name=length /field_name=length...
                  ("/" should be replaced by the /LD= delimit)

           /PR=  Print records.  Will, instead of displaying the menu,
                 send it to the currently defined printer device.

           /NC=  If 1, disables Copy record function.

           /NE=  If 1, disables Edit record function.

          /NI= If 1, disables the Create record function.

           /NDF=1   Do NOT delete file window when done.
           /NDH=1   Do NOT delete header window when done.
           /ENC=1   Exit if no records are found.
           /MACRO=str  Name of macro to be run both BEFORE and AFTER
              a record is modified.  The record will be in the global
              variable specified by /GLO=.  The following parameters
              will be passed to the macro:

                  /P=nn     nn = 0  Macro was run before modification.
                               = 1  Macro was run AFTER modification.

                  /GLO=str      name of the global variable containing the
                                record.

          /DPT=str  Name of the page to use for the data in multiple page
                      db files.
          /HPT=str  Name of the page to use for the header in multiple page
                      db files.

          /SRP=n    1 = Allow search.

          /S=       Starting choice.  This will be the hilited choice if <> 0
          /NSF=     Don't save the DB file even if a change is made.  Rarely
                    used.

          /ABT=str  Accept button title override.  Defaults to "OK".
          /CBT=str  Cancel button title override.  Defaults to "Cancel".

          /VA=1     Verify canceling a data_entry screen.

05-18-94  /EMAC=str
                    Specifies a macro to be called for the data entry,
                    INSTEAD of using the standard DATA_IN call.  The
                    following is passed to the macro:

                      /G=str    The name of the global containing the
                                record.

          /ADH=int  The dialog handle to use for addition items
                    on the DB list dialog.  See DIALOG.SH for info
                    on creating these.
                    IMPORTANT:  Use ctrl IDs greater than 3000!

          /ADF=int  Flags for the additional dialog.
                    0x0001      Put the additional data at the top
                    0x0002      Put the additional data at the bottom
                    0x0003      Put the additional data at the right
                    0x0004      Put the additional data at the left


          /BMP=str  Bitmap to use for the upper left corner.

04-20-94

        /FFLD       Used with /NL=1 (no list). Specifies the /DBF field
                    to use in the record search.  Allows the use of the
                    other fields besides the 1st field defined.

                        rm('USERIN^DB '
                          +'/PRE=@FV'
                          +'/F=DBFILE.DB'
                          +'/DPT=DATAPAGETITLE'
                          +'/HPT=HEADERPAGETITLE'
                          +'/GLO=GLOBALRECORD'
                          +'/FFLD=FIELD2'   // field to search on
                          +'/FV=FIELDVALUE' // value to search for
                          +'/NL=1'          // no list - direct edit
                        );




Global Variables Returned:
            Global_Int( '@DB_FILE_CHANGED' )  will be TRUE if any changes
            were made to the file.

               (C) Copyright 1991 by American Cybernetics, Inc.
*******************************************************************************/

  int
          field_count, /* The # of fields in the database */
          tp,         /* current record type */
          No_List,
          t_refresh,
          Create,
          Search_result,
          record_count, /* The # of records in the database */
          jx, jy, jz,      /* Temp vars */
          need_rebuild, /* 1 = Need new list of records */
          end_field = 0,    /* The line number of the last field in the header.
                         end_field will be 0 if a seperate header file is used */
          header_win, /* The database header window */
          old_win,    /* The window we started with */
          db_win,     /* The database data window */
          db_win_time = 0,
          list_ctrl_id = 0, /* The list box control containing the DB list */
          db_win_num,
          max_width,  /* The length of the biggest record */
          use_ds,
          cur_item, cur_row,
          No_Alpha,
          old_width,
          first_display,
          Print_Records,
          Use_Ps,
          T_Insert_Mode,
          T_Truncate_Spaces,
          header_page_line = 0, data_page_line = 0,
          db_exists, header_exists,
          temp_use_ds,
          old_backups,
          db_changed = FALSE,
          menu_level,
          creating = 0,
        //  disp_height = 0,
          Cancel_Macro = Parse_Int('/CANMAC=',misc_parms),
          Delete_Macro = Parse_Int('/DELMAC=',misc_parms),
          Move_Macro = Parse_Int('/MOVEMAC=', misc_parms),
          Copying = 0,
          adh = parse_int('/ADH=', misc_parms),
          adf = parse_int('/ADF=', misc_parms),
          EBC,
          main_dlg = 0,
          th2 = 0,
          list_hwnd = 0
          ;

  str  tstr[2000],
           tstr2[80],
           tstr3,
           Prefix[10],
           mac_str,
           data_entry_macro[128] = parse_str('/EMAC=', misc_parms),
           PP_Str[10],
           TP_STR,
           FV,
           menu_level_str[20],
           disp_str=''
          ;

    struct tmsg msg;
    struct db_button_list dbl;
    struct dlgctrl ctrl;
    struct trect rcDlg;
    struct MewListDispRec drec;

  int line_height = 0, font_height = 0, font_width = 0, dfont = 0;
  char Delimit;

  int tpersistent_blocks = persistent_blocks;

//======================================================================

// local variables for use in new ADDREC routines

  int blind_add = parse_int('/ADDREC=',misc_parms);


// local vars for use in /FFLD find_data modification
// (find record based on data field other than the first one)

  int jj;
	int ffldindex;

  str findfield = parse_str('/FFLD=',misc_parms);
	str fieldname;

//======================================================================
  // messagebox( frame_handle, misc_parms, "DB", mb_ok );

  Set_Global_Int('MENU_LEVEL', Global_Int('MENU_LEVEL') + 1);

  menu_level = global_int('MENU_LEVEL');
  menu_level_str = str(menu_level);

  Error_Level = 0;
  reg_exp_stat = TRUE;
  T_Insert_Mode = Insert_Mode;
  T_Truncate_Spaces = Truncate_Spaces;
  Truncate_Spaces = False;
  Old_Backups = Backups;
  Backups = FALSE;
  Use_Ps = 0;
  Return_Int = XPos('/LD=',misc_parms,1);
  if(  (Return_Int)  ) {
    Delimit = Copy(misc_parms,Return_Int + 4,1);
  } else {
    Delimit = '';
  }
  No_Alpha = Parse_Int('/NOALPHA=',misc_parms);
  No_List = Parse_Int('/NL=',misc_parms);
  // make_message( str(no_list));
  Create = Parse_Int('/C=',misc_parms);
  Jx = XPos('/MACRO=',misc_parms,1);
  if(  (Jx)  ) {
    mac_str = Copy(misc_parms,Jx + 7,254);
    if(  (XPos(' ',Mac_Str,1) == 0)  ) {
      Mac_Str = Mac_Str + ' ';
    }
  }
  Print_Records = False;
  if(  (List_Title == '')  ) {
    List_Title = Truncate_Path( data_page_title);
    if(  (List_Title == '')  ) {
      List_Title = Truncate_Path(data_file);
    }
    if(  (Parse_Int('/TT=',misc_parms) == 1)  ) {
      List_Title = Truncate_Extension(List_Title);
    }
  }

  if(  (Data_Title == '')  ) {
    Data_Title = List_Title;
  }

  Search_Result = 1;
  t_refresh = refresh;

  refresh = false;
  old_win = window_id;
  Prefix = Parse_Str('/PRE=',misc_parms);
  if(  prefix == ''  ) {
    prefix = menu_level_str;
  }

  field_count = 0;
  // tbc = box_count;

  /* Calculate position of box */
/*  x = parse_int('/X=', misc_parms);
  y = parse_int('/Y=', misc_parms);*/
 // Ds_Count = 0;
  Use_Ds = 0;

  /* Get file name.  If no path is specified, then assume the ME directory */
  if(  (Get_extension(data_file) == '')  ) {
/* This provides support for a default DB file extension to be configured.  It
is overridden if the calling macro specifies an extension */
    if(  (Global_Str('@DB_EXTENSION') == '')  ) {
      data_file = data_file + '.DB';
    } else {
      data_file = data_file + '.' + Global_Str('@DB_EXTENSION');
    }
  }

  if(  get_path(data_file) == ''  ) {
    if(  user_id == ''  ) {
      data_file = CAPS(me_path + data_file);
    } else {
      data_file = CAPS(me_path + user_id + '.USR\' + data_file);
    }
    if(  switch_file( data_file ) == FALSE  ) {
      return_str = Truncate_Path(data_file);
      RM('MakeUserPath /DF=1');
      data_file = return_str;
    }
  }
  data_file = CAPS(fexpand(data_file));
/* code for default file extension was here before.  Looks like it should be
about 14 lines above here. */
  error_level = 0;
  db_exists = Switch_File(data_file);
  if(  NOT(db_exists)  ) {
    create_window;
    load_file( data_file );
    window_attr = $80;
    if(  error_level != 0  ) {
      error_level = 0;
      file_name = data_file;
    }
    if(  parse_int('/NDF=', misc_parms) != 0  ) {
      db_exists = TRUE;
    }
  }
  window_attr = $81;
  db_win = window_id;
  db_win_num = cur_window;
  header_win = window_id;

  if(first_file( file_name ) == 0)
  {
    db_win_time = last_file_time;
  }



  /* Check for a seperate header file */
  if(  (Svl(header_file))  ) {
    if(  (Get_extension(Header_File) == '')  ) {
/* This provides support for a default DB file extension to be configured.  It
is overridden if the calling macro specifies an extension */
      if(  (Global_Str('@DB_EXTENSION') == '')  ) {
        Header_File = Header_File + '.DB';
      } else {
        Header_File = Header_File + '.' + Global_Str('@DB_EXTENSION');
      }
    }
    if(  get_path(header_file) == ''  ) {
      return_str = header_file;
      RM('MakeUserPath /DF=1');
      header_file = return_str;
    }
    header_file = CAPS(fexpand(header_file));
    /* If the header_file is not the same as the db file then load the header
      file */
    if(  header_file != data_file  ) {
      header_exists = Switch_File( header_file );
      if(  NOT(header_exists)  ) {
        create_window;
        load_file(header_file);
        window_attr = $80;
        if(  error_level != 0  ) {
          RM('MEERROR^Beeps /C=1');
          goto exit2;
        }
      }
      header_win = window_id;
    }
  }
  CALL find_page_lines;

/* Parse out the Display String array */
  if(  (Use_ds == false)  ) {
    tstr = global_str( parse_str('/DS=', misc_parms ) );
    use_ds = tstr != '';
    if(  use_ds  ) {
     // DSG_Name = '#DBDS';
     // Set_Global_Str(dsg_name + '@' + menu_level_str,TStr);
    //  DSG_Name += menu_level_str;
      disp_str = tstr;
    //  Call BUILD_DS;
    //  DS_Count = Jz;
    }
  }
  need_rebuild = true;
  call build_fields;

  if(  (Field_Count < 1)  ) {
    goto exit2;
  }
  tstr = global_str( 'DB#' + truncate_path(truncate_extension(file_name)) +
                              '^' + truncate_extension(data_page_title) );

/* If the calling macro specified a starting choice, use that instead. */
  cur_item = parse_int('/S=',misc_parms);
  if(  (Cur_Item < 1)  ) {
    if( !No_List ) {
      if(parse_str("/FV=", misc_parms) != "")
      {
        Return_Str = Parse_Str('/FV=',misc_parms);
        call find_data;
      }
    }
    if(cur_item < 1)
    {
      cur_item = parse_int('/S=',tstr);
      cur_row = parse_int('/OR=', tstr );
    }
  } else {
    cur_row = Cur_ITem;
  }
  if(!cur_item)
  {
    cur_row = 1;
    cur_item = 1;
  }

  if(  switch_win_id( db_win )  ) {
  }
  first_display = TRUE;




//----------------------------------------------------------------------

// check to see if a record is being blindly added to database

	if ( blind_add )
	{
		// record should be in glo_str
		// (sub) build_record_list calculates record_count
		//
		call blind_insert_record;
		goto exit2;
	}

//======================================================================




main_loop:
  /* Display the list of all of the fields */

  Copying = False;
  if(  (No_List)  ) {
    call NO_LIST_PROCESS;
    switch_win_id( db_win );
    call set_db_global;
    goto exit2;
  }
  call build_record_list;
  first_display = FALSE;
  if(  (Record_Count == 0)  ) {
    if(  ((Return_Int == 4) | ((Return_Int == 1) & (list_mode == 0)))  ) {
/* Don't allow editing if there is nothing to edit! */
      RM('MEERROR^BEEPS /C=1');
      Goto MAIN_LOOP;
    }
    if(  (Parse_Int('/ENC=',misc_parms))  ) {
      Search_Result = 0;
      Goto EXIT;
    }
  }


  /* Exit from DB */
  if(  return_int == 0  ) {
    switch_win_id( db_win );
    call set_db_global;
    return_str = parse_str(Delimit + parse_str('/DBF=', global_str(Prefix + 'IPARM_1') ) + '=', get_line);
    goto exit2;


  /* Modify was selected */
  } else if(  return_int == 4  ) {
    call modify_dialog;

  /* Display selected record */
  } else if(  return_int == 1  ) {
    if(  (list_mode)  ) {
      if(  parse_int( '/2TOP=', misc_parms ) & NOT(read_only)  ) {
        call move_item_to_top;
      }
      /* IF glo_str = '' THEN
        Goto NO_LIST_EXIT;
      END; */
    }
    if(  (list_mode > 0)  ) {
      call set_db_global;
      goto_line( cur_item + end_field );
      Set_Global_Str(glo_str,Get_Line);
    }
    return_str = parse_str(Delimit + parse_str('/DBF=', global_str(Prefix + 'IPARM_1') ) + '=', get_line);
    Goto EXIT2;

  /* Copy a record */
  } else if(  return_int == 5  ) {
    call user_copy_record;

  /* Create new record.  Put it in the file in alphabetical order */
  } else if(  return_int == 12  ) {
    call user_insert_record;

/* Delete selected record */
  } else if(  return_int == 3  ) {
    call user_delete_record;
/* print the list */
  } else if(  return_int == 6  ) {
    Print_Records = True;
    call build_record_list;
/* search */
  } else if(  ((return_int == 20) | (return_int == 21))  ) {
    RM('DB_SEARCH /DW=' + Str(Db_Win) + '/FC=' + Str(Field_Count) + '/CI=' +
        Str(Cur_Item) + '/PRE=' + Prefix + '/R=' + Str(Return_Int == 21) +
        '/RC=' + Str(Record_Count) + '/EF=' + Str(End_Field));
    Cur_Item = Return_Int;
  }

  goto main_loop;


user_insert_record:
  call check_read_only;
  if(  NOT(read_only)  ) {
    return_str = '';
    tstr3 = parse_str('/CP=', misc_parms);
    if(  tstr3 != ''  ) {
      RM('QUERYBOX /T=Create New Record/P=' + tstr3 + '/W=' + parse_str('/W=' ,global_str(Prefix + 'IPARM_1')) +
            '/ML=' + parse_str('/ML=' ,global_str(Prefix + 'IPARM_1')));
      if(  return_int < 1  ) {
        ret;
      }
    }
    Creating = True;
    call user_create_record;
  }
  ret;



//----------------------------------------------------------------------

// these incorporate an 'Add record on the fly' feature without
// going through any dialog boxes.

blind_insert_record:
	call check_read_only;
	if ( !read_only )
	{
		call blind_create_record;
	}
	ret;

blind_create_record:
	tstr = global_str(glo_str);
	call insert_record;
	// call modify_dialog2; // blind_add == true so no record display - just add
	ret;

//======================================================================



modify_dialog:
    goto_line( end_field + cur_item );

modify_dialog2:
    Set_Global_Str( glo_str, get_line );
    if(  (Creating)  ) {
      TStr = Get_Line;
    }
    if(  mac_str != ''  ) {

// ---------------------------------------------------------------

// if 'copying == TRUE' need to pass the previous record
// e.g. coping a toolbox record requires the BOXID value (first field)
//      of the source record such that toolitems can be copied as well
// (prefix+'copiedrec' is set in subroutine User_copy_record)

      RM( mac_str +
        '/GLO=' + glo_str +
        '/P=0/CREATE=' + Str(Creating) +
        '/COPY=' + str(copying) +
        '/COPYREC='+prefix+'CopiedRec' +
        '/DLGHANDLE=' + str(Main_Dlg) +
        '/DATAHANDLE=' + str(ADH));

// ------------------------------------------------------------------

//      RM( mac_str + '/GLO=' + glo_str + '/P=0/CREATE=' + Str(Creating) + '/COPY=' + str(copying));

      if(  global_str( glo_str ) != get_line  ) {
        put_line( global_str( glo_str ) );
        db_changed = TRUE;
      }
    }


    if( data_entry_macro != '' )
    {
      Jx = C_Line - end_field;
      rm( data_entry_macro + " /GLO=" + glo_str + "/CREATE=" + str(creating) + "/COPY=" + str(copying)
        + "/DLGHANDLE=" + str(Main_Dlg) + "/DATAHANDLE=" + str(ADH));
    }
    else
    {
      call get_data;
      if(  (Creating)  ) {
        TStr = Get_Line;
      }
      Jx = C_Line - end_field;
      RM('USERIN^DATA_IN /NC=1/T=' + Data_Title +
        '/VA=' + parse_str('/VA=', misc_parms) +
        '/#=' + str(field_count) + '/PRE=' + Prefix + '/RGS=' +
        Parse_Str('/RGS=',misc_parms) + '/H=' + Parse_Str('/H=',misc_parms));
    }

    call find_page_lines;  // TMJ - 7/25/94 12:37PM
    call Set_Data_Page_Line;
    goto_line( jx  + end_field );

    if(  return_int  ) {
      if( svl(data_entry_macro) != 0)
      {
        tstr = global_str(glo_str);
        call bypass_set;
      }
      else
        call set_data;
    }
    else
    {
      Set_Global_Str( glo_str, Get_Line);
      if(  (Creating)  ) {
        if(  (Cancel_Macro)  ) {
          RM( mac_str + '/C=1/CREATE=1/GLO=' + glo_str);
        }
        Del_Line;
        Need_rebuild = True;
      } else if(  (Cancel_Macro)  ) {
  /* If the post processing macro should be run even if editing was cancelled,
  do it */
        RM( mac_str + '/C=1/GLO=' + glo_str);
        if(  (Return_Int)  ) {
          Put_Line(Global_Str(glo_str));
          Need_Rebuild = True;
        }
      }
    }
    Copying = False;
    return_str = global_str(Prefix + 'ISTR_1');
    Creating = False;
  ret;

user_copy_record:
    call check_read_only;
    if(  NOT(read_only)  ) {

      if(  (switch_win_id( db_win ) )  ) {
        goto_line(cur_item + end_field);
        Return_Str = parse_str(Delimit + parse_str('/DBF=',global_str(Prefix + 'IPARM_1')) + '=',Get_Line);
set_global_str(prefix+'CopiedRec',return_str);
      }
      if(parse_int("/NCP=", misc_parms))
      {
        return_int = TRUE;
      }
      else
      {
        RM('QUERYBOX /T=Copy a Record/P=' + Shorten_Str(parse_str('/T=' ,global_str(Prefix + 'IPARM_1'))) +
              '/W=' + parse_str('/W=' ,global_str(Prefix + 'IPARM_1')) +
              '/ML=' + parse_str('/ML=' ,global_str(Prefix + 'IPARM_1')) +
              '/H=' + COPYRECORD_HELPLINK);
      }
      if(  return_int > 0  ) {
        Copying = True;
        call copy_record;
        call modify_dialog2;
set_global_str(prefix+'CopiedRec','');
      }
    }
    RET;

check_read_only:
  if(  (read_only)  ) {
    RM('MEERROR^MessageBox /B=1/T="' + file_name + '" IS LOCKED!/M=DB File is locked, no modifications will be allowed.');
  }
  RET;

USER_CREATE_RECORD:
  tstr = Delimit + parse_str('/DBF=', global_str(Prefix + 'IPARM_1')) + '=' + return_str;
  jx = 1;
  while(  jx < field_count  ) {
    ++jx;
    tstr3 = parse_str('/DDEF=', global_str(Prefix + 'IPARM_' + str(jx)));
    if(  svl(tstr3) != 0  ) {
      tstr = tstr + Delimit + parse_str('/DBF=', global_str(Prefix + 'IPARM_' + str(jx))) + '=' + tstr3;
    }
  }
  call insert_record;
  call modify_dialog2;
  ret;


NO_LIST_PROCESS:
    Return_Str = Parse_Str('/FV=',misc_parms);
    call find_data;
    if(  ((No_List == 1) & (Search_Result == 0))  ) {
      if(  (list_mode == true)  ) {
        Set_Global_Str(glo_str,Get_Line);
        ret;
      }
      if(  (Create == 0)  ) {
        if(  (Parse_Str('/FV=',misc_parms) == '')  ) {
          call MODIFY_DIALOG;
        }
      } else {
        call user_create_record;
      }
    }
    else
      call modify_dialog;
    RET;


user_delete_record:
  if(  (Record_Count > 0)  ) {
  /* Check to see if this record is protected */
    if(  (XPos('/PROTECT',misc_parms,1))  ) {
      if(  (switch_win_id( db_win ) )  ) {
        call check_read_only;
        if(  read_only  ) {
          ret;
        }
        goto_line(cur_item + end_field);
        Tstr = Caps(Parse_Str(Delimit + parse_str('/DBF=',global_str(Prefix + 'IPARM_1')) + '=',Get_Line));
        Jx = 1;
  CHECK_PROTECT:
        Tstr3 = Caps(Parse_Str('/PROTECT' + Str(Jx) + '=',misc_parms));
        if(  (Tstr3 != '')  ) {
          if(  (Tstr == Tstr3)  ) {
            RM('MEERROR^MessageBox /B=1/T=/M=This record is protected against deletion!');
            ret;
          } else {
            ++Jx;
            Goto CHECK_PROTECT;
          }
        }
      }
    }
    RM('USERIN^VERIFY /T=Delete this record ?/H=' + Parse_Str('/H=',misc_parms) );
    if(  return_int  ) {
      call delete_record;
    }
  }
  ret;

  int  tx;

/*************************************************************************/
/* Searches for the specified record, according to field 1 */
/* 042693[scm] let's change this to the field whose id is specified
 * by the parameter /FFLD (find field) i.e. /FFLD=NAME
 *
*/


find_data:

	// find /FV field given the field name and target value


  int svregexst = reg_exp_stat;
  if ( findfield != '' )
  {

    for ( jj=1; jj <= field_count; jj++ )
    {
      fieldname = parse_str('/DBF=', global_str(Prefix + 'IPARM_'+str(jj)));
      if ( fieldname == findfield )
        break; // the for loop, we found a match
    }
    ffldindex = jj;
  }
  else
  {
    ffldindex = 1;
  }

/*************************** end scm mods *******************************/

  switch_win_id( db_win );
	goto_line(end_field);
	goto_col(1);
search_again:
	reg_exp_stat = FALSE;

	Search_Result = search_fwd(Delimit + parse_str('/DBF=', global_str(Prefix + 'IPARM_'+str(ffldindex))) + '=' + return_str, 0);
	reg_exp_stat = TRUE;
	if(  (search_result != 0) & (caps(
			parse_str( Delimit + parse_str('/DBF=', global_str(Prefix + 'IPARM_'+str(ffldindex))) + '=', get_line ))					!= caps( return_str ))  ) {
		eol;
		Goto search_again;
	}
	if(  (Search_Result == 0)  ) {
		Goto_line(end_field + 1);
	}
	cur_item = c_line - end_field;
  reg_exp_stat = svregexst;
	ret;


/* Searches for the specified record, according to field 1 */
//find_data:
//  if(  switch_win_id( db_win )  ) {
//  }
//  goto_line(end_field);
//  goto_col(1);
//search_again:
//  Search_Result = find_text(Delimit + parse_str('/DBF=', global_str(Prefix + 'IPARM_1')) + '=' + return_str, 0, 0);
//  if(  (search_result != 0) & (caps(
//      parse_str( Delimit + parse_str('/DBF=', global_str(Prefix + 'IPARM_1')) + '=', get_line ))
//          != caps( return_str ))  ) {
//    eol;
//    Goto search_again;
//  }
//  if(  (Search_Result == 0)  ) {
//    Goto_line(end_field + 1);
//  }
//  cur_item = c_line - end_field;
//  ret;

/* Retrieves the data in the current record and puts it into a DATA_IN compatible
 globals */
get_data:
  jx = 0;
  tstr = get_line;
  while(  jx < field_count  ) {
    ++jx;
    TStr3 = global_str(Prefix + 'IPARM_' + str(jx));
    tp = parse_int('/TP=', Tstr3);
/* Assign to a special global if one exists for this field.  Originally created
for format line initialization. */
    if(  (XPos('/GSTR=',Tstr3,1))  ) {
      if(  ((parse_str(Delimit + parse_str('/DBF=', Tstr3) +
        '=',tstr ) != '') | (Parse_Int('/GSET=',Tstr3) > 0))  ) {
        Set_Global_Str( Parse_Str('/GSTR=',Tstr3),
          parse_str(Delimit + parse_str('/DBF=',TStr3) + '=',TStr));
      }
    }
    if(  (tp == 30) | (tp == 17) | ((tp == 9) | (tp == 0) | (tp == 2) | (Tp == 6) | ((tp == 8) & (Parse_Str('/ISTR=',TStr3) == '')))  ) {
        set_global_str(Prefix + 'ISTR_' + str(jx),
          parse_str(Delimit + parse_str('/DBF=',Tstr3) + '=',
          tstr ));
    } else if( (tp == 18) | (tp == 1) | (tp == 3) | (tp == 4) | (tp == 5) | (tp == 7) | (tp == 13)  ) {
        set_global_int(Prefix + 'IINT_' + str(jx),
          parse_int(Delimit + parse_str('/DBF=',TStr3) + '=',
          tstr ));
    } else if(  (tp == 12)  ) {
      var_parse_int( '/DBV=', tstr3, jz );
      var_parse_int( delimit + parse_str('/DBF=', tstr3 ) + '=', tstr, jy );
      var_parse_int( '/MIN=', tstr3, tx );
      if(  (tx != 0)  ) {
        if(  jy < tx  ) {
          jy = tx;
        }
      }
      if(  (jz == jy)  ) {
        set_global_int(Prefix + 'IINT_' + str(jx), 1 );
      } else {
        set_global_int(Prefix + 'IINT_' + str(jx), 0 );
      }
    }
  }
  ret;

delete_record:
  if(  switch_win_id( db_win )  ) {
    call check_read_only;
    if(  read_only  ) {
      ret;
    }
    goto_line( cur_item + end_field );
    if(  (Delete_Macro)  ) {
      Set_Global_Str( glo_str, Get_Line);
      RM( mac_str + '/D=1/GLO=' + glo_str +
          '/DLGHANDLE=' + str(Main_Dlg) + '/DATAHANDLE=' + str(ADH));
    }
    del_line;
    db_changed = TRUE;
    --record_count;
    switch_win_id( db_win );
    if(  AT_EOF  ) {
      --cur_item;
    }
  //  if(  record_count < (screen_length - 3)  ) {
  //    new_box = TRUE;
  //  }
  }
  ret;

copy_record:
  if(  (switch_win_id( db_win ) )  ) {
    call check_read_only;
    if(  read_only  ) {
      ret;
    }
    goto_line(cur_item + end_field);
    tstr = get_line;
/* Place the prompted for first field value in place of the original for the copy */
    Tstr3 = Delimit + parse_str('/DBF=',global_str(Prefix + 'IPARM_1')) + '=';
    Tstr = Tstr3 + Return_Str + Copy(Tstr,
            Length(parse_str(Tstr3,tstr )) + Svl(Tstr3) + 1,2048);
    call insert_record;
  }
  ret;

  /* Inserts the record contained in tstr into the file at the current position */
insert_record:
  if(  (switch_win_id( db_win ) )  ) {
    call check_read_only;
    if(  read_only  ) {
      ret;
    }
    Call ALPHABETIZE;
    if(  NOT(AT_EOF)  ) {
      Insert_Mode = True;
      if ((xpos("\f",get_line,1) == 1) || (get_line == "****START****")) {
        eol;
        cr;
      } else {  //fixed problem with inserting stuff in the wrong place T.R.
        goto_col(1);
        cr;
        up;
      }
    }
    ++record_count;
    call Put_Line_Here;
  //  if(  record_count < (screen_length - 3)  ) {
  //    new_box = TRUE;
  //  }
  }
  ret;

/* Takes the current record out of the DATA_IN globals and puts it in the file */
set_data:
  call check_read_only;
  if(  read_only  ) {
    ret;
  }
  jx = 0;
  tstr = '';
	int beenhere = 0;
  while(  jx < field_count  ) {
    ++jx;
    TStr3 = global_str(Prefix + 'IPARM_' + str(jx));
    tp = parse_int('/TP=', Tstr3);

/* If we are supposed to use a special global instead of the ISTR, do that */
    if(  (XPos('/GSTR=',Tstr3,1))  ) {
      if(  (Global_Str( Parse_Str('/GSTR=',Tstr3)) != '')  ) {
        tstr = tstr + Delimit + parse_str('/DBF=',Tstr3) + '=' +
              Global_Str(Parse_Str('/GSTR=',Tstr3));
      }
//      Call BYPASS_SET;  this was wrong
			goto ALREADY_SET;
    }
    switch (tp) {
      case 0 :
      case 2 :
      case 6 :
      case 9 :
      case 8 :
      case 17 :
      case 30 :
        if(  global_str(Prefix + 'ISTR_' + str(jx)) != ''  ) {
          tstr = tstr + Delimit + parse_str('/DBF=', tstr3 ) + '=' +
                global_str(Prefix + 'ISTR_' + str(jx));
        }
        break;

      case 1 :
      case 3 :
      case 4 :
      case 5 :
      case 7 :
      case 13 :
      case 18 :
          if(  (tp == 3)  ) {
    /* This looks like a fix T.R. */
            if(  global_int( prefix + 'IINT_' + str(jx)) == 0  ) {
              set_global_int( prefix + 'IINT_' + str(jx), 1);
            }
          }
          if(  global_int(Prefix + 'IINT_' + str(jx)) != 0  ) {
            tstr = tstr + Delimit + parse_str('/DBF=', global_str(Prefix + 'IPARM_' + str(jx))) + '=' +
                  str(global_int(Prefix + 'IINT_' + str(jx)));
          }
          break;

      case 12 :
        if(  global_int(Prefix + 'IINT_' + str(jx)) != 0  ) {
          tstr = tstr + Delimit + parse_str('/DBF=', global_str(Prefix + 'IPARM_' + str(jx))) + '=' +
                parse_str('/DBV=', global_str(prefix + 'IPARM_' + str(jx)));
        }
    }
ALREADY_SET:
  }

BYPASS_SET:
  if(  mac_str != ''  ) {
    Set_Global_Str( glo_str, tstr );
    Set_Global_Int('@DB_NEED_REBUILD!',0);
		if ( !beenhere )
		{
			beenhere = 1;
    	RM( mac_str + '/GLO=' + glo_str + '/P=1/CREATE=' + str(Creating) );
		}
    //RM( mac_str + '/GLO=' + glo_str + '/P=1/CREATE=' + str(Creating) );
    if(  (Return_Int == -100)  ) {
/* This will allow the post processing macro to delete the current record, for
example if the user does not put the proper or neccesary data */
      Del_Line;
      Need_Rebuild = True;
      Ret;
    }
    tstr = global_str( glo_str );
    Need_Rebuild = Global_Int('@DB_NEED_REBUILD!');
  }
  switch_win_id( db_win );
  if(  ((tstr != get_line) | (Copying == True))  ) {
    del_line;
    db_changed = TRUE;
    Call ALPHABETIZE;
    if(  not(at_eof)  ) {
      Insert_Mode = True;
      goto_col(1);
      cr;
      up;
    }

put_line_here:
    call check_read_only;
    if(  read_only  ) {
      ret;
    }

    put_line(tstr);
    cur_item = c_line - end_field;
    switch_win_id( db_win );

   /* need_rebuild := true; */
  }
  ret;

/* Takes the file header that defines the fields and builds DATA_IN compatible
 global parameter variables. */
build_fields:
  Set_Global_Str(Prefix + 'IHELP1','');
  Set_Global_Str(Prefix + 'IHELP2','');
  Set_Global_Str(Prefix + 'IHELP3','');
  tp_str = '';
  if(  switch_win_id( header_win )  ) {
    field_count = 0;
    Goto_Line( header_page_line + 1);
  floop:
    tstr = get_line;
    if(  (tstr == '****START****') | (At_Eof)  ) {
      end_field = c_line;
      goto floop_exit;
    }
    if(  str_char(tstr,1) == '|12'  ) {
      if(  svl(tstr) > 0  ) {
        end_field = c_line;
        goto floop_exit;
      }
    }

/* This is for the new stuff for printer string and display string being in the
 header */
    if(  (XPos('@',TStr,1) == 1)  ) {
      if(  (XPos('@DISPLAY_STRING=',TStr,1) == 1)  ) {
        if(  NOT( use_ds )  ) {
        //  Set_Global_Str('#DBDS@' + menu_level_str,
        //                  Copy(TStr,17,2048));
          TStr = Copy(TStr,17,2048);
        //  DSG_Name = '#DBDS' + menu_level_str;
          disp_str = tstr;
       //   Call BUILD_DS;
       //   Ds_Count = Jz;
          use_ds = true;
        }
/*
      } else if(  (XPos('@PRINTER_STRING=',TStr,1) == 1)  ) {
        Set_Global_Str('#DBPS@' + menu_level_str,
                        Copy(TStr,17,2048));
        use_Ps = true;
*/
      } else if(  (XPos('@IHELP',TStr,1) == 1)  ) {
        Set_Global_Str(Prefix + Copy(Tstr,2,6),Copy(TStr,9,2048));
      }
      Goto other_data;
    }

    ++field_count;
    set_global_str(Prefix + 'IPARM_' + str(field_count), tstr);

    if(  ((Parse_Int('/TP=',Tstr) == 5) | (Parse_Int('/TP=',Tstr) == 11))  ) {
/* This is to accomodate the type 5 true/false. */
        set_global_str(Prefix + 'ISTR_' + str(field_count), Copy(tstr,XPos('/ISTR=',Tstr,1) + 6,255));
    } else {
        set_global_str(Prefix + 'ISTR_' + str(field_count), parse_str('/ISTR=', tstr));
    }

    set_global_int(Prefix + 'IINT_' + str(field_count), parse_int('/IINT=', tstr));
/* Save a special string which ties the /TP= with the /DBF= for use by PARSE_DS */
    tp_str = tp_str + Delimit + Parse_Str('/DBF=', tstr) + '=' + Parse_Str('/TP=',Tstr);
other_data:
    down;
    goto floop;

  floop_exit:
  }

set_data_page_line:
  if(  (db_win != header_win) | (data_page_line != 0)  ) {
    if(  (data_page_line == header_page_line) & (db_win == header_win)  ) {
      data_page_line = end_field;
    }
    end_field = data_page_line;
  }
  if(  (Field_Count < 1)  ) {
    RM('MEERROR^MessageBox /B=2/T=NO HEADER/M=Header in "' + file_name + '" or file not found!  Cannot display menu.');
  }
  switch_win_id( db_win );
  ret;

/* Builds the Variable Length Menu that lists all of the records by their
 first field */

  int  button_lines, go_type ;



build_record_list:
{

  refresh = FALSE;
  if(  (First_Display)  ) {
    FV = Parse_Str('/FV=',misc_parms);
  }
    jx = cur_window;
    old_width = max_width;
    if(  (need_rebuild)  ) {
      working;
      need_rebuild = FALSE;
      max_width = _DB_MIN_WIDTH;
print_it:
      if(  switch_win_id( db_win )  ) {
        jy = cur_window;
        goto_col(1);
        goto_line(end_field + 1);
        record_count = 0;
    //    DSG_Name = '#DBDS' + menu_level_str;
        while(  not(at_eof) & (cur_char != '|12')  ) {
            ++record_count;
          down;
        }

      }
    }
    if(  max_width < _DB_MIN_WIDTH  ) {
      max_width = _DB_MIN_WIDTH;
    }
    if(  cur_item > record_count  ) {
      cur_item = 1;
    }
    switch_win_id(db_win);
    if(  (Record_Count == 0)  ) {
      if(  (Parse_Int('/ENC=',misc_parms))  ) {
        Ret;
      }
    }

    update_status_line;

    if( main_dlg == 0 )
    {

      dbl.count = _DB_BUTTON_MAX - 1;


      for ( jx = 0;  jx < dbl.count; jx++ )
      {
        dbl.handle[jx] = 0;
        dbl.status[jx] = 0;
      }

      main_dlg = Create_MEW_Dlg( list_title, parse_str("/H=",misc_parms), frame_handle, DLG_NOSIZE | DLG_NOCENTER );
      Get_MEW_Dlg_Metrics( main_dlg, line_height, font_height, font_width, dfont );

      int xstyle = bs_pushbutton | ws_tabstop;
      int button_height =  ((DLG_DefBtnHeight * font_height) / 8) + 1;
      int button_space = button_height / 9;
      int th,ell, half_line = button_height / 2;

      int origin_x = 0, origin_y = 0;


      if( adh && (adf == 1 ))
      {
        tstr = menu_item_str( adh, 1, 3 );
        str_to_struct( ctrl, tstr );
        ctrl.whandle = main_dlg;

        struct_to_str( tstr, ctrl );
        menu_set_str( adh, 1, 3, tstr );

        DlgBuild( adh, "", "","", 0 );
        Auto_Size_MEW_Dlg( main_dlg, 10, 10 );

        GetClientRect(main_dlg, &rcDlg);
        origin_y = rcDlg.bottom - rcdlg.top + 4;
      }

      jy = 5 + origin_y;
      jz = font_width * 10;

      if(parse_str("/BMP=", misc_parms) != "")
      {
        BuildMEWComboButton( main_dlg, MEWBTN_RT_RESNAME,
                  parse_str("/BMP=", misc_parms),
                  "",
                  bs_pushbutton | ws_child, MEWBTN_STATICBUTTON | MEWBTN_SIZETOBITMAP,
                  50000, 3 + (jz / 2) - 13, jy, 0, 0,
                  8,0,
                  dfont,
                  0,0,0 );
        jy += button_height + half_line;
      }


      dbl.handle[ _DB_EDIT ] = Create_MEW_Ctrl( "BUTTON", "&Edit", xstyle | ws_tabstop,3,jy,jz,button_height,main_dlg,1004,app_handle, 0);
      if(!Parse_Int('/NE=',misc_parms))
      {
        dbl.status[ _DB_EDIT ] = _DB_BTN_ENABLED;
      }

      jy += button_height + half_line;
      dbl.handle[ _DB_INSERT ]  = Create_MEW_Ctrl( "BUTTON", "&Insert", xstyle,3,jy,jz,button_height,main_dlg,1005,app_handle, 0);
      if(!Parse_Int('/NI=',misc_parms))
      {
        dbl.status[ _DB_INSERT ] = _DB_BTN_ENABLED;
      }

      jy += button_height + button_space;
      dbl.handle[ _DB_DELETE ]  = Create_MEW_Ctrl( "BUTTON", "&Delete", xstyle,3,jy,jz,button_height,main_dlg,1006,app_handle, 0);
      if(!Parse_Int('/ND=',misc_parms))
      {
        dbl.status[ _DB_DELETE ] = _DB_BTN_ENABLED;
      }

      jy += button_height + button_space;
      dbl.handle[ _DB_COPY ]  = Create_MEW_Ctrl( "BUTTON", "&Copy", xstyle,3,jy,jz,button_height,main_dlg,1007,app_handle, 0);
      if(!Parse_Int('/NC=',misc_parms))
      {
        dbl.status[ _DB_COPY ] = _DB_BTN_ENABLED;
      }
      jy += button_height + half_line;
      dbl.handle[ _DB_MOVE_UP ]  = Create_MEW_Ctrl( "BUTTON", "Move &Up", xstyle,3,jy,jz,button_height,main_dlg,1101,app_handle, 0);
      if(Parse_Int('/MOVE=',misc_parms))
      {
        dbl.status[ _DB_MOVE_UP ] = _DB_BTN_ENABLED;
      }
      jy += button_height + button_space;
      dbl.handle[ _DB_MOVE_DN ]  = Create_MEW_Ctrl( "BUTTON", "&Move Dn", xstyle,3,jy,jz,button_height,main_dlg,1102,app_handle, 0);
      if(Parse_Int('/MOVE=',misc_parms))
      {
        dbl.status[ _DB_MOVE_DN ] = _DB_BTN_ENABLED;
      }
      jy += button_height + half_line;
      dbl.handle[ _DB_SEARCH ]  = Create_MEW_Ctrl( "BUTTON", "&Search", xstyle,3,jy,jz,button_height,main_dlg,1009,app_handle, 0);
      if(!Parse_Int('/SRP=',misc_parms))
      {
        dbl.status[ _DB_SEARCH ] = _DB_BTN_ENABLED;
      }
      jy += button_height + button_space;
      dbl.handle[ _DB_AGAIN ]  = Create_MEW_Ctrl( "BUTTON", "&Again", xstyle,3,jy,jz,button_height,main_dlg,1010,app_handle, 0);
      if(!Parse_Int('/SRP=',misc_parms))
      {
        dbl.status[ _DB_AGAIN ] = _DB_BTN_ENABLED;
      }
      jy += button_height + half_line;
      dbl.handle[ _DB_PRINT ]  = 0;
/*
      dbl.handle[ _DB_PRINT ]  = Create_MEW_Ctrl( "BUTTON", "&Print", xstyle,3,jy,jz,button_height,main_dlg,1011,app_handle, 0);
      if(use_ps)
      {
        dbl.status[ _DB_PRINT ] = _DB_BTN_ENABLED;
      }
*/

      ell = jy + button_height + button_space - origin_y;
      jy  = ell + half_line + origin_y;
      // jx += half_line;

      xstyle = bs_defpushbutton | ws_tabstop;
      if( list_mode > 0 )
      {
        dbl.handle[ _DB_SELECT ] = Create_MEW_Ctrl( "BUTTON", "Se&lect", xstyle | ws_tabstop | bs_defpushbutton,3,jy,jz,button_height,main_dlg,1,app_handle, 0);
        dbl.status[ _DB_SELECT ] = _DB_BTN_ENABLED | _DB_BTN_FIXED;
        xstyle = bs_pushbutton | ws_tabstop;
      }

      dbl.handle[ _DB_DONE ] = Create_MEW_Ctrl( "BUTTON", "Close", xstyle,font_width * 13,jy,jz,button_height,main_dlg,2,app_handle, 0);
      dbl.status[ _DB_DONE ] = _DB_BTN_ENABLED | _DB_BTN_FIXED;

      go_type = 1;
      if(  list_mode == 1  ) {
        go_type = 4;
      }

      xstyle = 0;

      if(disp_str == "")
      {
        disp_str = Delimit + parse_str('/DBF=', global_str(Prefix + 'IPARM_1') ) + '=/W=40/IS=1';
      }
      list_hwnd = ListBoxCreate( cur_window, 1, record_count,
              12 * font_width + origin_x, origin_y + 5,
              0, ell - 5,
              100,
              _LB_FLAG_INCSEARCH | _LB_FLAG_AUTOWIDTH, 0, main_dlg,
              disp_str
              );

      Auto_Size_MEW_Dlg( main_dlg, 10, 10 );

      GetClientRect(main_dlg, &rcDlg);

      xstyle = bs_pushbutton | ws_tabstop;

      dbl.handle[ _DB_HELP ] = Create_MEW_Ctrl( "BUTTON", "&Help", xstyle, rcdlg.Right - (font_Width * 11),jy,jz,button_height,main_dlg,3,app_handle, 0);
      dbl.status[ _DB_HELP ] = _DB_BTN_ENABLED | _DB_BTN_FIXED;


      if( adh && (adf == 3 ))
      {
        tstr = menu_item_str( adh, 1, 3 );
        str_to_struct( ctrl, tstr );
        ctrl.whandle = main_dlg;
        ctrl.x = rcDlg.right - rcDlg.left + 10;
        ctrl.y = 10;

        struct_to_str( tstr, ctrl );
        menu_set_str( adh, 1, 3, tstr );

        DlgBuild( adh, "", "","", 0 );
        Auto_Size_MEW_Dlg( main_dlg, 10, 10 );

      }

      Center_MEW_Dlg( main_dlg, false );

      SendMessage(main_dlg, DM_SETDEFID, 2, 0);

    }

    if(dbl.status[ _DB_INSERT ] == _DB_BTN_ENABLED)
    {
      sendmessage( list_hwnd, WM_ML2_SETKEYWCMD, 1005 , 0);
    }
    else
    {
      sendmessage( list_hwnd, WM_ML2_SETKEYWCMD, 0 , 0);
    }

    if(dbl.status[ _DB_DELETE ] == _DB_BTN_ENABLED)
    {
      sendmessage( list_hwnd, WM_ML2_SETKEYWCMD, 1006 , 1);
    }
    else
    {
      sendmessage( list_hwnd, WM_ML2_SETKEYWCMD, 0 , 1);
    }

    sendmessage( list_hwnd, WM_ML2_SETLISTBUF, db_win_num, end_field);

    jx = SendMessage( list_hwnd, LB_GETCOUNT, 0, 0 );
    while(  jx < record_count )
    {
      SendMessage( list_hwnd, LB_ADDSTRING, 0, 0 );
      ++jx;
    }
    while(  jx > record_count )
    {
      SendMessage( list_hwnd, LB_DELETESTRING, jx - 1, 0 );
      --jx;
    }

    call enable_buttons;

    EnableWindow( main_dlg, TRUE );


    if( !list_mode )
    {
      SetDefaultButton( main_dlg, 1004 );
    }
    else
    {
      SetDefaultButton( main_dlg, 1 );
    }

    Update_Status_Line;

    BringWindowToTop( main_dlg );
    sendmessage( list_hwnd, LB_SETCURSEL, cur_item - 1, 0);
    goto_col(1);
    RedrawWindow( list_hwnd, 0, 0, rdw_Invalidate );


    if(!IsWindowVisible( main_dlg ) )
      ShowWindow( main_dlg, TRUE );

    SetFocus( list_hwnd );


      return_int = -1;
      while(getmessage( &msg, 0, 0, 0 ) && (return_int == -1))
      {
        if ( msg.message == WM_USER )
        {
          if ( msg.wparam == 998 )
          {
            msg.wparam = GetDefaultButton( main_dlg ) ;
          }

          switch ( msg.wparam )
          {
            case 2 :
            case 999 :
              return_int = 0;
              break;

            case 3 :
              MewHelp_Context  (); // (parse_str("/H=",misc_parms));
							return_int = -1;
              break;

            case 1 :
              return_int = 1;
              break;

            case 998 :
            case 1004 :
              return_int = 4;
              break;

            case 1005 :
              return_int = 12;
              break;

            case 1006 :
              return_int = 3;
              break;
            case 1007 :
              return_int = 5;
              break;

            case 1101 :
              call move_up;
              break;

            case 1102 :
              call move_down;
              break;

            case 1009 :
              return_int = 20;
              break;
            case 1010 :
              return_int = 21;
              break;
            case 1011 :
              return_int = 6;
              break;
          }
        }
        if (return_int == -1) {
          if (!IsDialogMessage( main_dlg, &msg)) {
            translatemessage( &msg );
            dispatchmessage( &msg );
          }
          return_int = -1;  // we have to do this here because certain events trigger macros that can change the value of return_int

          block_linex;
        }
        else
          break;
      }
    message_exit:
    if( !list_mode )
    {
      SetDefaultButton( main_dlg, 1004 );
    }
    else
    {
      SetDefaultButton( main_dlg, 1 );
    }
    // enablewindow( main_dlg, false );
    if(  (return_int == 1) & (list_mode == 0)  ) {
      return_int = 4;
    }
    refresh = false;
    cur_item = c_line - end_field;
    cur_row = c_row;
    return_str = get_line;
    switch_win_id( db_win );
  }
  ret;



move_up:
  switch_win_id(db_win);
  if(c_line > (end_field + 1))
  {
    persistent_blocks = true;
    block_begin;
    block_end;

    if(move_macro)
    {
      RM( mac_str + '/MOVE=1/GLO=' + glo_str);
    }
    else
    {
      goto_line(block_line1);
      up;
    }
    move_block;
    block_off;
    cur_item = c_line - end_field;
    sendmessage( list_hwnd, LB_SETCURSEL, cur_item - 1, 0);
    RedrawWindow( list_hwnd, 0, 0, rdw_Invalidate );
    persistent_blocks = tpersistent_blocks;
    update_status_line;
    return_int = -1;
    db_changed = TRUE;
  }
  ret;

move_down:
  switch_win_id(db_win);
  if(c_line < (end_field + record_count))
  {

    persistent_blocks = true;
    block_begin;
    block_end;

    if(move_macro)
    {
      RM( mac_str + '/MOVE=2/GLO=' + glo_str);
    }
    else
    {
      goto_line(block_line2);
      down;
      down;
    }
    move_block;
    block_off;
    cur_item = c_line - end_field;
    sendmessage( list_hwnd, LB_SETCURSEL, cur_item - 1, 0);
    RedrawWindow( list_hwnd, 0, 0, rdw_Invalidate );
    persistent_blocks = tpersistent_blocks;
    update_status_line;
    return_int = -1;
    db_changed = TRUE;
  }
  ret;



enable_buttons:
  {

    for(jx = 0; jx < dbl.count; jx++ )
    {
      if( dbl.handle[jx] != 0 )
      {
        if( dbl.status[jx] & _DB_BTN_ENABLED )
        {
          enablewindow( dbl.handle[jx], TRUE );
        }
        else
        {
          enablewindow( dbl.handle[jx], FALSE );
        }
      }
    }

    ret;
  }


disable_buttons:
  {

    for(jx = 0; jx < dbl.count; jx++ )
    {
      if( dbl.handle[jx] != 0 )
      {
        if( !(dbl.status[jx] & _DB_BTN_FIXED ) )
          enablewindow( dbl.handle[jx], FALSE );
      }
    }

    ret;
  }

move_item_to_top:
  if(  (Global_Int('@NO_DB_TO_TOP@'))  ) {
    Ret;
  }
  switch_win_id( db_win );
  Goto_Line(End_Field + Cur_Item);
  tstr = get_line;
  if(cur_item > 1 ) {
    del_line;
    goto_line( end_field);
    eol;
    Insert_Mode = true;
    cr;
    put_line( tstr );
    cur_item = 1;
  }
  ret;


find_page_lines:
  int old_end_field;

  old_end_field = end_field;
  if(  header_page_title != ''  ) {
    switch_win_id( header_win );
    if( header_page_line != 0)
    {
      goto_line(header_page_line);
      goto_col(1);
      if(  !search_fwd('%|12' + make_literal(header_page_title) + ' ||$',1)  )
        header_page_line = 0;

    }
    if(header_page_line == 0)
    {
      tof;
      if(  search_fwd('%|12' + make_literal(header_page_title) + ' ||$',0)  ) {
        header_page_line = c_line;
        if(  search_fwd('%@*@*@*@*START@*@*@*@*$',0)  ) {
    /* Look for end of header */
          End_Field = c_line;
        }
      }
    }
  }
  else
  {
    header_page_line = 0;
  }

  if(  data_page_title != ''  ) {
    switch_win_id( db_win );
    if( data_page_line != 0)
    {
      goto_line(data_page_line);
      goto_col(1);
      if(  !search_fwd('%|12' + make_literal(data_page_title) + ' ||$',1)  )
        data_page_line = 0;
      else
        end_field = old_end_field;

    }
    if(data_page_line == 0)
    {

      tof;
      if(  search_fwd('%|12' + make_literal(data_page_title) + ' ||$',0)  ) {
        data_page_line = c_line;
        if(  header_page_line == 0  ) {
          header_page_line = data_page_line;
          if(  search_fwd('%@*@*@*@*START@*@*@*@*$',0)  ) {
    /* Look for end of header */
            End_Field = c_line;
          }
        }
      } else if(  header_page_line != 0  ) {
        EOF;
        EOL;
        Insert_mode = true;
        CR;
        TEXT('|12'+ data_page_title );
        data_page_line = c_line;
        end_field = 0;
      }
    }
  }
  else
  {
    data_page_line = 0;
  }
  RET;

ALPHABETIZE:
  goto_col(1);
  if(  (No_Alpha)  ) {
    if(cur_item < 1)
    {
      cur_item = 1;
    }
    if(  (Record_Count < 1)  ) {
      Goto_Line(End_Field + 1);
    } else {
      Goto_Line(End_Field + Cur_Item);
    }
  } else {
    goto_line(end_field+1);
    goto_col(1);
    tstr2 = Delimit + parse_str('/DBF=', global_str(Prefix + 'IPARM_1')) + '=';
    tstr3 = caps(parse_str(tstr2,tstr));
    while(  not(at_eof) & (caps(parse_str(tstr2,get_line)) < tstr3) &
      (Cur_Char != '|12')  ) {
      down;
    }
  }
  RET;
set_db_global:

  set_global_str( 'DB#' + truncate_path(truncate_extension(file_name))+
                  '^' +
                  truncate_extension(data_page_title),
                  '/S=' + Str(cur_item) + '/OR=' + str(cur_row));
  ret;


exit:
  Return_Int = Search_Result - 1;
exit2:

  if( main_dlg != 0 )
  {
    if(adh)
    {
      DlgSetFields(adh);
    }
    destroy_mew_dlg( main_dlg );
    while ( PeekMessage( &msg, 0,WM_USER,WM_USER, PM_REMOVE ))
    {
    }
  }
  jx = 0;

  Set_Global_Str(Prefix + 'IHELP1','');
  Set_Global_Str(Prefix + 'IHELP2','');
  Set_Global_Str(Prefix + 'IHELP3','');

  jx = 0;
  while(  jx < field_count  ) {
    ++jx;
    set_global_str(Prefix + 'IPARM_' + str(jx), '');
    set_global_str(Prefix + 'ISTR_' + str(jx), '');
    set_global_int(Prefix + 'IINT_' + str(jx), 0);
    Set_Global_Str(Prefix + 'DB_GSTR' + Str(jx),'');
  }

  if(  switch_win_id( db_win )  ) {
    make_window_visible(0);
    window_attr = 0x81;
    jx = db_changed;
    if(!jx)
    {
      if(first_file( file_name ) == 0)
      {
        jx = (db_win_time != last_file_time);
      }
    }
    set_global_int('@DB_FILE_CHANGED', jx );
    set_global_int('!*' + truncate_path(file_name), jx );
    if ((db_changed == true) && (Parse_Int('/NSF=',misc_parms) == false)) {
      do {
        Error_Level = 0;
        save_file;
        if ( Error_Level ) {
          jx = menu_create;
          jy = return_int;
          menu_set_item(jx,1,' Retry ','','/L=2/QK=2/R=0/W=7/C=2',11,0,0);
          menu_set_item(jx,2,' Switch to DB window ','','/L=2/QK=2/R=1/W=21/C=11',11,0,0);
          menu_set_item(jx,3,' Abandon ','','/L=2/QK=2/R=3/W=10/C=35',11,0,0);
          menu_set_item(jx,4,'Switch to DB window will exit and bring the  ','','/L=5/C=1',10,0,0);
          menu_set_item(jx,5,'DB file up in a window for you to diagnose','','/L=6/C=1',10,0,0);
          menu_set_item(jx,6,'and remedy the problem manually.','','/L=7/C=1',10,0,0);
          menu_set_item(jx,7,'Abandon will cause you to loose all your','','/L=9/C=1',10,0,0);
          menu_set_item(jx,8,'changes.','','/L=10/C=1',10,0,0);
          RM('MEERROR^Beeps /C=2');
          Return_int = jx;
          RM('USERIN^DATA_IN /HN=1/#=8/T=ERROR ' + str(error_level) +
                  ' SAVING ' + file_name  + '/S=1');
          menu_delete(jx);
          jx = return_int;
          return_int = jy;
          switch ( jx ) {
            case 0 :
              break;
            case 1 :
              window_attr = 0;
              old_win = window_id;
              Goto SWITCH_DB;
              break;
            case 3 :
              Error_Level = 0;
              break;
          }
        }
      } while (Error_Level);
    }
    if(  NOT( db_exists )  ) {
      delete_window;
    }
  }

SWITCH_DB:
  if(  (db_win != header_win) & switch_win_id( header_win )  ) {
    if(  NOT( header_exists )  ) {
      delete_window;
    }
  }


  switch_win_id(old_win);
  Set_Global_Int('MENU_LEVEL', menu_level - 1);
  Set_Global_Str('@DBS_SEARCH','');
  Set_Global_Str('@DBS_FIELD','');
  Backups = Old_Backups;
  Insert_Mode = T_Insert_Mode;
  Truncate_Spaces = T_Truncate_Spaces;
  Refresh = T_Refresh;
  update_status_line;
  return(return_int);

}



macro DB_SEARCH TRANS {
/*******************************************************************************
                                MULTI_EDIT MACRO

Name: DB_SEARCH

Description:  Performs a search in a db file.  For use by DB only.

               (C) Copyright 1991 by American Cybernetics, Inc.
*******************************************************************************/
  int Active_Window = Window_Id,
          Db_Window = Parse_int('/DW=',Mparm_Str),
          T_Refresh = Refresh,
          Field_Count = Parse_Int('/FC=',MParm_Str),
          Counter,
          T_Int,
          Type,
          Menu_Window = 0,
          Cur_Item = Parse_Int('/CI=',MParm_Str),
          T_Cur_Item = Cur_Item,
          Field_Width = 0,
          Max_Length = 0,
          T_Line,
          T_Col,
          T_Reg_Exp_Stat = Reg_Exp_Stat,
          T_Ignore_Case = Ignore_Case,
          Search_Amount,
          Data_Start,
          Field_Selection,
          Repeat = Parse_Int('/R=',MParm_Str),
          Repeat_Ok = False,
          Record_Count = Parse_Int('/RC=',Mparm_Str)
          ;
  str IParm[20] = Parse_Str('/PRE=',Mparm_Str) + 'IPARM_',
          Field_Title[80]
          ;
  Refresh = False;

  if (Repeat) {
/* Can't repeat if either global does not exist */
    if ((Length(Global_Str('@DBS_SEARCH')) == 0) |
        (Length(Global_Str('@DBS_FIELD')) == 0)) {
        Repeat = False;
    }
  }
  Reg_Exp_Stat = True;
  Ignore_Case = True;
  Create_Window;
  Menu_Window = Window_Id;
  Counter = 0;
  T_Int = 0;
  while (Counter < Field_Count) {
    ++Counter;
    Type = Parse_Int('/TP=',Global_Str(IParm + Str(Counter)));
    if ((Type == 0) | (Type == 3) | (Type == 8)) {
      Field_Title = Remove_Space(Parse_Str('/T=',Global_Str(IParm + Str(Counter))));

      if (Svl(Field_Title)) {
        T_Int = Parse_Int('/W=',Global_Str(IParm + Str(Counter)));
        if (T_Int > Field_Width) {
          Field_Width = T_Int;
        }
        T_Int = Parse_Int('/ML=',Global_Str(IParm + Str(Counter)));
        if (T_Int > Max_Length) {
          Max_Length = T_Int;
        }
/* This creates an array of DBF field values corresponding to each line */
        Set_Global_Str('@DBSDBF' + Str(C_Line),Parse_Str('/DBF=',Global_Str(IParm + Str(Counter))));
        if (Repeat) {
          if (Field_Title == Global_Str('@DBS_FIELD')) {
            Field_Selection = C_Line;
            Repeat_Ok = True;
          }
        }
        Put_Line(Field_Title);
        Down;
      }
    }
  }

  Tof;

  if ((Repeat == True) & (Repeat_Ok == True)) {
    Create_Global_Str('DBSISTR_1',Global_Str('@DBS_SEARCH'));
    Field_Title = Global_Str('@DBS_FIELD');
    Goto SKIP_PROMPT;
  }

  Create_Global_Str('DBSISTR_1','');
  Create_Global_Str('DBSIPARM_1','/T=Search For:/L=1/QK=1/C=1/W=' +
                    Str(Field_Width) + '/ML=' + Str(Max_Length) + '/GO=');
  Create_Global_Str('DBSIPARM_2','/TP=15/C=1/L=2/H=/QK=1/T=Field to search:/WIN=' +
                  Str(Cur_Window));
  RM('DATA_IN /PRE=DBS/#=2/T=Search a Field');
  if (Return_Int == 0) {
    Goto EXIT;
  }
  Field_Title = Get_Line;
  Set_Global_Str('@DBS_SEARCH',Global_Str('DBSISTR_1'));
  Set_Global_Str('@DBS_FIELD',Field_Title);
  Field_Selection = C_Line;

SKIP_PROMPT:
  Switch_Win_Id(Db_Window);
  Working;
  //RM('MEERROR^MESSAGEBOX /NW=1/T=DB SEARCH/M=Searching the file: "' + File_Name
  //    + '" for the string: "' + Global_Str('DBSISTR_1') + '" in the field: "' +
  //    Field_Title + '"');

/* I'm not using MARK_POS here for a very simple reason,  DB is using MARK_POS
to keep track when nesting DB.  Not using it here will help to prevent filling
up the bookmark stack */
  T_Line = C_Line;
  T_Col = C_Col;

  Data_Start = Parse_Int('/EF=',Mparm_Str) + 1;
  if (Repeat) {
    Goto_Line(Data_STart + Cur_Item);
  } else {
    Goto_Line(Data_Start);
    T_Cur_Item = 1;
  }

SEARCH_AGAIN:
  Search_Amount = Record_Count - T_Cur_Item + 1;

  if (Find_Text(make_literal(Global_Str('DBSISTR_1')),Search_Amount,_OldExp)) {
    Goto_Col(1);
    T_Cur_Item = C_Line - Data_Start + 1;
    if (Find_Text('{' + make_literal(Global_Str('@DBSDBF' + Str(Field_Selection))) +
                  '=[|0-}€-|255]*}{' + make_literal(Global_Str('DBSISTR_1')) +
                  '}{[|0-}€-|255]*||$}',1,_OldExp) == False) {

      Eol;
      Goto SEARCH_AGAIN;
    }
    Cur_Item = T_Cur_Item;
  } else if (Error_Level == 1015) {
    RM('MEERROR^MESSAGEBOX /B=2/M=Search aborted by user.');
  } else {
    RM('MEERROR^MESSAGEBOX /B=2/M=The string: "' + Global_Str('DBSISTR_1') +
        '" was not found in any "' + Field_Title + '" Field.');
  }
  Update_Status_Line;
 //Kill_Box;
  Goto_Line(T_Line);
  Goto_Col(T_Col);

EXIT:
  Reg_Exp_Stat = T_Reg_Exp_Stat;
  Ignore_Case = T_Ignore_Case;
  Set_Global_Str('DBSISTR_1','');
  Set_Global_Str('DBSIPARM_1','');
  Set_Global_Str('DBSIPARM_2','');
  if(  (Switch_Win_Id(Menu_Window))  ) {
    Eof;
/* Get rid of DBF field array */
    Counter = C_Line;
    while (Counter) {
      Set_Global_Str('@DBSDBF' + Str(Counter),'');
      --Counter;
    }

    Delete_Window;
  }
  Switch_Win_Id(Active_Window);
  Refresh = T_Refresh;
  Return_Int = Cur_Item;

}