macro_file metools;

/******************* Multi-Edit STRING Macro Function ***********************

 NAME:         GetUserMacroPath()

 DESCRIPTION:  Returns the path to place user generated .MAC files in.

*****************************07-23-93 11:15am*******************************/
str GetUserMacroPath()  trans2
{
	if( user_path != me_path )
	{
		return(user_path);
	}
	else
	{
		return(me_path + 'MAC\');
	}
}




str TranslateCmdLine( str cmdline, fname[128] ) trans2
/*******************************************************************************
Description:  Translates cmdline so that any occurences of
							<FILE>, <NAME>, <EXT>, <PATH>, <ME_PATH>, <USER_PATH>, <MAC_PATH>
							 are expanded out.

							Also, <%str> is now expanded out to whatever the environment
							variable "str" is.
							AND, <~str> is now expanded out to the value of
							Global_Str( str ).

              fname is the file name to be used.



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

{
	int  jx, jy ;

  while( JX = XPOS('<FILE>',Caps(cmdline),1) )
	{
    cmdline = Str_Del(cmdline,jx,6);
    cmdline = Str_Ins(Truncate_Extension(fname),cmdline,jx);
	}

  while( JX = XPOS('<EXT>',Caps(cmdline),1) )
	{
    cmdline = Str_Del(cmdline,jx,5);
    cmdline = Str_Ins(Get_Extension(fname),cmdline,jx);
	}

  while( JX = XPOS('<NAME>',Caps(cmdline),1) )
	{
    cmdline = Str_Del(cmdline,jx,6);
    cmdline = Str_Ins(Truncate_Path(Truncate_Extension(fname)),cmdline,jx);
	}

  while( JX = XPOS('<PATH>',Caps(cmdline),1) )
	{
    cmdline = Str_Del(cmdline,jx,6);
    cmdline = Str_Ins(Get_Path(fname),cmdline,jx);
	}

  while( JX = XPOS('<ME_PATH>',Caps(cmdline),1) )
	{
    cmdline = Str_Del(cmdline,jx,9);
    cmdline = Str_Ins(me_path,cmdline,jx);
	}

  while( JX = XPOS('<COMSPEC>',Caps(cmdline),1) )
	{
    cmdline = Str_Del(cmdline,jx,9);
    cmdline = Str_Ins(comspec,cmdline,jx);
	}

  while( JX = XPOS('<USER_PATH>',Caps(cmdline),1) )
	{
    cmdline = Str_Del(cmdline,jx,11);
    cmdline = Str_Ins(user_path,cmdline,jx);
	}

  while( JX = XPOS('<MAC_PATH>',Caps(cmdline),1) )
	{
    cmdline = Str_Del(cmdline,jx,10);
    cmdline = Str_Ins(GetUserMacroPath(),cmdline,jx);
	}

  while( JX = XPOS('<USER_ID>',Caps(cmdline),1))
	{
    cmdline = Str_Del(cmdline,jx,9);
    cmdline = Str_Ins(User_id,cmdline,jx);
	}

  while( jx = XPOS('<%',cmdline,1) ) {
    cmdline = Str_Del(cmdline,jx,2);
    jy = XPOS( '>', cmdline, jx );
		if( jy > 0 ) {
      fname = copy( cmdline, jx, jy - jx );
      cmdline = Str_Ins(get_environment( fname ),
            Str_Del(cmdline, jx, jy - jx + 1),
						jx);
		}
	}

  while( jx = XPOS('<~',cmdline,1) ) {
    cmdline = Str_Del(cmdline,jx,2);
    jy = XPOS( '>', cmdline, jx );
		if( jy > 0 ) {
      fname = copy( cmdline, jx, jy - jx );
      cmdline = Str_Ins(global_str( fname ),
            Str_Del(cmdline, jx, jy - jx + 1),
						jx);
		}
	}
  return(cmdline);
}


/******************* Multi-Edit STRING Macro Function ***********************

 NAME:         GetUserMacroPath()

 DESCRIPTION:  Returns the path to place user generated .MAC files in.

*****************************07-23-93 11:15am*******************************/
str GetUserMacroPath()  trans2
{
	if( user_path != me_path )
	{
		return(user_path);
	}
	else
	{
		return(me_path + 'MAC\');
	}
}


/****************************Multi-Edit Macro********************************

 NAME:         GetUserPath

 DESCRIPTION:  Gets the complete path pointing to the user directory, or
							 the Multi-Edit directory if user directories are not being
							 used.

 PARAMETERS:   if create_dirs is TRUE then it will create the user directory
							 if it doesn't exist.

 RETURNS:      A string containing the complete path name including ending
							 backslash.

*****************************12-21-92 02:05pm*******************************/
str GetUserPath( )
{

	return( user_path );
}




str CreateUserPath( str path, int copy_default )
{

	int  t_attr, jx ;
	str  tstr[120], t_search_rec[64] ;

  path = Truncate_Path( path );
	t_attr = File_Search_Attr;
	t_search_rec = file_search_rec;

	File_Search_Attr = $37;

  tstr = user_path;
  path = tstr + path;

  if( first_file( path ) != 0 )
	{
    path = user_path + truncate_path( path );
		File_Search_Attr = $27;
    if(  (first_file( path ) != 0)  )
		{
      if(  copy_default  )
			{
        if(  get_path( path) != me_path )
				{
          jx = Copy_File( me_path + truncate_path(path), path, false );
				}
			}
		}
	}

	file_search_rec = t_search_rec;
	File_Search_Attr = t_attr;
  return( path );
}



str TempFileName( str path ) trans2
{
  str tstr = Global_Str('@TMP_FILE_PATH');
  if(svl(tstr)) {
    tstr = TranslateCmdline( tstr, path );
    if(copy(tstr,svl(tstr),1) != '\') {
      tstr += '\';
		}
    tstr += user_id + path;
	} else {
    tstr = user_id + path;
    tstr = CreateUserPath( tstr, FALSE );
	}
  return(fexpand(tstr));
}






int LocateDbPage( str fname[128], str page_title, int create_if_not_found  )
/*******************************************************************************

Description: Loads up the specified DB file (if it is not already
						loaded), and then searches for the specified page title.

Returns:    1 IF the title was found,
            0 If NOT found.

Parameters:   fname                   The db file name.
              page_title              The page Title.
              create_if_not_found     1 = Create page if not found.

							 (C) Copyright 1991 by American Cybernetics, Inc.
*******************************************************************************/
{
	str  tstr[40];
	int Path_Specified,l,c,r,o;
	int tRegExpStat = reg_exp_stat,   // JKP make sure these get restored
      tCase = ignore_case,
      result;

  if(  (Get_extension(fname) == '')  ) {
/* 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') == '')  ) {
      fname = fname + '.DB';
		} else {
      fname = fname + '.' + Global_Str('@DB_EXTENSION');
		}
	}
  Path_Specified = (Get_Path(fname) != '');
	if(  ((user_id == '') | (Path_Specified == True))  ) {
		tstr = '';
	} else {
		tstr = me_path + user_id + '.USR\';
	}
  if(  switch_file( CAPS( tstr + fname ) )  ) {
    fname = tstr + fname;
		error_level = 0;
	} else {
		if(  (Path_Specified == False)  ) {
      fname = CreateUserPath( fname, TRUE );
		}
		error_level = 0;
    if(  NOT( switch_file( fname ) )  ) {
			Switch_Window( window_count );
			Create_Window;
      Load_File( fname );
			window_attr = $81;
		}
	}
  result = 1;
	if(  error_level == 0  ) {
		reg_exp_stat = TRUE;
		ignore_case  = TRUE;    // JKP added to take care of titles in lower case
    if(  page_title != ''  ) {
      if( global_str( '~SETCONFIG_' + str( window_id ) ) == page_title ) {
				GET_MARK_RECORD( 1, 3, l, c, r, o );
				goto_line( l );
				goto_col( 1 );
        if(  find_text( '%|12' + make_literal(page_title) + '$|| ' ,1,_OldExp)) {
          result = TRUE;
					goto exit;
				}
			}
			tof;
      if(  NOT(Find_Text( '%|12' + make_literal(page_title) + '$|| ' ,0,_OldExp))  ) {
        result = 0;
        if( create_if_not_found ) {
					EOF;
					Insert_mode = true;
					if(  c_col > 1  ) {
						CR;
					}
          TEXT( '|12' + page_title );
          result = 1;
				}
			}
      if( result ) {
        set_global_str( '~SETCONFIG_' + str( window_id ), page_title );
				set_mark_record( 1, 3, c_line, c_col, 1, 1 );
			}
		} else {
			tof;
		}
	} else {
    result = 0;
	}
exit:
	reg_exp_stat = tRegExpStat;
	ignore_case  = tCase;
  return(result);
}



#DEFINE GDR_CASESENSITIVE 1

int GetDbRecord(
/****************************************************************************
Description:  Finds and returns the specified record in a .DB file.
Returns:
              1 if found
              0 if not found, but first record is stored in /GLO=
             -1 if not found and there are no records.
             -2 if the DPT is not found in the DB file.
             -3 if the DB file is not found.

This only works for string and integer fields
****************************************************************************/
          str fname[128],      // db filename
          str dpt[80],         // data page title
          str dbf,             // field name
          str fv,              // field value
          int rec_num,         // record # to return (overrides fv
                               //   and dbf).  Example:  If /#=3 then the
                               //   3rd record will be returned.
          int flags,           // 1 = case sensitive search
          str global_name[20], // name of global variable to store record
          int remove_file,     // if TRUE, then remove DB file from memory
                               //    after operation
          str misc             // Misc parameters
                               //   /AGLO=n  name  of global integer
                               //            to store total #  of
                               //            records
                               //   /LD=str  Delimit to use, default is
                               //            ASCII 127
                               //   /RGLO=n  name of global integer
                               //            to store the # of the found
                               //            record.
                               //   /RS=n    the number of the record to
                               //            start searching from
                 )


{
	int Active_Window = Window_Id,
					Db_Window = 0,
					T_Reg_Exp_Stat = Reg_Exp_Stat,
					T_Ignore_Case = Ignore_Case,
					T_Refresh = Refresh,
					Start_Records,
          result,
          Record_Amount;
  int RecordStart = Parse_Int( "/RS=", Misc );

	ignore_case = true;
  char Delimit = Parse_Str('/LD=',misc);
	if(  (Delimit == '|0')  ) {
		Delimit = '';
	}
	Refresh = False;

  if( !LocateDbPage( fname, dpt, false ))
  {
    result = -3;
    goto exit;
  }

  /*
  if(  (Truncate_Path(fname) != Truncate_Path(File_Name))  ) {
      make_message( fname + " " +  file_name );
      beep;
      result = -3;
			Goto EXIT;
	}
	if (Svl(Dpt)) {
		if (Caps(Get_Line) != ('|12' + DPT)) {
      result = -2;
			Goto EXIT;
		}
	}

   */

  fname = file_name;
	db_window = window_id;


	reg_exp_stat = TRUE;
	Start_Records = C_Line;
	Eol;
	if (Find_Text('%{|12}||{@*@*@*@*START@*@*@*@*}',0,_OldExp)) {
/* If we found a data page title, assume no header in this db */
		if (Cur_Char != '|12') {
			Start_Records = C_Line;
			if(  (Find_Text('%|12',0,_OldExp) == False)  ) {
				Eof;
				if(  (C_Col > 1)  ) {
					Down;
				}
			}
		}
	} else {
		Eof;
		if(  (C_Col > 1)  ) {
			Down;
		}
	}
	++Start_Records;
	Record_Amount = C_Line - Start_Records;

  if(parse_str('/AGLO=', misc) != '')
    Set_Global_Int(Parse_Str('/AGLO=',misc),Record_Amount);


	if(  (Record_Amount < 1)  ) {
    result = -1;
		Goto EXIT;
	}
	if(  (Rec_Num)  ) {
		if(  ((Rec_Num > Record_Amount) | (Rec_Num < 1))  ) {
      result = 0;
			Goto_Line(Start_Records);
		} else {
      result = 1;
			Goto_Line(Start_Records + Rec_Num - 1);
		}
  }
//   else {
//     Goto_Line(Start_Records);
  else if ( RecordStart < Record_Amount ) {
    Goto_Line( Start_Records  + RecordStart );
		Goto_Col(1);
    if ( flags & GDR_CASESENSITIVE ) { // case sensitive field search
			ignore_case = false;
		}
		reg_Exp_Stat = TRUE;


    result = Search_Fwd(Delimit + dbf + '=' +
                  fv  + Delimit + '||$', Record_Amount - RecordStart );
//                   fv  + Delimit + '||$', Record_Amount);
	}
  else {
    Result = 0;
    Goto_Line( Start_Records );
  }
  Set_Global_Str( Global_Name, Get_Line );
  if ( Parse_Str( "/RGLO=", Misc )  != "" ) {
    Set_Global_Int( Parse_Str( "/RGLO=", Misc), C_Line - Start_Records + 1 );
  }

EXIT:
  if(  remove_file  ) {
		if(  (Switch_Win_Id(DB_Window))  ) {
			Delete_Window;
		}
	}
	Reg_Exp_Stat = T_Reg_Exp_Stat;
	Ignore_Case = T_Ignore_Case;
	Switch_Win_Id(Active_Window);
	Refresh = T_Refresh;
  return(result);
}

int CheckDupFields (str dbpage, str dbline[2048], str fielddata, ...)
{
  int tRefresh  = Refresh;
  int dup       = FALSE;

  Refresh       = False;

  tof;
  if (  find_text("%\f" + dbpage + "$| ",0, _OldExp)  )  // find start of header
  {
    down;
    int s_line    = c_line;
    int e_line;
    int num_lines = 0;

    if (find_text ("%\f", 0, _OldExp))
    {
      e_line    = c_line;
      num_lines = e_line - s_line;
    }

    goto_line (s_line);

    int pc  = 0;
    dup = False;

    while ( Get_Param_Type (++pc) == 1 )
    {
      str fstr = Get_Param_Str (pc) + fielddata;

      while (find_text (fstr, num_lines, 0))
      {
        if (dbline != get_line  )
        {
          dup = True;
          break;
        }
        goto_col (1);
        down;
        num_lines = e_line - c_line;
      }
    }

  }
  Refresh      = tRefresh;
  return (dup);
}




str SearchPath( str fname, fpath )
/*******************************************************************************
Description: Searches for a filename in a given path
            TranslateCmdLine is called to parse out any metacommands BEFORE
						the search takes place.

Returns:    complete path and filename, or a NUL string if
            the search was not successful.

*******************************************************************************/
{
	int  jx, jy ;
  str tpath ;

  fname = TranslateCmdLine( fname, "" );
  tpath = TranslateCmdLine( fpath, "" );
	jy = 0;
	fpath = '';
	goto first_time;
LOOP:
  if(  jy > svl(tpath)  ) {
    return('');
	}

  jx = XPos( ';', tpath, jy + 1 );
  if(  jx == 0  ) {
    jx = svl( tpath ) + 1;
  }
  fpath = Copy( tpath, jy + 1, jx - jy - 1 );
  if(  (SVL(fpath) > 0) & (copy(fpath,SVL(fpath),1) != '\')  ) {
    fpath = fpath + '\';
  }
  jy = jx;

first_time:
	if(  file_exists( fpath + fname )  ) {
		return_int = 1;
    return(fexpand(fpath + fname));
	}
	goto loop;

}

