// $Header: /MeWin/Src/TEMPLATE.S 86    4/26/96 16:52 Dan $

macro_file  TEMPLATE;

//#define TMP_MODELESS 0
#define TMP_MODELESS ( Dlg_Modeless | Dlg_NoParDisable )
#define BLDTMP_HELPLINK  "BUILD TEMPLATE"
#define EDITTMP_HELPLINK "EDIT TEMPLATE"

#include WINDOWS.SH
#include METOOLS.SH
#include TEMPLATE.SH
#include DIALOG.SH
#include MEW.SH
#include MEWLIB.SH
#include LANGUAGE.SH
#include DBTOOLS.SH
#include MEWHELP.SH
#include STDDLGS.SH

#ifdef _Debug_
	#include DBUG.SH
  #include MSGLOG.SH
#endif

// Internal Functions
prototype TEMPLATE {
	void _TmpDecode( str Set, str &TStr, int &Col );
	str  _TmpEvaluate( str &Set, str Template, int ExpandFlags, str AddonTemps );
  int  _TmpAccept( int Dlg, int Focus_Flag );
	void _TmpSaveData( int SaveFile );
  void _TmpSetChange( int Dlg, str Sel_Str, str Tmp_Sel_Str );
}

void Template( int Space_Expand = Parse_Int( "/S=", MParm_Str ) ) Trans2 {

	str Set;
	str Template;
	str Tmp_Name;
	str TmpData;
	str AddonTemps;

	int T_Refresh = Refresh;
	int T_Line = C_Line;
	int T_Col = 0;
	int T_Row = C_Row;
	int ExpandFlags = 0;
	int GlobalOnly = False;

	TmpData = Global_Str( "." + Get_Extension( File_Name ) );
	if ( Svl( TmpData ) != 0 ) {
		if ( Space_Expand && !Parse_Int( "\x7F" + "ATX=", TmpData ) ) {
			GlobalOnly = True;
		}
		if ( !GlobalOnly ) {
			Set = Parse_Str( "\x7F" + "TEMPLATE=", TmpData );
			if ( Svl( Set ) == 0 ) {
				Set = Parse_Str( "\x7F" + "LS=", TmpData );
			}
			AddonTemps = Parse_Str( "\x7F" + "ATEMP=", TmpData );
		}
		if ( ( Svl( Set ) == 0 ) && g_Tmp_Global ) {
			Set = "GLOBAL";
		}
		if ( Svl( Set ) != 0 ) {
			if ( Caps( Set ) == "NONE" ) {
				Set = "GLOBAL";
			}
			if ( Global_Str( "!" + Set + "_Tmp_Data" ) != "" ) {
				Refresh = False;
				g_Tmp_Abort = False;
				Push_Undo;
				if ( Space_Expand ) {
					ExpandFlags = _tmp_xSpace;
				}
				if ( At_Eol ) {
					ExpandFlags |= _tmp_xAtEol;
				}
				g_TmpSavedPB = Persistent_Blocks + 1;
				Persistent_Blocks = True;
				Mark_Pos;
				while ( C_Col > 1 ) {
					Left;
					if ( XPos( Cur_Char, " \t\xFF", 1 ) ) {
						Right;
						break;
					}
				}
				T_Col = C_Col;
				First_Word;
				g_Original_Col = C_Col;
				if ( C_Col == T_Col ) {
					ExpandFlags |= _tmp_xFirstWord;
				}
				Goto_Mark;
				Template = Copy( Get_Line( ), T_Col, C_Col - T_Col );

				Tmp_Name = _TmpEvaluate( Set, Template, ExpandFlags, AddonTemps );
				if ( Svl( Template ) && Svl( Tmp_Name ) ) {
					Space_Expand = False;
					g_TmpRmChars = True;
					g_Tmp_Recurs_Level = 0;
					// this sets up a global so that template config dialog can move to
					// the correct selection
					Set_Global_Str( "!" + Set + "_Last_Tmp", Tmp_Name );
					// insert template
					TmpExpand( Set, Tmp_Name );
					call Position;
				}
				else if ( !Space_Expand ) {
					g_TmpRmChars = True;
					g_Tmp_Recurs_Level = 0;
					Tmp_List( g_TmpFirstSet, g_TmpFirstName );
					call Position;
				}
				Pop_Undo;
				if ( g_Tmp_Abort ) {
					Undo;
				}
				if ( g_TmpSavedPB ) {
					Persistent_Blocks = g_TmpSavedPB - 1;
					g_TmpSavedPB = 0;
				}
				g_TmpRmChars = False;
				g_Template = "";
				g_TmpFirstSet = "";
				g_TmpFirstName = "";
				Refresh = T_Refresh;
			}
			else {
				// run old template macro if there isn't the new data loaded
				if ( Set != "GLOBAL" ) {
					Rm( "Template2 /S=" + Str( Space_Expand ) );
					Space_Expand = False;
				}
			}
		}
	}
	if ( Space_Expand ) {
    Push_Undo;
    if ( Typing_Overwrites_Block && !Persistent_Blocks ) {
      if ( CursorInBlock( True ) ) {
        Delete_Block;
      }
    }
		Text( Char( Key1 ) );
    Pop_Undo;
	}
	return ( );


Position:
	T_Row += C_Line - T_Line; 	// get scrolling correct
	if ( T_Row >= Win_CHeight ) {
		T_Row = Win_CHeight / 2;
	}
	T_Line = C_Line;

	while ( C_Row < T_Row ) {
		Down;
	}
	while ( C_Row > T_Row) {
		Up;
	}
	Goto_Line( T_Line );
	if ( Cur_Char == "\x60" ) {
		TmpGotoField( False, 0 );
	}
	Redraw;
	ret;

}  // Template

macro Template2 Trans2 {
/*******************************************************************************
																MULTI_EDIT MACRO

Description:  Checks for the existence of the language specific global
							variable that contains the template data for that language
							if it exists then it will be used for the template expansion
							otherwise calls the appropriate template macro for the filename
							extension of the current file.  The global variable name is
							determined by a '!' followed by the first 3 characters of the
							language type followed by '.TMPLT0'.  For example the pascal
							global would be '!PAS.TMPLT0' the C global would be '!C.TMPLT0'
							The macro name is determined by the first three characters
							of the language type followed by  '_IND'.  For example, the
							pascal macro would be 'PAS_IND', the C macro would be 'C_IND'

		'îC=' = Expansion case type.
								0 = case sensitive.    Keyword  - case sensitive
																			Expansion - verbatim.
								1 = case insensitive.  Keyword  - case insensitive
																			Expansion - All caps.
								2 = case insensitive.  Keyword  - case insensitive
																			Expansion - First letter caps.
								3 = case insensitive.  Keyword  - case insensitive
																			Expansion - dependent on keyword.
		'îM=' = Minimum number of characters in keyword required for an
							expansion to occurr.
	238 - 'î' = Parameter delimiter
	127 - '' = Field separator
	 20 - '' = Carriage return (Run CR macro)
	174 - '®' = Carriage return (Goto starting column)
	196 - 'Ä' = Record cursor position
	 17 - '' = Move cursor left
	 16 - '' = Move cursor right
	 24 - '' = Move cursor up
	 25 - '' = Move cursor down
	 64 - '@' = Translate next character literally
	168 - '¨' = Remember current column position
	173 - '­' = Goto remembered column number
	240 - 'ð' = Goto starting column
	241 - 'ñ' = Toggle Insert mode
	251 - 'û' = Run macro:  "/*ûC^CCOMMENT"
	252 - 'ü' = Expand template for preceding character (be carefull about
								infinite loops)
	237 - 'í' = Do nothing (used to stop 'keyword' interpretation)
	242 - 'ò' = Indent and set indent level
	243 - 'ó' = Undent and set indent level
	128 - '€' = Expand only in comment.

	Parameters:  /S= - If non-zero then the key pressed will be typed out if
										 There is no template to expand.

							/O= - Override minimum expansion.


							 (C) Copyright 1992 by American Cybernetics, Inc.
*******************************************************************************/
#define FIELDSEP    127
#define CARRIAGE1    20
#define CARRIAGE2   174
#define CURSOR      196
#define MVLEFT       17
#define MVRIGHT      16
#define MVUP         24
#define MVDOWN       25
#define XLATELIT     64
#define REMCOL      168
#define GOCOL       173
#define GOSCOL      240
#define TOGINS      241
#define MACRUN      251
#define TEMPL       252
#define DONOTHING   237
#define _INDENT     242
#define _UNDENT     243
#define COMMENTONLY 128

	char  CurChar;
	str   KeyWord[20], ExpandStr[100], TStr[16],
				TemplateName[16],PrePend='';
	int   old_refresh=refresh,StrPos, StrLen, OrigCol, CCol = 0, CLine, RCol = 0, SKCol,
				OCol = C_Col, TemplateStat = 0, CaseSense, MinExpand, jx,
				tins = insert_mode,
				space_expand = parse_int("/S=", mparm_str ),
				FirstChar = 1;

	push_undo;
	insert_mode = TRUE;
	if( (keywords_str != "") && space_expand ) {
		if( line_stat & 0x30 ) {
			PrePend='€';
		}
	}
	Mark_Pos;
	if ( Global_Str('.' + Get_Extension(File_Name)) != '' )
	{
		TStr = Parse_Str('LS=',Global_Str('.' + Get_Extension(File_Name)));
		if ( Tstr != '' )
		{
			if ( "" != Global_Str(TemplateName = "!"+Copy(TStr,1,3)+".Tmplt0") )
			{
				Refresh = False;
				if ( space_expand )
				{
					First_Word;
					SKCol = C_Col;
					if ( PrePend == (KeyWord = PrePend+Shorten_Str(Get_Word(''))) )
						KeyWord = "";
				}
				else
				{
					while ( (C_Col > 1) )
					{
						Left;
						if ( Pos(Cur_Char,' |9|255') )
						{
							Right;
							break;
						}
					}
					SKCol = C_Col;
					KeyWord = ""+Get_Word(' |9|255');
				}
				Mark_Pos;
				First_Word;
				OrigCol = C_Col;
				Goto_Mark;

				jx = SVL(KeyWord);

				if ( 0 == (MinExpand = Parse_Int('/O=', MParm_Str)) )
					MinExpand = Parse_Int("îM=", Global_Str(TemplateName));

				if ( (jx < (1+MinExpand)) || !MinExpand )
					ExpandStr = "";
				else
				{
					switch ( CaseSense = Parse_Int("îC=", Global_Str(TemplateName)) )
					{
						case 0 :
							ExpandStr = Parse_Str(KeyWord, Global_Str(TemplateName));
							break;

						case 1 :
						case 2 :
						case 3 :
							CurChar = Str_Char(KeyWord, 2);
							KeyWord = Lower(KeyWord);
							if ( "" != (ExpandStr = Parse_Str(KeyWord, Global_Str(TemplateName))) )
							{
								Goto_Col(SKCol);
								Del_Chars(jx - 1);
								ExpandStr = Copy(KeyWord, 2, jx-1)+ExpandStr;
							}
							if ( (CaseSense == 3) && (CurChar == Caps(CurChar)) )
								ExpandStr = Caps(ExpandStr);
							break;
					}
				}
				StrLen = SVL(ExpandStr);

				for ( StrPos = 1; StrPos <= StrLen; StrPos++)
				{
					TemplateStat++;
					switch ( ASCII(CurChar = Str_Char(ExpandStr, StrPos)) )
					{
						case CARRIAGE1 :
							rm('CR');
						case DONOTHING :
							break;

						case CARRIAGE2 :
							mark_pos;
							goto_col( OrigCol );
							set_indent_level;
							goto_mark;
							Cr;
							break;

						case CURSOR :
							CCol = C_Col;
							CLine = C_Line;
							break;

						case MVLEFT :
							Left;
							break;

						case MVRIGHT :
							Right;
							break;

						case MVUP :
							up;
							break;

						case MVDOWN :
							down;
							break;

						case XLATELIT :
							StrPos++;
							Text(Str_Char(ExpandStr, StrPos));
							break;

						case REMCOL :
							RCol = C_Col;
							break;

						case GOCOL :
							if ( RCol )
								Goto_Col(RCol);
							break;

						case GOSCOL :
							Goto_Col(OrigCol);
							break;

						case TOGINS :
							if ( Insert_Mode )
								Insert_Mode = False;
							else
								Insert_Mode = True;
							break;

						case MACRUN :
							rm(Remove_Space(Copy(ExpandStr, 1+StrPos, StrLen - StrPos)));
							StrPos = StrLen;
							break;

						case TEMPL :
							rm('TEMPLATE /O=1');
							break;

						case _INDENT :
							Indent;
							break;

						case _UNDENT :
							Undent;
							break;

						default :
							switch ( CaseSense )
								{
									case 1 :
										CurChar = Caps(CurChar);
										break;

									case 2 :
										if ( FirstChar )
										{
											CurChar = Caps(CurChar);
											FirstChar = 0;
										}
										break;
								}
							Text(CurChar);
					}
					if ( (Caps(CurChar) == Lower(CurChar)) && (!Pos(CurChar, '')) )
						FirstChar = 1;
				}
				if ( CCol )
				{
					Goto_Col(CCol);
					while( (c_line > cline) && (c_line > 1) )
						up;
					while( (c_line < cline) && !at_eof )
						down;
				}
				else if ( 0 == TemplateStat)
					Goto_Col(OCol);
				if ( strlen ) {
					Refresh = old_refresh;
					Redraw;
				}
			}
			else if ( !Parse_Int("/S=", MParm_Str) )
			{
				RM(copy(Tstr,1,8) +'^'+Copy(TStr,1,3)+'TEMP');
				if ( Error_Level != 0 )
				{
					Make_Message('NOT Supported for this file extension.');
					Error_Level = 0;
				}
			}
		}
	}
	if ( (0 == TemplateStat) && space_expand )
	{
		Goto_Mark;
		refresh = old_refresh;
		insert_mode = tins;
		// if no template expanded then output the key that was pressed.  If same key
		//  pressed then continue outputting key until different key is pressed.
		Text(Char(Key1));
 /*		if ( !Global_Int("~In_Repeat") )
		{
			int k1=Key1;
			Push_Undo;
			Read_Key;while(k1==Key1){Text(Char(Key1));Read_Key;}
			Pop_Undo;
			Pass_Key(Key1,Key2);
		} */
	}
	else
		Pop_Mark;
	pop_undo;

	display_line;
}

void TmpButtonExpand(
			str Set	 = Parse_Str( "/S=", MParm_Str ),
			str Name = Parse_Str( "/N=", MParm_Str )
)
/******************************************************************************
															 Multi-Edit Macro
															 25-Jan-96  11:10

	Function: Expand the template Name from the TPT file Set.  Use this macro
						when expanding templates from a toolbar button or menu entry.

	Entry   : str Set 		- The name of the TPT file           						(/S=)
						str Name		- The name of the template to expand            (/N=)

							 Copyright (C) 1996 by American Cybernetics, Inc.
********************************************************************( ldh )***/
{
	int SavRefresh = Refresh;
	int TLine			 = C_Line;
	int TCol 			 = 0;
	int TRow 			 = C_Row;

	Refresh = False;
	g_TmpSavedPB = Persistent_Blocks + 1;
	Persistent_Blocks = True;
	g_Original_Col = C_Col;

	g_Tmp_Recurs_Level = 0;
	if ( Global_Str( "!" + Set + "_Tmp_Data" ) == "" ) {
		Tmp_Init_All( Set, False );
	}
	Set_Global_Str( "!" + Set + "_Last_Tmp", Name );
	Push_Undo;
	TmpExpand( Set, Name );
	call Position;
	Pop_Undo;
	if ( g_Tmp_Abort ) {
		Undo;
	}
	if ( g_TmpSavedPB ) {
		Persistent_Blocks = g_TmpSavedPB - 1;
		g_TmpSavedPB = 0;
	}
	Refresh = SavRefresh;
	return ( );


Position:
	TRow += C_Line - TLine; 	// get scrolling correct
	if ( TRow >= Win_CHeight ) {
		TRow = Win_CHeight / 2;
	}
	TLine = C_Line;

	while ( C_Row < TRow ) {
		Down;
	}
	while ( C_Row > TRow) {
		Up;
	}
	Goto_Line( TLine );
	if ( Cur_Char == "\x60" ) {
		TmpGotoField( False, 0 );
	}
	Redraw;
	ret;

}  // TmpButtonExpand

str Proper( str T_Str[ Max_Line_Length ] ) {
/*
	converts the passed string to proper case
*/
	str t_delimits = " \t",
			prefix = "";
	int str_index = 1,
			caps_flag = 0;

	if (svl(t_str) == 0) {
    return ( "" );
	}
	// move past any leading delimiters
	while (xpos(str_char(t_str, str_index), t_delimits, 1)) {
		++str_index;
	}

	if (str_index > 1) {
		prefix = copy(t_str, 1, str_index - 1);
		t_str = copy(t_str, str_index, max_line_length);
	}
	str_index = 0;

	t_str = prefix + caps(str_char(t_str, 1)) + copy(lower(t_str), 2, svl(t_str) - 1);

	for (/*str_index = 2*/; str_index <= svl(t_str); ++str_index) {
		if (caps_flag) {
			// move past delimits, then caps the first char after
			while (xpos(str_char(t_str, str_index), t_delimits, 1)) {
				++str_index;
			}
			if (str_index <= svl(t_str)) {
				t_str = copy(t_str, 1, str_index - 1) +
								caps(str_char(t_str, str_index)) +
								copy(t_str, str_index + 1, svl(t_str) - str_index);
			}
			caps_flag = 0;
		}
		if (xpos(str_char(t_str, str_index), t_delimits, 1)) {
			caps_flag = 1;
		}
	}

	RETURN(t_str);
}

str _TmpDataFile( str Set ) {
/*
	returns the name of the data file for the passed set name
*/

	return ( Set + tmp_File_Ext );

}  // _TmpDataFile

int _TmpLocateData( str Sel_Str, int Flags )
/*
	attempts to find a template in the current template data file
*/
{
  int FndFlags = _RegExp;

  if ( Flags == 0 ) {
    Tof;
    Eol;
  }
  else if ( Flags < 0 ) {
    FndFlags |= _Backward;
  }
	return ( Find_Text( "^\f" + Make_Literal_X( Sel_Str + tmp_Data_Ext) +
      " |$", 0, FndFlags ) );

}  // _TmpLocateData

int _TmpInitData( str Set, str Name, int AlreadyThere ) {
/*
	Initializes the data in memory for the passed set and template name
*/

  str DataGlobName             = "!" + Set + "_Tmp_Data";
  str TData[ Max_Line_Length ];
	str TStr;
	str Line;
	str Keyword;

  int Result  = 0;
  int GlobCnt = Global_Int( DataGlobName );
	int DataIndex;

	if ( !AlreadyThere ) {
    if ( _TmpLocateData( Name, 0 ) ) {
			AlreadyThere = True;
		}
	}
	if ( AlreadyThere ) {
    // Adjust for multiple globals
    if ( GlobCnt != 0 ) {
      if ( Length( Global_Str( DataGlobName + Str( GlobCnt ) ) ) > _tmpGSLen ) {
        ++GlobCnt;
        Set_Global_Int( DataGlobName, GlobCnt );
      }
      DataGlobName += Str( GlobCnt );
      TData = Global_Str( DataGlobName );
    }
    else {
      if ( Length( Global_Str( DataGlobName ) ) > _tmpGSLen ) {
        ++GlobCnt;
        Set_Global_Int( DataGlobName, GlobCnt );
        DataGlobName += Str( GlobCnt );
      }
      TData = Global_Str( DataGlobName );
    }
		// this initializes the data global index string for this set
    TStr = "\xFE";
		Line = Get_Line( );
    Keyword = Parse_Str( "\x7F" + _db_tmp_Keyword + "=", Line );
		if ( Svl( Keyword ) ) {
			TStr += "\x7F" + _gf_tmp_Template + "=" + Keyword;
			TStr += "\x7F" + _gf_tmp_MinMatch + "=" +
          Str( Parse_Int( "\x7F" + _db_tmp_MinMatch + "=", Line ) );
			TStr += "\x7F" + _gf_tmp_Excmnt + "=" +
          Str( Parse_Int( "\x7F" + _db_tmp_CmntExpand + "=", Line ) );
			TStr += "\x7F" + _gf_tmp_Space + "=" +
          Str( Parse_Int( "\x7F" + _db_tmp_SpaceExpand + "=", Line ) );
			TStr += "\x7F" + _gf_tmp_Eol + "=" +
          Str( Parse_Int( "\x7F" + _db_tmp_EOL + "=", Line ) );
			TStr += "\x7F" + _gf_tmp_FirstWord + "=" +
          Str( Parse_Int( "\x7F" + _db_tmp_FirstWord + "=", Line ) );
			TStr += "\x7F" + _gf_tmp_Name + "=" + Caps( Name ) + "\x7F";
			Set_Global_Str( DataGlobName, TData + TStr );
		}
		Goto_Col( 1 );
		TData = "";
		DataIndex = 0;
		Down;
		if ( !At_Eof  && ( Cur_Char != "\f" ) ) {
			Result = ( Caps( Keyword ) == Caps( Get_Line( ) ) ) && Svl( Keyword );
			TData = _gf_tmp_Special + "=" + Str( Result ) + "\x7F";
			Down;
			++DataIndex;
			while ( !At_Eof  && ( Cur_Char != "\f" ) ) {
				Down;
				++DataIndex;
			}
		}
		if ( ( DataIndex == 1 ) && Result ) {
			Set_Global_Str( DataGlobName, Global_Str( DataGlobName ) + TData );
		}
		Result = DataIndex;
	}
	return ( Result );

}  // _TmpInitData

str _TmpGetSet( ) {
/*
	returns the name of the template set associated with the current file extension
*/

	str ExtSetupData = Global_Str( "." + Get_Extension( File_Name ) );
	str Set = Parse_Str( "\x7F" + "TEMPLATE=", ExtSetupData );

	if ( Svl( Set ) == 0 ) {
		Set = Parse_Str( "\x7F" + "LS=", ExtSetupData );
	}
	return ( Set );

}  // _TmpGetSet

int _TmpLdDataFile( str Set, int Check_Read_Only ) {
/*
	Loads the data file for the current file extension
*/

	int Result;

	if ( Svl( Set ) == 0 ) {
		Set = _TmpGetSet( );
	}
	if( Result = LocateDbPage( _TmpDataFile( Set ), "", 0 ) ) {
		if ( Read_Only && Check_Read_Only ) {
      MsgDlg( "Template data file \"" + File_Name + "\" is locked," +
          "\\nno modifications will be allowed.", "LOCKED FILE!", "", 1 );
		}
		Window_Attr |= 0x81;
	}
	return( Result );

}  // _TmpLdDataFile

void Tmp_Init_All(
      str Set     = Parse_Str( "/SET=", MParm_Str ),
      int Rebuild = Parse_Int( "/REBUILD=", MParm_Str )
)
/*
	Loads all the template data from the template set file into memory
	for the passed set
*/
{
	str Glob_Name = "!" + Set + "_Tmp_Data";

  int Jx;

	if ( Rebuild ) {
		Set_Global_Str( Glob_Name, "" );
    Jx = Global_Int( Glob_Name );
    while ( Jx ) {
      Set_Global_Str( Glob_Name + Str( Jx ), "" );
      --Jx;
    }
    Set_Global_Int( Glob_Name, 0 );
	}
	if ( Global_Str( Glob_Name ) == "" ) {

    int ActiveWindow  = Window_Id;
    int TRefresh      = Refresh;
    int SavInsertMode = Insert_Mode;
    int STime;
    int SFTime;

    str TStr[ Max_Line_Length ];

		Refresh = False;
		if ( _TmpLdDataFile( Set, 0 ) ) {
      if ( File_Changed ) {
        Save_File;
        Error_Level = 0;
      }
      SFTime = GetFileTime( File_Name );
			Tof;
      TStr = Copy( Get_Line( ), 2, Max_Line_Length );
      Set_Global_Str( Glob_Name, TStr );
			Down;
			Goto_Col( 1 );
      if ( ( Cur_Char != "\f" ) && !At_Eof ) {
        // Get and check times
        STime = Parse_Int( "/T=", Get_Line( ) );
        if ( ( STime <= ( SFTime + 5 ) ) && ( STime >= SFTime ) ) {
          Down;
          Goto_Col( 1 );
          Set_Global_Str( Glob_Name, Get_Line( ) );
          Down;

#ifdef _Debug_
  Beep;
#endif
          Jx = 0;
          while ( ( Cur_Char != "\f" ) && !At_Eof ) {
            ++Jx;
            Set_Global_Str( Glob_Name + Str( Jx ), Get_Line( ) );
            Down;
          }
          Set_Global_Int( Glob_Name, Jx );
          goto Exit;
        }
        Goto_Col( 1 );
        while ( ( Cur_Char != "\f" ) && !At_Eof ) {
          Down;
        }
      }
			while ( Cur_Char == "\f" ) {
				Right;
				Jx = _TmpInitData( Set, Get_Word( "." ), 1 );
			}
      Tof;
      Down;
      Insert_Mode = True;
      if ( Cur_Char != "\f" ) {
        Block_Begin;
        do {
          Down;
        } while ( ( Cur_Char != "\f" ) && !At_Eof );
        Up;
        Delete_Block;
      }
      Up;
      Eol;
      Cr;
      // Leave a line for the file time
      Cr;
      Put_Line( Global_Str( Glob_Name ) );
      for ( Jx = 1; Jx <= Global_Int( Glob_Name ); ++Jx ) {
        Eol;
        Cr;
        Put_Line( Global_Str( Glob_Name + Str( Jx ) ) );
      }
      Mark_Pos;
      Tof;
      Down;
      Save_File;
      // Get the file time and write it onto second line of TPT file
      SFTime = GetFileTime( File_Name );
      Put_Line( "/T=" + Str( SFTime ) );
      Save_File;
      Error_Level = 0;
      Insert_Mode = SavInsertMode;
      Goto_Mark;
      Down;
		}
    else {
      Set_Global_Str( Glob_Name, "NONE" );
      if ( Window_Id != ActiveWindow) {
        Delete_Window;
      }
		}

Exit:
		Switch_Win_Id( ActiveWindow );
		Refresh = TRefresh;
	}
}  // Tmp_Init_All

void _TmpRmChars( str Set, str Template, str TmpStr )
/******************************************************************************
															 Multi-Edit Macro
															 14-Dec-95  15:53

	Function: Remove Template characters when they match the start of the keyword
						for the template being expanded.

	Entry   : str Set				- The template set name
						str Template	- The template string to be deleted
						str TmpStr		- The parameters for the template to be expanded

							Copyright (C) 1995-96 by American Cybernetics, Inc.
********************************************************************( ldh )***/
{
	str Data_Str[ Max_Line_Length ] = Global_Str( "!" + Set + "_Tmp_Data" );

	int Case_Sense = Parse_Int( "\x7F" + _gf_tmp_CaseSense + "=", Data_Str );

	TmpStr = Parse_Str( "\x7F" + "TEMPLATE=", TmpStr );
	if ( Svl( TmpStr ) ) {
		if ( !Case_Sense ) {
			Template = Caps( Template );
			TmpStr = Caps( TmpStr );
		}
		if ( StrAbbrev( TmpStr, Template ) ) {
			Goto_Col( C_Col - Svl( Template ) );
			Del_Chars( Svl( Template ) );
		}
	}
}  // _TmpRmChars

void TmpPutText( str Tmp_Str )
/*
	inserts the passed string into the current file according to the
	"Case of result" configuration
*/
{
	switch ( g_Case_Flag) {
		case 2 : // all caps
			Tmp_Str = Caps( Tmp_Str );
			break;

		case 3 : // proper
			Tmp_Str = Proper( Tmp_Str );
			break;

		case 4 : // same as keyword

			char T_Char = g_Template;

			if ( T_Char == Caps( T_Char ) ) {
				Tmp_Str = Caps( Tmp_Str );
			}
			else {
				Tmp_Str = Lower( Tmp_Str );
			}
			break;
	}
	Text( Tmp_Str );

}  // TmpPutText

void _TmpDecode(str Set, &Tmp_Str[MAX_LINE_LENGTH], int &Col) {
/*
	Translates the special metacommands in a single line of a template
*/
	int Jx,
			jy,
			jz,
			t_int,
			t_line, t_col, t_row, t_offset,
			x_line, x_col, x_row, x_offset;
	int NLine, NCol, NRow, NOffset;
	int SavTruncateSpaces = Truncate_Spaces;

	str param, t_str, param2;
	str FieldStr;
  str DefStr;

	char t_char;

	struct tCommentChars rCC;

	col = 0;
	jz = 1;

	Truncate_Spaces = False;
	tmp_str = TranslateCmdLine(tmp_str, file_name);
	if ( XPos( "<-?>", Tmp_Str, 1 ) ) {
		GetCommentChars( rCC );
		if ( Length( rCC.szOpenComment1 ) && Length( rCC.szCloseComment1 ) ) {
			FieldStr = rCC.szOpenComment1 + "?" + rCC.szCloseComment1;
		}
	}
	while (Jx = XPos( '<', tmp_str, jz)) {
		t_char = Str_Char(tmp_str,jx + 1);
		if (xpos(t_char, "-^!", 1)) {
			jz = jx;
			switch ( T_Char ) {
				case "-" :                      // special template metacommands
					tmp_str = Str_Del(tmp_str, Jx, 2);
					Jy = XPos('>', tmp_str, Jx);
					if (Jy > 0) {
						Jy -= Jx;
						param = caps(Copy(tmp_str, Jx, Jy));
						if (xpos("PROMPT", caps(param), 1) == 1) {
							if (xpos(" ", param, 1) == 7) {
								param = "PROMPT";
								param2 = copy(tmp_str, jx + 7, jy - 7);
                if ( T_Int = XPos( "\x60", Param2, 1 ) ) {
                  DefStr = Copy( Param2, T_Int + 1, 255 );
                  Param2 = Copy( Param2, 1, T_Int - 1 );
                }
                else {
                  DefStr = "";
                }
							}
							else {
								param2 = "Enter template string:";
							}
						}
						else if ( XPos( "PUTBLOCK", Caps( Param), 1 ) == 1 ) {
							if ( XPos( " ", Param, 1 ) == 9 ) {
								Param = "PUTBLOCK";
								Param2 = Copy( Tmp_Str, Jx + 9, Jy - 9 );
							}
							else {
								Param2 = "";
							}
						}
						switch ( Param ) {
							case "?" :
								Tmp_Str = Str_Ins( FieldStr, Tmp_Str, Jx );
								Jx += Svl( FieldStr );
								break;

							case "SPACE" : // space (for end of line spaces)
								tmp_str = str_ins(" ", tmp_str, jx);
								++jx;
								break;

							case "TAB" :
								call DoPutText;
								Text( "\t" );
								if ( g_Cr_Flag ) {
									g_TmpCrCol = C_Col;
								}
								continue;

							case "UP" :
								Up;
								break;

							case "CUR" : // cursor_pos
								g_Cursor_Col = Jx - 1;
								if ( C_Col > g_Original_Col ) {
									g_Cursor_Col += C_Col;
								}
								else {
									g_Cursor_Col += g_Original_Col;
								}
								g_Cursor_Line = C_Line;
								break;

							case "SMARTIND+" : // run the macro CR instead of a simple carriage return at any line breaks
								g_Cr_Flag = TRUE;
								break;

							case "SMARTIND-" : // do a simple carriage return instead of run the macro CR at any line breaks
								g_Cr_Flag = FALSE;
								break;

							case "SCUR" : // save cursor pos
								call DoPutText;
								// save cursor pos as a random access mark by "borrowing" one
								Get_Mark_Record( 1, 2, T_Line, T_Col, T_Row, T_Offset );
								Set_Mark( 1 );
								Get_Mark_Record( 1, 2, X_Line, X_Col, X_Row, X_Offset );
								Set_Mark_Record( 1, 2, T_Line, T_Col, T_Row, T_Offset );

								Set_Global_Int( tmp_Cursor_Save, Global_Int( Tmp_Cursor_Save ) + 1 );
								Set_Global_Str( tmp_Cursor_Save + Str( Global_Int( tmp_Cursor_Save ) ),
										"\x7F" + "LINE=" + Str( X_Line ) +
										"\x7F" + "COL=" + Str( X_Col ) +
										"\x7F" + "ROW=" + Str( X_Row ) +
										"\x7F" + "OFFSET=" + Str( X_Offset ) +
										"\x7F" + "CR=" + Str( g_TmpCrCol ) +
										"\x7F" + "OC=" + Str( g_Original_Col ) );
								continue;

							case "RCUR" : // restore cursor pos
								// restore cursor pos as a random access mark by "borrowing" one
								call DoPutText;
								T_Int = Global_Int( tmp_Cursor_Save );
								if ( T_Int > 0 ) {
									T_Str = Global_Str( tmp_Cursor_Save + Str( T_Int ) );
									Set_Global_Int( tmp_Cursor_Save, T_Int - 1 );
									Set_Global_Str( tmp_Cursor_Save + Str( T_Int ), "" );
									Get_Mark_Record( 1, 2, T_Line, T_Col, T_Row, T_Offset );
									Set_Mark_Record( 1, 2,
											Parse_Int( "\x7F" + "LINE=", T_Str ),
											Parse_Int( "\x7F" + "COL=", T_Str ),
											Parse_Int( "\x7F" + "ROW=", T_Str ),
											Parse_Int( "\x7F" + "OFFSET=", T_Str ) );
									Get_Mark( 1 );
									Set_Mark_Record( 1, 2, T_Line, T_Col, T_Row, T_Offset );
									g_TmpCrCol = Parse_Int( "\x7F" + "CR=", T_Str );
									g_Original_Col = Parse_Int( "\x7F" + "OC=", T_Str );
								}
								continue;

							case "XCUR" : 						// exchange cursor pos
								call DoPutText;
								T_Int = Global_Int( tmp_Cursor_Save );
								if ( T_Int > 0 ) {
									T_Str = Global_Str( tmp_Cursor_Save + Str( T_Int ) );
									// save "borrowed" random access mark
									Get_Mark_Record( 1, 2, T_Line, T_Col, T_Row, T_Offset );
									// set and save current cursor pos
									Set_Mark( 1 );
									Get_Mark_Record( 1, 2, X_Line, X_Col, X_Row, X_Offset );
									// goto previous cursor pos
									Set_Mark_Record( 1, 2,
											Parse_Int( "\x7F" + "LINE=", T_Str ),
											Parse_Int( "\x7F" + "COL=", T_Str ),
											Parse_Int( "\x7F" + "ROW=", T_Str ),
											Parse_Int( "\x7F" + "OFFSET=", T_Str ) );
									Get_Mark( 1 );
									// restore borrowed mark
									Set_Mark_Record( 1, 2, T_Line, T_Col, T_Row, T_Offset );
									// replace previous cursor pos with the new cursor pos
									Set_Global_Str( Tmp_Cursor_Save +
											Str( Global_Int( tmp_Cursor_Save ) ),
											"\x7F" + "LINE=" + Str( X_Line ) +
											"\x7F" + "COL=" + Str( X_Col ) +
											"\x7F" + "ROW=" + Str( X_Row ) +
											"\x7F" + "OFFSET=" + Str( X_Offset ) +
											"\x7F" + "CR=" + Str( g_TmpCrCol ) +
											"\x7F" + "OC=" + Str( g_Original_Col ) );
									g_TmpCrCol = Parse_Int( "\x7F" + "CR=", T_Str );
									g_Original_Col = Parse_Int( "\x7F" + "OC=", T_Str );
								}
								continue;

							case "SIND" :
							case "SCIND" :
								++g_TmpIndentCnt;
								Set_Global_Int( tmp_SavIndent + Str( g_TmpIndentCnt ),
										g_Original_Col );
								if ( ( Get_Line( ) != "" ) && ( Param == "SIND" ) ) {
									Mark_Pos;
									First_Word;
									if ( C_Col > g_Original_Col ) {
										g_Original_Col = C_Col;
									}
									Goto_Mark;
								}
								else if ( C_Col > g_Original_Col ) {
									g_Original_Col = C_Col;
								}
								break;

							case "RIND" :
								T_Int = g_TmpIndentCnt;
								if ( T_Int > 0 ) {
									g_Original_Col = Global_Int( tmp_SavIndent + Str( T_Int ) );
									--g_TmpIndentCnt;
								}
								break;

							case "PROMPT" : 					// prompt for string
                Return_Str = DefStr;
                Rm( "QueryBox /T=Template Expansion/W=30/ML=254/P=" + param2 );
								if (return_int) {
									g_tmp_last_prompt = return_str;
								}
								else {
									g_Tmp_Abort = True;
									Truncate_Spaces = SavTruncateSpaces;
									return ( );
								}                       // No break!!!

							case "LASTPROMPT" : 			// insert last prompt
								call DoPutText;
								Text( g_Tmp_Last_Prompt );
								continue;

							case "GETBLOCK" :         // Cut marked stream block to buffer 2
								if ( ( Block_Stat == _StrBlock ) && CursorInBlock( True ) ) {
									g_TmpBlkSaved = True;
									Block_End;
									Rm( "TopBlock" );
                  Rm( "Cut /B=52/M=1" );
								}
								else {
									g_TmpBlkSaved = False;
								}
								break;

							case "PUTBLOCK" :         // Paste last cut block from buffer 2
								call DoPutText;
								if ( g_TmpBlkSaved ) {
                  Rm( "Paste /B=52" + Param2 + "/A=1" );
								}
								continue;

							default:
								// Insert character
								if ( Copy( Param, 1, 2 ) == "0X" ) {
									Param2 = "0X";
									if ( Str_Char( Param, 3 ) == "0" ) {
										Param2 += "0";
									}
									T_Int = Parse_Hex_Int( Param2, Param );
									if ( ( T_Int >= 0x00 ) && ( T_Int < 0x100 ) ) {
										Tmp_Str = Str_Ins( Char( T_Int ), Tmp_Str, Jx );
										++Jx;
									}
								}
								else if ( Val( T_Int, Param ) == 0 ) {
									if ( ( T_Int >= 0x00 ) && ( T_Int < 0x100 ) ) {
										Tmp_Str = Str_Ins( Char( T_Int ), Tmp_Str, Jx );
										++Jx;
									}
								}
						}
						Tmp_Str = Str_Del( Tmp_Str, Jx, Jy + 1 );
					}
					break;

				case "^" : // special template metacommands
				case "!" : // run macro
					// this is a very special case requiring that we insert what we've
					// decoded so far into the file
					Param = "";
					Tmp_Str = Str_Del(tmp_str, Jx, 2);
					Jy = XPos( ">", Tmp_Str, Jx );
					if ( Jy > 0 ) {
						Jy -= Jx;
            Param = Copy( Tmp_Str, Jx, Jy );
						call DoPutText;
					}
					if ( Svl( Param ) ) {
						switch ( T_Char ) {
							case "^" :
								TmpExpand( Set, Param ); // this will create a recursion
								break;

							case "!" :
                Rm( Param );
								if ( g_Tmp_Abort ) {
									Truncate_Spaces = SavTruncateSpaces;
									return ( );
								}
								break;
						}
					}
					break;
			}
		}
		else {
			Jz = Jx + 1;
		}
	}
	Truncate_Spaces = SavTruncateSpaces;
	return ( );


DoPutText:
	if ( Get_Line( ) == "" ) {
		Goto_Col( g_TmpCrCol );
	}
  TmpPutText( Copy( Tmp_Str, 1, Jx - 1 ) );
	Tmp_Str = Copy( Tmp_Str, Jx + Jy + 1, Max_Line_Length );
	Jz = 1;
	ret;

}  // _TmpDecode

void TmpExpand(
      str Set  = Parse_Str( "/S=", MParm_Str ),
			str Name = Parse_Str( "/N=", MParm_Str )
)
/*
	This performs the actual template expansion for the passed set and
	template name
*/
{
	if ( g_Tmp_Abort ) {
		return ( );
	}
	if ( g_Tmp_Recurs_Level > 10 ) {
		Rm( "MessageBox /B=2/T=Template Expansion Error" +
				"/M=Template expansion recursion stack fault." +
				"  Check your templates for possible circular reference." );
		g_Tmp_Abort = True;
	}
	Name = Caps( Name );

	str TStr[ Max_Line_Length ];

	if ( g_Tmp_Recurs_Level < 1 ) {
		Set_Global_Int( tmp_Cursor_Save, 0 );
		g_Tmp_Recurs_Level = 0;
		g_Cursor_Col = 0;
		g_Cursor_Line = 0;
		g_Cr_Flag = 0;
		g_TmpBlkSaved = 0;
		g_TmpCrCol = g_Original_Col;
		g_TmpIndentCnt = 0;
	}
	++g_Tmp_Recurs_Level;

	int OrgWin = Window_Id;
	int TRefresh = Refresh;
	int Index = 0;
	int Amount;
	int DataWin;

	int TInsert_Mode = Insert_Mode;
	int Col;
	int Result;

	Refresh = False;
	Result = DbGetPage( _TmpDataFile( Set ), Name + tmp_Data_Ext, Index, Amount );
	DataWin = Cur_Window;
	Switch_Win_Id( OrgWin );
	Refresh = TRefresh;
	if ( Result == _NoError ) {
		Push_Undo;
		if ( Amount ) {
			if ( g_TmpRmChars ) {
				// erase original text before expanding template
				_TmpRmChars( Set, g_Template, Get_Line_From_Win( Index - 1, DataWin ) );
				g_TmpRmChars = False;
			}
			Insert_Mode = True;
			while ( Amount-- ) {
				TStr = Get_Line_From_Win( Index++, DataWin );
				_TmpDecode( Set, TStr, Col );
				if ( g_Tmp_Abort ) {
					Pop_Undo;
					return ( );
				}
				if ( Get_Line( ) == "" ) {
					Goto_Col( g_TmpCrCol );
				}
        TmpPutText( TStr );
				if ( Amount ) {
					if ( Get_Line( ) != "" ) {
						Eol;
					}
					if ( g_Cr_Flag ) {
						Rm( "Cr /NM=1" );
						g_TmpCrCol = C_Col;
					}
					else {
						Cr;
						g_TmpCrCol = g_Original_Col;
					}
					Goto_Col( g_TmpCrCol );
				}
			}
		}
		if ( g_Tmp_Recurs_Level == 1 ) {
			if ( g_Cursor_Line ) {
				Goto_Line( g_Cursor_Line );
			}
			if ( g_Cursor_Col ) {
				Goto_Col( g_Cursor_Col );
			}
		}
		Insert_Mode = TInsert_Mode;
		Pop_Undo;
	}
	else if ( g_Tmp_Global && ( Set != "GLOBAL" ) ) {
		TmpExpand( "GLOBAL", Name );
	}
	--g_Tmp_Recurs_Level;
	return ( );

}  // TmpExpand

str _TmpEvaluate( str &Set, str Template, int ExpandFlags, str AddonTemps ) {
/******************************************************************************
															 Multi-Edit Macro
															 25-Jul-95  17:07

	Function: Scan the template data index global for the passed template and
						return the name of the template when a match is found.  When space
						expand is enabled, the pattern will only match a template when the
						position of pattern meets the specification of the FirstWord and Eol
						flags for a template.

	Entry   : str Set         - The name of the template set
						str Template		- The pattern to be expanded
						int ExpandFlags	- Flags specifying the match conditions.
							_tmp_xAtEol			- Set when pattern was at end of line
							_tmp_xFirstWord	- Set when pattern was first word on line
							_tmp_xSpace			- Set when space expand enabled
						str AddonTemps		- List of additional templates to search

	Exit    : str							- The name of the template or "" when no matching
															template found.

	Notes		: The table below shows all of the states of the FirstWord and
						Eol 3state checkboxes and how they affect the expansion.

						0 - Uncheck, 1 - Checked, 2 - Grayed

		FirstWord		Eol 	Description
		~~~~~~~~~		~~~		~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				0				 0		Will expand when not firstword and not at end of line.
				0				 1		Will expand when not firstword and at end of line.
				0				 2		Will expand when not firstword.
				1				 0		Will expand when firstword and not at end of line.
				1				 1		Will expand only on a blank line.
				1				 2		Will expand when firstword.
				2				 0		Will expand when not at end of line.
				2				 1		Will expand when at end of line.
				2				 2		Will always expand.

							Copyright (C) 1995-96 by American Cybernectic, Inc.
********************************************************************( ldh )***/

	str T_Name = "";

	g_Template = Template;
	if ( Svl( Template ) != 0 ) {

		str T_Data;
		str Tmp_Str;
    str GlobStr                      = "!" + Set + "_Tmp_Data";
    str Data_Str[ Max_Line_Length ]  = Global_Str( GlobStr );
		str Data_Str2[ Max_Line_Length ] = Data_Str;
    str Keyword;

		int Jx;
    int Jy;
		int TempLength;
		int SpaceEn;
		int ExCmnt;
		int FirstWordEn;
		int EolEn;
    int DoSpaceExpand  = ( ExpandFlags & _tmp_xSpace ) != 0;
    int TmpAtEol       = ( ExpandFlags & _tmp_xAtEol ) != 0;
		int TmpAtFirstWord = ( ExpandFlags & _tmp_xFirstWord ) != 0;
		int Special;
    int GlobCnt        = Global_Int( GlobStr );
    int Cnt            = 0;

		g_Case_Flag = Parse_Int( "\x7F" + _gf_tmp_Case + "=", Data_Str );
		g_Case_Sense = Parse_Int( "\x7F" + _gf_tmp_CaseSense + "=", Data_Str );

    while ( Cnt <= GlobCnt ) {
      if ( !g_Case_Sense ) {
        Template = Caps( Template );
        Data_Str = Caps( Data_Str );
      }
      Jx = 1;
      while ( Jx = XPos( "\x7F" + _gf_tmp_Template + "=" + Template, Data_Str, Jx ) ) {
        Jy = XPos( "\xFE", Data_Str, Jx );
        if ( Jy == 0 ) {
          Jy = 255;
        }
        else {
          Jy = Jy - Jx - 1;
        }
        Tmp_Str = Parse_Str( "\x7F" +  _gf_tmp_Name + "=",
            Copy( Data_Str2, Jx, 255 ) );
        T_Data = Copy( Data_Str, Jx, Jy );
        ExCmnt = Parse_Int( "\x7F" + _gf_tmp_ExCmnt + "=", T_Data );
        SpaceEn = Parse_Int( "\x7F" + _gf_tmp_Space + "=", T_Data );
        TempLength = Parse_Int( "\x7F" + _gf_tmp_MinMatch + "=", T_Data );
        Special = Parse_Int( "\x7F" + _gf_tmp_Special + "=", T_Data );
        if ( !TempLength ) {
          Keyword = Parse_Str( "\x7F" + _gf_tmp_Template + "=", T_Data );
          TempLength = Svl( Keyword );
        }
        Jx += Jy;
        if ( !ExCmnt) {
          if ( GetStatusAtCursor( ) & 0x0F ) {
            continue;
          }
        }
        if ( !DoSpaceExpand || ( DoSpaceExpand == SpaceEn ) ) {
          if ( Svl( Template ) >= TempLength ) {
            if ( !DoSpaceExpand ) {
              T_Name = Tmp_Str;
              break;
            }
            else {
              FirstWordEn = Parse_Int( "\x7F" + _gf_tmp_FirstWord + "=", T_Data );
              EolEn = Parse_Int( "\x7F" + _gf_tmp_Eol + "=", T_Data );
              if ( ( FirstWordEn == 2 ) || ( FirstWordEn == TmpAtFirstWord ) ) {
                if ( ( EolEn == 2 ) || ( EolEn == TmpAtEol ) ) {
                  T_Name = Tmp_Str;
                  break;
                }
              }
            }
          }
          else if ( Length( g_TmpFirstName ) == 0 ) {
            g_TmpFirstName = Tmp_Str;
            g_TmpFirstSet = Set;
          }
        }
      }
      ++Cnt;
      Data_Str = Global_Str( GlobStr + Str( Cnt ) );
      Data_Str2 = Data_Str;
    }
		if ( Svl( T_Name ) == 0 ) {
			if ( Svl( AddonTemps ) != 0 ) {
				Jx = XPos( ";", AddonTemps, 1 );
				if ( Jx == 0 ) {
					Jx = Svl( AddonTemps ) + 1;
				}
				Set = Copy( AddonTemps, 1, Jx - 1 );
				AddonTemps = Str_Del( AddonTemps, 1, Jx );
				T_Name = _TmpEvaluate( Set, g_Template, ExpandFlags, AddonTemps );
			}
		}
		if ( Svl( T_Name ) == 0 ) {
			if ( ( g_Tmp_Global ) && ( Set != "GLOBAL" ) ) {
				Set = "GLOBAL";
				T_Name = _TmpEvaluate( Set, g_Template, ExpandFlags, "" );
			}
		}
		else {
			// this is a very special case to allow a space to be inserted if there is
			// no need to expand a template
			if ( Special ) {
				if ( !g_Case_Sense ) {
					Tmp_Str = Caps( Tmp_Str );
				}
				if ( Template == Tmp_Str ) {
					T_Name = "";
				}
			}
		}
	}
	return ( T_Name );

}  // _TmpEvaluate

int _TmpSetList( str &Set_Choice_Str[ Max_Line_Length ], &Sel_Str, int No_Global ) {
/*
	builds a list of templates sets based on template set data files found on disk
*/

	int Set_Choice_Int = 0,
			Data_Found = _TmpLdDataFile( "", 0 ),
			Count = 0,
			Find_Data = !Data_Found,
			Dos_Error;

	struct WIN32_FIND_DATA new_fd;
	struct DOS_FIND_DATA old_fd;
	int find_handle;
	int tw = window_id;
	int tr = refresh;
	int tx;

	refresh = false;


	if ( Data_Found && ( Sel_Str == "" ) ) {
		Sel_Str = Truncate_Path( Truncate_Extension( File_Name ) );
	}
	if ( Svl( Sel_Str ) == 0 ) {
		Sel_Str = "GLOBAL";
	}
	create_window;

	// build the choices of templates
	find_handle = FindFirstFile(User_Path + "*" + Tmp_File_Ext, &new_fd, &old_fd );
	if(find_handle)
	{
		do {
			if ((truncate_extension(new_fd.cFileName) != "GLOBAL") || (!no_global)) {
				put_line(truncate_extension(new_fd.cFileName));
				down;
			}
			dos_error = FindNextFile( find_handle, &new_fd, &old_fd);
		}
		while( dos_error );
		FindClose( find_handle );
	}

	find_handle = FindFirstFile( _DefaultDir + "*" + Tmp_File_Ext, &new_fd, &old_fd );
	if(find_handle)
	{
		do {
			if ((truncate_extension(new_fd.cFileName) != "GLOBAL") || (!no_global)) {
				mark_pos;
				tof;
				tx = Find_Text( "^" + make_literal_x(truncate_extension(new_fd.cFileName)) + "$", 0, _RegExp );
				goto_mark;
				if(!tx)
				{
					put_line(truncate_extension(new_fd.cFileName));
					down;
				}
			}
			dos_error = FindNextFile( find_handle, &new_fd, &old_fd);
		}
		while( dos_error );
		FindClose( find_handle );
	}

	qsort_lines( 1, c_line -1, TRUE, 0, 0, TRUE );

	tof;
	while(!at_eof)
	{
		++count;
		set_choice_str += get_line + "()";
		if ( caps(Sel_Str) == caps(get_line) ) {
			set_choice_int = count;
		}
		down;
	}

	delete_window;
	switch_win_id(tw);
	refresh = tr;

	if (!count) {
		RM("MESSAGEBOX /B=2/T=Template Editing Error/M=No template data files found.");
		Return(-1);
	}
	return ( Set_Choice_Int );

}  // _TmpSetList

void Tmp_Menu( ) {
/*
	a dialog that pops up over the main template dialog allowing adding
	and/or deleting template sets.
*/

	int Dlg = Parse_Int( "/DATAHANDLE=", MParm_Str );
	int FromTmpEdit = Parse_Int( "/TE=", MParm_Str );
	int LstDlg;
	int Active_Window = Window_Id;
	int TInsert_Mode = Insert_Mode;
	int TRefresh = Refresh;
	int Width = 32;
	int BtnCol;
	int LstCol;
	int DosError;
	int SelBtnFlags;
	int CloseBtnFlags;
  int SetNo;

	struct WIN32_FIND_DATA new_fd;
	struct DOS_FIND_DATA old_fd;
	int find_handle;

  str OrgSet;

	if ( Global_Int( "&BtnOnRight" ) ) {
		LstCol = 1;
		BtnCol = LstCol + Width + 1;
	}
	else {
		BtnCol = 1;
		LstCol = BtnCol + dlg_StanBtnWidth + 1;
	}
	Refresh = False;
	Switch_Window( Window_Count );
	Insert_Mode = True;
	Create_Window;
	Window_Attr |= 0x81;

	DlgCreate( LstDlg );
	if ( FromTmpEdit && Dlg ) {
		SelBtnFlags = dlgf_Disable;
		CloseBtnFlags = dlgf_DefButton;
		DlgChoice2Win( Dlg, Set_Ctrl );
    OrgSet = Get_Line( );
    SetNo = DlgGetInt( Dlg, Set_Ctrl );
	}
	else {
		SelBtnFlags = dlgf_DefButton;
		CloseBtnFlags = 0;
		find_handle = FindFirstFile(User_Path + "*" + Tmp_File_Ext, &new_fd, &old_fd );
		if(find_handle)
		{
			do
			{
				Put_Line( Truncate_Extension( new_fd.cFileName ) );
				Down;
			}
			while( FindNextFile( find_handle, &new_fd, &old_fd ));
			FindClose( find_handle );  // This is IMPORTANT!!!
		}
	}
	File_Changed = False;

	DlgAddCtrl( LstDlg, dlg_ListBox, "",
			LstCol, 1,
			Width, 5,
			List_Ctrl, dlgf_LBIncSearch, "/WIN=" + Str( Cur_Window ) );

	DlgAddCtrl( LstDlg, dlg_PushButton, "&Insert",
			BtnCol, dlg_Units | 29,
			dlg_StanBtnWidth,
			0, Insert_Ctrl, 0, "/M=_TmpSetInsert" );

	DlgAddCtrl( LstDlg, dlg_PushButton, "&Delete",
			dlg_PosOffset + 0, dlg_PosOffset | Dlg_Units | 20,
			dlg_StanBtnWidth, 0,
			Delete_Ctrl, 0, "/M=_TmpSetDelete" );

	DlgAddCtrl( LstDlg, DLG_PushButton, "&Select",
			LstCol, DLG_Units | 68,
			dlg_StanBtnWidth, 0,
			OK_Ctrl, SelBtnFlags, "/R=1");

	DlgAddCtrl( LstDlg, dlg_PushButton, "Close",
			dlg_PosOffset + dlg_StanBtnWidth + 1, dlg_PosOffset + 0,
			dlg_StanBtnWidth, 0,
			Cancel_Ctrl, CloseBtnFlags, "/R=0");

	DlgAddCtrl( LstDlg, dlg_PushButton, "&Help",
			LstCol + Width - dlg_StanBtnWidth, dlg_PosOffset + 0,
			dlg_StanBtnWidth, 0,
			Help_Ctrl, 0, "/R=2");

	Return_Int = DlgExecute( LstDlg, List_Ctrl, "Template Sets", EDITTMP_HELPLINK, "", 0 );
	DlgKill( LstDlg );

	if ( FromTmpEdit && Dlg ) {
		if ( File_Changed ) {
      Goto_Line( SetNo );
      if ( OrgSet != Get_Line( ) ) {
        OrgSet = Get_Line( );
      }
      else {
        OrgSet = "";
      }
			DlgWin2Choice( Dlg, Set_Ctrl );
			DlgUpdateCtrl( Dlg, Set_Ctrl, 0 );
		}
	}
	else if ( Return_Int ) {
		Return_Str = Get_Line( );
	}
	Delete_Window;
	Switch_Win_Id( Active_Window );
  if ( Svl( OrgSet ) != 0 ) {
    _TmpSetChange( Dlg, OrgSet, "" );
  }
	Insert_Mode = TInsert_Mode;
	Refresh = TRefresh;

}  // Tmp_Menu

void _TmpShowHint( int Dlg 	 = Parse_Int( "/DATAHANDLE=", MParm_Str ) )
/******************************************************************************
															 Multi-Edit Macro
															 19-Jan-96  02:53

	Function: Show a template description on the status line.  Only to called by
						the Tmp_List macro.

	Entry   : int Dlg			- The dialog data handle.

							 Copyright (C) 1996 by American Cybernetics, Inc.
********************************************************************( ldh )***/
{
	if ( Dlg ) {

		str TStr = Get_Line( );

		Make_Message( Parse_Str( "\x7F" + "S=", TStr ) + ": " +
				Parse_Str( "\x7F" + "C=", TStr ) );
	}
}  // _TmpShowHint

void _TmpShowHelp(
			int Dlg 	 = Parse_Int( "/DATAHANDLE=", MParm_Str ),
			int CtrlId = Parse_Int( "/ID=", MParm_Str )
)
/******************************************************************************
															 Multi-Edit Macro
															 19-Jan-96  14:35

	Function: Bring up the help for the selected template or the context help if
						no help defined for the selected template.

	Entry   : int Dlg			- The dialog data handle.
						int CtrlId	- The control id with the Help string

							 Copyright (C) 1996 by American Cybernetics, Inc.
********************************************************************( ldh )***/
{
	str HelpStr;

	if ( Dlg ) {
		if ( CtrlId ) {
			DlgSetFields( Dlg );
			HelpStr = DlgGetStr( Dlg, CtrlId );
		}
		else {
			HelpStr = Parse_Str( "\x7F" + "H=", Get_Line( ) );
		}
	}
	if ( Svl( HelpStr ) != 0 ) {
		HelpStr = TranslateCmdline( HelpStr, File_Name );
		MewHelp( HelpStr );
	}
	else {
		Make_Message( "No help available for this template" );
	}
}  // _TmpShowHelp

void Tmp_List(
			str Set 	 = Parse_Str( "/SET=", MParm_Str ),
			str TmpStr = Parse_Str( "/TMPSTR=", MParm_Str )
)
/******************************************************************************
															 Multi-Edit Macro
															 28-Jan-96  15:57

	Function: This is the stand-alone list of templates
	Entry   : str Set     - The name of the template set to list        (/SET=)
						str TmpStr	- The name of the template to start on        (/TMPSTR=)

							 Copyright (C) 1996 by American Cybernetics, Inc.
********************************************************************( ldh )***/
{
	int ActiveWindow = Window_Id;
	int TRefresh = Refresh;
	int Dlg;
	int List_Window;
	int Set_Choice_Int;
	int Result;

	str Set_Choice_Str[ Max_Line_Length ];
	str Sel_Str = Set;

	Set_Choice_Int = _TmpSetList( Set_Choice_Str, Sel_Str, !g_Tmp_Global);
	if ( Set_Choice_Int == -1 )  {
		return ( );
	}

	Refresh = False;
	Switch_Window( Window_Count );
	Create_Window;
	List_Window = Window_Id;
	Window_Attr |= 0x81;

	DlgCreate( Dlg );
	DlgAddCtrl( Dlg, dlg_BitmapStatic, "BT_GN_115",
			1, 1,
			0, 0,
			bitmap_ctrl, 0, "" );

	DlgAddCtrl( Dlg, dlg_Static, "Template &set:",
			First_Column, 1,
			0, 0,
			Case_Title_Ctrl, 0, "" );

	// the /CHANGEMAC= parameter of the following control is for
	// updating the list of templates any time a new set is selected
	DlgAddCtrl( Dlg, dlg_Choice, Set_Choice_Str,
			dlg_PosOffset + 0, Title_Y_Offset,
			20, 1,
			Set_Ctrl, 0, "/CHANGEMAC=_TmpSetChange2" );
	DlgSetInt( Dlg, Set_Ctrl, Set_Choice_Int );

	DlgAddCtrl( Dlg, dlg_Static, "&Template:",
			1, dlg_PosOffset | 1,
			0, 0,
			Case_Title_Ctrl, 0, "" );
	DlgAddCtrl( Dlg, dlg_ListBox, "\x7F" + "T=/W=20/IS=1",
			1, Title_Y_Offset,
			35, 5,
			List_Ctrl, dlgf_LBIncSearch, "/WIN=" + Str( Cur_Window ) +
			"/CHANGEMAC=_TmpShowHint" );

	DlgAddCtrl( Dlg, dlg_PushButton, "&Edit",
      dlg_PosOffset + 36, dlg_PosOffset + 0,
			dlg_StanBtnWidth, 0,
			101, 0, "/R=10" );

//  DlgAddCtrl( Dlg, dlg_PushButton, "T&mp Hlp",
//      dlg_PosOffset + 0, dlg_PosOffset + dlg_Units_3HLines,
//      dlg_StanBtnWidth, 0,
//      100, 0, "/M=_TmpShowHelp" );

	DlgAddCtrl( Dlg, dlg_PushButton, "&Help",
			dlg_PosOffset, dlg_Units + 98,
			dlg_StanBtnWidth, 0,
			Help_Ctrl, 0, "/R=2" );

	DlgAddCtrl( Dlg, dlg_PushButton, "E&xpand",
			1, dlg_PosOffset,
			dlg_StanBtnWidth, 0,
			Expand_Ctrl, dlgf_DefButton, "/R=1" );

	DlgAddCtrl( Dlg, dlg_PushButton, "Close",
			dlg_StanBtnWidth + 2, dlg_PosOffset,
			dlg_StanBtnWidth, 0,
			Cancel_Ctrl, 0, "/R=0" );

	// The /PRELOOPMAC= macro will initialized the list of templates
	Return_Int = Result = DlgExecute( Dlg, List_Ctrl, "Expand Template",
			BLDTMP_HELPLINK, "/PRELOOPMAC=_TmpSetChange2 //SELSTR=" +
			Double_Slashes( Sel_Str ) + "//TMPSTR=" + TmpStr, 0 );

	Switch_Win_Id( List_Window );
	Sel_Str = Shorten_Str( Parse_Str( "\x7F" + "T=", Get_Line( ) ) );
	Set_Choice_Str = Parse_Str( "\x7F" + "S=", Get_Line( ) );
	Delete_Window;

	Switch_Win_Id( ActiveWindow );

	switch ( Result ) {
		case 1 :                            // Expand
      if ( Global_Str( "!" + Set_Choice_Str + "_Tmp_Data" ) == "" ) {
				Tmp_Init_All( Set_Choice_Str, False );
      }
			Set_Global_Str( "!" + Set_Choice_Str + "_Last_Tmp", Sel_Str );
			TmpExpand( Set_Choice_Str, Sel_Str );
			break;

		case 10 :                           // Edit
			Tmp_Edit( Set_Choice_Str, Sel_Str, False );
			break;
	}
	DlgKill( Dlg );
	Refresh = TRefresh;

}  // Tmp_List

void _TmpSetChange2(
			int Dlg 		= Parse_Int( "/DATAHANDLE=", MParm_Str ),
			str Sel_Str = Parse_Str( "/SELSTR=", MParm_Str ),
			str TmpStr	= Parse_Str( "/TMPSTR=", MParm_Str )
)
/*
	refreshes the controls in the TMP_LIST dialog box when a new set
	is selected.  To be run ONLY via the /CHANGEMAC= parameter of
	the template set control of TMP_LIST or the /PRELOOPMAC= parameter
	passed to the DlgExecute() function.
	When run via the /CHANGEMAC= parameter, the parameters are passed
	according to the current dialog box data handle (/DATAHANDLE=)
	and the newly selected item in the pull-down list (/SELSTR=)
*/
{
	if ( Dlg ) {

		int ActiveWindow  = Window_Id;
		int TRefresh 			= Refresh;
		int ListWindowNum = Cur_Window;
		int Count;
		int Jx;

		str TStr;
    str Comment;
    str HelpCtx;

		Refresh = False;
		Erase_Window;
		Window_Attr |= 0x81;

		if ( _TmpLdDataFile( Sel_Str, 1 ) ) {
			Count = 0;
			// put stuff in the templates list
			Tof;
			Eol;
			while ( Find_Text( "^\f", 0, _RegExp ) ) {
				Eol;
				TStr = Get_Line( );
        Comment = Parse_Str( "\x7F" + _db_tmp_Comment + "=", TStr );
        HelpCtx = Parse_Str( "\x7F" + _db_tmp_HelpCtx + "=", TStr );
        if ( !Parse_Int( "\x7F" + _db_tmp_NoListShow + "=", TStr ) ) {
					if ( Jx = XPos( ".", TStr, 1 ) ) {
            TStr = "\x7F" + "T=" + Copy( TStr, 2, Jx - 2 ) +
                "  \x7F" + "C=" + Comment +
								"\x7F" + "S=" + Sel_Str +
                "\x7F" + "H=" + HelpCtx;
						Put_Line_To_Win( TStr, ++Count, ListWindowNum, 0 );
					}
				}
			}
			Switch_Win_Id( ActiveWindow );
			QSort_Lines( 1, Count, TRUE, 4, 32, TRUE );
			if ( Svl( TmpStr ) ) {
				Find_Text( "^\x7F" + "T=" + Make_Literal_X( TmpStr ) + "  \x7F" + "C=",
						0, _RegExp );
			}
			_TmpShowHint( Dlg );
			DlgUpdateCtrl( Dlg, List_Ctrl, 0 );
			DlgSetFocus( Dlg, List_Ctrl );
		}
		Switch_Win_Id( ActiveWindow );
		Refresh = TRefresh;
	}
	Return_Int = 0;

}  // _TmpSetChange2

void _TmpAddToMenu( int Dlg, int hMenu, str Menu_Str ) {
/*
	adds items to the metacommand popup menu
	to be invoked only from _TmpMetaCmds
*/
  int Tab_Pos = XPos( "\t", Menu_Str, 1 );

  if ( !Tab_Pos ) {
    Tab_Pos = Svl( Menu_Str ) + 1;
	}

  int WCmd = GetAvailableWCmd( 0, 0 );

  if ( WCmd ) {
    WCmd_Add( 0, WCmd, 0, 0, 0, "_TmpInsertMeta /DATAHANDLE=" + Str( Dlg ) +
        "/META=" + Copy( Menu_Str, 1, Tab_Pos - 1 ), "" );
    AppendMenu( hMenu, MF_STRING, WCmd, Menu_Str );
	}
}  // _TmpAddToMenu

void _TmpMetaInit( int Dlg = Parse_Int( "/DATAHANDLE=", MParm_Str ) )
{
  if ( Dlg ) {

    g_hMetaMenu = CreatePopupMenu( );

		_TmpAddToMenu( Dlg, g_hMetaMenu, "<-?>\tField marker" );
		_TmpAddToMenu( dlg, g_hMetaMenu, "<-SPACE>\tEnd of line space");
		_TmpAddToMenu( dlg, g_hMetaMenu, "<-TAB>\tTab right");
		_TmpAddToMenu( dlg, g_hMetaMenu, "<-UP>\tMove cursor up");
		_TmpAddToMenu( dlg, g_hMetaMenu, "<-CUR>\tCursor ends up here");
		_TmpAddToMenu( dlg, g_hMetaMenu, "<-SMARTIND+>\tEnable smart indent");
		_TmpAddToMenu( dlg, g_hMetaMenu, "<-SMARTIND->\tDisable smart indent");
		_TmpAddToMenu( dlg, g_hMetaMenu, "<-SCUR>\tSave cursor pos");
		_TmpAddToMenu( dlg, g_hMetaMenu, "<-RCUR>\tRestore cursor pos");
		_TmpAddToMenu( Dlg, g_hMetaMenu, "<-XCUR>\tExchange cursor pos" );
		_TmpAddToMenu( Dlg, g_hMetaMenu, "<-SIND>\tSet indent level" );
		_TmpAddToMenu( Dlg, g_hMetaMenu, "<-SCIND>\tSet cursor pos as indent level " );
		_TmpAddToMenu( Dlg, g_hMetaMenu, "<-RIND>\tRestore indent level" );
		_TmpAddToMenu( dlg, g_hMetaMenu, "<-PROMPT>\tPrompt for string");
		_TmpAddToMenu( dlg, g_hMetaMenu, "<-LASTPROMPT>\tValue of last <-PROMPT>");
		_TmpAddToMenu( Dlg, g_hMetaMenu, "<-GETBLOCK>\tGet a stream marked block");
		_TmpAddToMenu( Dlg, g_hMetaMenu, "<-PUTBLOCK>\tPut the last <-GETBLOCK>");
		_TmpAddToMenu( Dlg, g_hMetaMenu, "<-nnn>\tCharacter in decimal 0-255" );
		_TmpAddToMenu( Dlg, g_hMetaMenu, "<-0xhh>\tCharacter in hex 0x00-0xFF" );
		_TmpAddToMenu( dlg, g_hMetaMenu, "<^template>\tExpand another template");
		_TmpAddToMenu( dlg, g_hMetaMenu, "<!macro>\tRun a macro");
		_TmpAddToMenu( dlg, g_hMetaMenu, "<~global_str>\tInsert global string");


		AppendMenu( g_hMetaMenu, MF_SEPARATOR, 0, ""); // separator

		int	sub_handle1	= CreatePopupMenu();

		AppendMenu(g_hMetaMenu, MF_POPUP, sub_handle1, "&More");

		_TmpAddToMenu( dlg, sub_handle1, "<%environment_var>\tEnvironment variable");
		_TmpAddToMenu( dlg, sub_handle1, "<FILE>\tCurrent file name");
		_TmpAddToMenu( dlg, sub_handle1, "<EXT>\tCurrent file extension");
		_TmpAddToMenu( dlg, sub_handle1, "<NAME>\tFile name (no path)");
		_TmpAddToMenu( dlg, sub_handle1, "<PATH>\tCurrent file path");
		_TmpAddToMenu( dlg, sub_handle1, "<ME_PATH>\tMulti-Edit path");
		_TmpAddToMenu( dlg, sub_handle1, "<COMSPEC>\tComspec (e.g. COMMAND.COM)");
		_TmpAddToMenu( dlg, sub_handle1, "<USER_PATH>\tPath to config files");
		_TmpAddToMenu( dlg, sub_handle1, "<MAC_PATH>\tPath to macros");
		_TmpAddToMenu( dlg, sub_handle1, "<USER_ID>\tUser id (network version)");
		_TmpAddToMenu( dlg, sub_handle1, "<CTIME>\tCurrent time");
		_TmpAddToMenu( dlg, sub_handle1, "<CDATE>\tCurrent date");
		_TmpAddToMenu( dlg, sub_handle1, "<FTIME>\tCurrent file time");
		_TmpAddToMenu( dlg, sub_handle1, "<FDATE>\tCurrent file date");
	}
}

void _DelMenu( int menu_handle )
{

	int jx;
	int num_items;
	int id;

	num_items = GetMenuItemCount (menu_handle);
	for ( jx = 0; jx < num_items; jx++ ) {
		id = GetMenuItemID (menu_handle, jx);
		if ( id != 0 ) {
			if ( id == 0xffff) {
				if (GetSubMenu (menu_handle, jx))
					_DelMenu (GetSubMenu (menu_handle, jx));
			}
			else {
				ReleaseWCmd (id);
			}
		}
	}
	DestroyMenu( menu_handle );

}  // _DelMenu

void _TmpMetaExit( int Dlg = Parse_Int( "/DATAHANDLE=", MParm_Str ) )
{
	if ( g_hMetaMenu ) {
		_DelMenu( g_hMetaMenu );
		g_hMetaMenu = 0;
	}
}  // _TmpMetaExit

void _TmpInit( int Dlg = Parse_Int( "/DLGHANDLE=", MParm_Str ) )
{
	int nfont, bfont, ifont, ibfont;

  _TmpMetaInit( Parse_Int( "/DATAHANDLE=", MParm_Str ) );
	if ( Global_Int( "Oem_Mode" ) ) {
		Get_Window_Font_Handle( -1, nfont, bfont, ifont, ibfont );
	}
	else {
		Get_Window_Font_Handle( 0, nfont, bfont, ifont, ibfont );
	}
  SendDlgItemMessage( Dlg, Edit_Ctrl, WM_SETFONT, nfont, 0 );

}  // _TmpInit

void Tmp_Edit(
			str Set 	 			 = Parse_Str( "/SET=", MParm_Str ),
			str TmpStr 			 = Parse_Str( "/TMPSTR=", MParm_Str ),
			int Not_Modeless = Parse_Int( "/NM=", MParm_Str )
)
/******************************************************************************
															 Multi-Edit Macro
															 28-Jan-96  15:54

	Function: This is the main tempate editing/configuration macro.
	Entry   : str Set           - The name of the template set to edit	(/SET=)
						str TmpSet        - The name of the template to edit      (/TMPSTR=)
						int Not_Modeless	- True for a modal dialog               (/NM=)

							 Copyright (C) 1996 by American Cybernetics, Inc.
********************************************************************( ldh )***/
{
	if ( g_hTmpEditDlg != 0 ) {
		DlgSetActiveWindow( g_hTmpEditDlg );
		return ( );
	}

	int ActiveWindow = Window_Id;
	int TRefresh = Refresh;
	int Dlg;
	int List_Window_Num;
	int Edit_Window_Num;
	int Set_Choice_Int;
	int CtrlId = 100;
	int mode_flags = TMP_MODELESS;
	int X;
	int Y;

	str Data_File;
	str Set_Choice_Str[ Max_Line_Length ] = "";
	str Sel_Str = Set;
	str File_Str;
	str ExpandOptStr = "any where()at end of line()" +
					"when not at end of line()when first word()on a blank line()" +
					"when first word and not at end of line()when not first word()" +
					"when not first word and at end of line()in the middle of a line()";

	Refresh = False;
	Set_Choice_Int = _TmpSetList( Set_Choice_Str, Sel_Str, !g_Tmp_Global );
	if ( Set_Choice_Int == -1 )  {
		return ( );
	}
	g_Data_Window = Window_Id;
  g_TmpEditLine = 0;

	if ( Not_Modeless ) {
		Mode_Flags = 0;
	}
	// create window for list of templates
	switch_window(window_count);
	create_window;
	window_attr |= 0x81;
	file_name = "TMP_LIST.TMP";
	g_list_window = window_id;
	list_window_num = cur_window;

	// create window for template result
	switch_window(window_count);
	create_window;
	window_attr |= 0x81;
	file_name = "TMP_RSLT.TMP";
	g_edit_window = window_id;
	edit_window_num = cur_window;

	DlgCreate( Dlg );
	// Save dialog handle
	g_hTmpEditDlg = Dlg;

	// the /CHANGEMAC= macro here saves this configuration whenever it is changed
	DlgAddCtrl( Dlg, dlg_Checkbox, "Enable &global templates",
			3, 1,
			0, 0,
			Global_Ctrl, 0, "/CHANGEMAC=_TmpGlobChange" );
	DlgSetInt( Dlg, Global_Ctrl, g_Tmp_Global );

	DlgAddCtrl( Dlg, dlg_Groupbox, "Template &Set",
			1, 2,
			dlg_Units | 159, 14,
			CtrlId, 0, "" );

	DlgAddCtrl( Dlg, dlg_BitmapStatic, "BT_GN_115",
			2, 3,
			0, 0,
			++CtrlId, 0, "" );

	// the /CHANGEMAC= macro will reset the template list and all the controls on the template side of the box whenever the set is changed
	DlgAddCtrl( Dlg, dlg_Choice, Set_Choice_Str,
			First_Column, 3,
			20, 1,
			Set_Ctrl, 0, "/CHANGEMAC=_TmpSetChange" );
	DlgSetInt( Dlg, Set_Ctrl, Set_Choice_Int );

	DlgAddCtrl( Dlg, dlg_PushButton, "...",
			dlg_PosOffset | 21, dlg_PosOffset,
			4, 0,
			Set_Change_Ctrl, 0, "/M=Tmp_Menu /TE=1" );

	DlgAddCtrl( Dlg, dlg_Static, "&Case of result:",
			First_Column, dlg_Units | 40,
			0, 0,
			++CtrlId, 0, "" );
	// the /CHANGEMAC= macro will save this configuration option to the template data file whenever a change is made
	DlgAddCtrl( Dlg, dlg_Choice, "Verbatim()ALL CAPS()Proper()Same As Keyword()",
			dlg_PosOffset, Title_Y_Offset,
			25, 1,
			Case_Ctrl, 0, "/CHANGEMAC=_TmpCaseChange" );

	// the /CHANGEMAC= macro is the same as the one above
	DlgAddCtrl( Dlg, dlg_Checkbox, "C&ase sensitive keyword",
			First_Column, dlg_Units | 62,
			0, 0,
			Sense_Ctrl, 0, "/CHANGEMAC=_TmpCaseChange" );

	DlgAddCtrl( Dlg, dlg_Static, "&Templates:",
			First_Column, dlg_Units | 74,
			0, 0,
			++CtrlId, 0, "" );
	// the /CHANGEMAC= macro will reset all the controls on the template side of the box whenever the template is changed
	DlgAddCtrl( Dlg, dlg_ListBox, "",
			dlg_PosOffset, Title_Y_Offset,
			25, dlg_Units | 92,
			List_Ctrl, dlgf_LBIncSearch, "/INSWCMD=" + str(insert_ctrl) +
			"/DELWCMD=" + str(delete_ctrl) +
			"/CHANGEMAC=_TmpListChange/DISP#=3/WIN=" + Str( List_Window_Num ) );

	DlgGetXY( Dlg, List_Ctrl, X, Y );
	DlgAddCtrl( Dlg, dlg_PushButton, "&Insert",
			2, dlg_Units | Y,
			dlg_StanBtnWidth, 0,
			Insert_Ctrl, 0, "/M=_TmpInsert" );

	DlgAddCtrl( Dlg, dlg_PushButton, "&Delete",
			dlg_PosOffset + 0, dlg_PosOffset | dlg_Units_5QLines,
			dlg_StanBtnWidth, 0,
			Delete_Ctrl, 0, "/M=_TmpDelete" );

	DlgAddCtrl( Dlg, dlg_PushButton, "Cop&y",
			dlg_PosOffset + 0, dlg_PosOffset | dlg_Units_5QLines,
			dlg_StanBtnWidth, 0,
			id_ted_CopyBtn, 0, "/M=_TmpInsert //COPY=1" );

	DlgAddCtrl( Dlg, dlg_PushButton, "Move &Up",
			dlg_PosOffset + 0, dlg_PosOffset | dlg_Units_3HLines,
			dlg_StanBtnWidth, 0,
			id_ted_MoveUpBtn, 0, "/M=_TmpMoveUp" );

	DlgAddCtrl( Dlg, dlg_PushButton, "Mo&ve Dn",
			dlg_PosOffset + 0, dlg_PosOffset | dlg_Units_5QLines,
			dlg_StanBtnWidth, 0,
			id_ted_MoveDnBtn, 0, "/M=_TmpMoveDn" );

	// Use /R=0 to have dialog close after macro is run
	DlgAddCtrl( Dlg, dlg_PushButton, "&Expand",
			dlg_PosOffset + 0, dlg_PosOffset | dlg_Units_3HLines,
			dlg_StanBtnWidth, 0,
			Expand_Ctrl, 0, "/R=0/M=_TmpDoExpand" );

	DlgAddCtrl( Dlg, dlg_Groupbox, "Edit Template",
//      Second_Column - 1, 1,
//      60, 15,
      Second_Column - 1, 2,
      60, 14,
			++CtrlId, 0, "" );

	DlgAddCtrl( Dlg, dlg_Static, "Descriptio&n:",
			Second_Column, dlg_PosOffset + 1,
			0, 0,
			++CtrlId, 0, "" );

	// the /CHANGEMAC= macro sets a global integer indicating a change was made
	DlgAddCtrl( Dlg, dlg_Text, "",
			dlg_PosOffset, Title_Y_Offset,
			58, 0,
			Desc_Ctrl, 0, "/CHANGEMAC=_TmpEditChange" );

//  DlgAddCtrl( Dlg, dlg_Static, "Help &file:",
//      Second_Column, dlg_PosOffset | dlg_Units + ( dlg_Units_QLine * 5 ) - 1,
//      0, 0,
//      ++CtrlId, 0, "" );
//  DlgAddCtrl( Dlg, dlg_Text, "",
//      dlg_PosOffset | 10, dlg_PosOffset,
//      48, 0,
//      id_ted_HelpFile, 0, "/CHANGEMAC=_TmpEditChange" );

	DlgAddCtrl( Dlg, dlg_Static, "&Keyword:",
			Second_Column, dlg_PosOffset | dlg_Units + ( dlg_Units_QLine * 5 ) - 1,
			0, 0,
			++CtrlId, 0, "" );
	DlgAddCtrl( Dlg, dlg_Text, "",
			dlg_PosOffset | 10, dlg_PosOffset,
			22, 0,
			Keyw_Ctrl, 0, "/CHANGEMAC=_TmpEditChange" );

	DlgAddCtrl( Dlg, dlg_Static, "Min &length:",
			dlg_PosOffset | 25, dlg_PosOffset,
			0, 0,
			++CtrlId, 0, "" );
	DlgAddCtrl( Dlg, dlg_Integer, "",
			dlg_PosOffset | 12, dlg_PosOffset,
			4, 0,
      Min_Ctrl, 0, "/MIN=0/CHANGEMAC=_TmpEditChange" );
	DlgSetInt( Dlg, Min_Ctrl, 1 );

	DlgAddCtrl( Dlg, dlg_Checkbox, "S&pace",
			Second_Column, dlg_PosOffset | dlg_Units + ( dlg_Units_QLine * 5 ) - 1,
			0, 0,
			Space_Ctrl, 0, "/CHANGEMAC=_TmpEditChange" );

	DlgAddCtrl( Dlg, dlg_Static, "E&xpand",
			dlg_PosOffset + 10, dlg_PosOffset | dlg_Units + 2,
			0, 0,
			++CtrlId, 0, "" );

	DlgAddCtrl( Dlg, dlg_Choice, ExpandOptStr,
			dlg_PosOffset + 8, dlg_NegOffset | dlg_Units + 2,
			40, 0,
			id_ted_Eol, 0, "/CHANGEMAC=_TmpEditChange" );

	DlgAddCtrl( Dlg, dlg_Checkbox, "Expand in C&omments",
			Second_Column, dlg_PosOffset + 1,
			0, 0,
			id_ted_ExpandComment, 0, "/CHANGEMAC=_TmpEditChange" );

	DlgAddCtrl( Dlg, dlg_Checkbox, "Do not sho&w in list",
			dlg_PosOffset + 28, dlg_PosOffset + 0,
			0, 0,
			id_ted_NoShowInList, 0, "/CHANGEMAC=_TmpEditChange" );

	DlgAddCtrl( Dlg, dlg_Static, "&Result:",
			Second_Column, 9,
			0, 0,
			++CtrlId, 0, "" );

	DlgAddCtrl( Dlg, dlg_Text, "",
			dlg_PosOffset, Title_Y_Offset,
			58, 6,
			Edit_Ctrl, dlgf_es_HScrollBar | dlgf_GetTextFromWin | dlgf_es_MultiLine |
					dlgf_es_WantReturn | dlgf_es_AutoHScroll,
			"/CHANGEMAC=_TmpEditChange/ML=32000/WID=" + str( g_Edit_Window ) );

	DlgAddCtrl( Dlg, dlg_PushButton, "&Metacommands",
			dlg_PosOffset | 42, dlg_NegOffset | dlg_Units | 16,
			16, 0,
			Meta_Ctrl, 0, "/M=_TmpMetaCmds" );

	DlgAddCtrl( Dlg, dlg_PushButton, "Cancel edit",
			dlg_NegOffset | 14, dlg_PosOffset + 0,
			13, 0,
			id_ted_CancelBtn, 0, "/M=_TmpCancelEdit" );

//  DlgAddCtrl( Dlg, dlg_PushButton, "Tmp help",
//      dlg_NegOffset + 12, dlg_PosOffset + 0,
//      11, 0,
//      ++CtrlId, 0, "/M=_TmpShowHelp //ID=" + Str( id_ted_HelpFile ) );

	// Use /R=0 to have dialog close
	DlgAddCtrl( Dlg, dlg_PushButton, "Close",
			1, dlg_Units | 184,
			dlg_StanBtnWidth, 0,
			Cancel_Ctrl, dlgf_DefButton, "/R=0" );

	DlgAddCtrl( Dlg, dlg_PushButton, "&Help",
			91, dlg_PosOffset,
			dlg_StanBtnWidth, 0,
			Help_Ctrl, 0, "/R=2" );

	Switch_Win_Id( ActiveWindow );
	g_Tmp_Was_Changed = False;
	if ( Svl( TmpStr ) == 0 ) {
		TmpStr = Global_Str( "!" + _TmpGetSet( ) + "_Last_Tmp" );
	}

	// The /PRELOOPMAC= macro is running the same macro as the CHANGEMAC= for the
	// set controls.  We have to supply the /SELSTR= parameters ourselves
	DlgExecute( Dlg, List_Ctrl, "Edit Templates", EDITTMP_HELPLINK,
			"/RPOS=TmpEditDlgPos/DEACTIVEMAC=_TmpDeactive/INITMAC=_TmpInit" +
			"/PRELOOPMAC=_TmpSetChange //SELSTR=" + Double_Slashes( Sel_Str ) +
			"//TMPSTR=" + Double_Slashes( TmpStr ) + "/EXITMAC=_TmpDone",
			mode_flags );

	if ( !mode_flags ) {
		DlgKill( Dlg );
		g_hTmpEditDlg = 0;
	}
	Switch_Win_Id( ActiveWindow );
	Refresh = TRefresh;

}  // Tmp_Edit

void _TmpInsertMeta( Dlg = Parse_Int( "/DATAHANDLE=", MParm_Str ) ) {
/*
	Inserts metacommands into the template result edit box
	to be invoked only via the metacommand popup menu
*/
	if ( Dlg ) {
		DlgInsertText( Dlg, Edit_Ctrl, Parse_Str( "/META=", MParm_Str ) );
		DlgSetFocus( Dlg, Edit_Ctrl );
	}
}  // _TmpInsertMeta

void _TmpMetaCmds( int Dlg = Parse_Int( "/DATAHANDLE=", MParm_Str ) ) {
/*
	The popup metacommand menu
	Only to be invoked from the metacommands button control
*/
	int x, y;
	if ( dlg && g_hMetaMenu)
	{
		DlgGetCtrlPos(dlg, meta_ctrl, x, y);
		TrackPopupMenu(g_hMetaMenu, 0, x, y, 0, frame_handle, 0);
	}
}

void _TmpEditChange( ) {
/*
	invoked via the /CHANGEMAC= parameter of several dialog box controls
*/

	g_Tmp_Was_Changed = True;
	Return_Int = 0;

}  // Tmp_Edit_Change

void _TmpGlobChange( int Dlg = Parse_Int( "/DLGHANDLE=", MParm_Str ) ) {
/*
	invoked via the /CHANGEMAC= parameter of the global templates checkbox
*/

	g_Tmp_Global = !g_Tmp_Global;
	if ( g_Tmp_Global != 0 ) {

		str TStr = "GLOBAL";

		if ( !File_Exists( User_Path + TStr + Tmp_File_Ext ) ) {
			Rm( "_TmpSetInsert /SET=" + TStr );
			SendDlgItemMessageStr( Dlg, Set_Ctrl, cb_AddString, 0, TStr );
		}
	}
	Rm( "MEWSETUP^SetSave" );
	Return_Int = 0;

}  // _TmpGlobChange

void _TmpCaseChange( Dlg = Parse_Int( "/DATAHANDLE=", MParm_Str ) ) {
/*
 invoked via the /CHANGEMAC= parameter of the case of result and
 case sensitive dialog box controls
*/

	if ( Dlg ) {

		int ActiveWindow = Window_Id;
		int SavRefresh = Refresh;

    g_Tmp_Was_Changed = True;
		DlgSetFields( Dlg );
		g_Tmp_Case = DlgGetInt( Dlg, Case_Ctrl );
		g_Case_Sense = DlgGetInt( Dlg, Sense_Ctrl );

		Refresh = False;
		if ( Switch_Win_Id( g_Data_Window ) ) {
			Mark_Pos;
			Tof;
      Put_Line( Get_Word( " " ) + " " +
          "\x7F" + _gf_tmp_Case + "=" + Str( g_Tmp_Case ) +
          "\x7F" + _gf_tmp_CaseSense + "=" + Str( g_Case_Sense ) );
			Goto_Mark;
		}
		Switch_Win_Id( ActiveWindow );
		Refresh = SavRefresh;
	}
	Return_Int = 0;

}  // _TmpCaseChange

void _TmpSaveData( int SaveFile ) {
/*
	saves the template data for the dialog box to disk
*/

	int ActiveWindow = Window_Id;
  int SavRefresh   = Refresh;
  int ReInit;

	Refresh = False;
	if ( Switch_Win_Id( g_Data_Window ) ) {
    Error_Level = 0;
    if ( ReInit = ( File_Changed && SaveFile ) ) {
      Save_File;
    }
    if ( Error_Level ) {
      Rm( "MeError" );
    }
    else if ( ReInit ) {
      // This re-initalizes template data in ram
      Mark_Pos;
			Tmp_Init_All( Truncate_Path( Truncate_Extension( File_Name ) ), True );
      Goto_Mark;
    }
	}
	Switch_Win_Id( ActiveWindow );
  Refresh = SavRefresh;

}  // _TmpSaveData

void _TmpDoExpand( Dlg = Parse_Int( "/DATAHANDLE=", MParm_Str ) ) {
/*
	invoked from the expand button
*/
	if ( Dlg ) {

		int ActiveWindow = Window_Id;
		int SavRefresh 	 = Refresh;
		int SavLine			 = C_Line;
		int SavRow			 = C_Row;

		Refresh = False;
    _TmpAccept( Dlg, 1 );
    _TmpSaveData( True );
		DlgSetFields( Dlg );
		Switch_Win_Id( g_List_Window );

		str Template = Get_Line( );
		str Set = DlgGetStr( Dlg, Set_Ctrl );

		Switch_Win_Id( ActiveWindow );
    if ( Global_Str( "!" + Set + "_Tmp_Data") == "" ) {
			Tmp_Init_All( Set, False );
    }
		Push_Undo;
		Mark_Pos;
		First_Word;
		g_Original_Col = C_Col;
		Goto_Mark;
		g_Tmp_Recurs_Level = 0;
		Set_Global_Str( "!" + Set + "_Last_Tmp", Template );
		TmpExpand( Set, Template );
		SavRow += C_Line - SavLine; 				// get scrolling correct
		if ( SavRow >= Win_CHeight ) {
			SavRow = Win_CHeight / 2;
		}
		SavLine = C_Line;
		while ( C_Row < SavRow ) {
			Down;
		}
		while ( C_Row > SavRow) {
			Up;
		}
		Goto_Line( SavLine );
		Pop_Undo;
		Refresh = SavRefresh;
		Redraw;
	}
}  // _TmpDoExpand

void _TmpUpdateTmp( int Dlg, int Data_Found ) {
/*
	updates the template data in the template data file for an individual template
*/
	int ActiveWindow = Window_Id;
  int SavRefresh = Refresh;

  struct TTmpHdr TmpHdr;

	Refresh = False;

  // Clear data structure
  DbRec2TmpHdr( TmpHdr, "" );
  if ( Data_Found ) {
    DbRec2TmpHdr( TmpHdr, Get_Line( ) );
	}
  DlgSetStr( Dlg, Keyw_Ctrl, TmpHdr.Keyword );
	DlgUpdateCtrl( Dlg, Keyw_Ctrl, 0 );

  DlgSetStr( Dlg, Desc_Ctrl, TmpHdr.Comment );
	DlgUpdateCtrl( Dlg, Desc_Ctrl, 0 );

  DlgSetInt( Dlg, Min_Ctrl, TmpHdr.MinMatch );
	DlgUpdateCtrl( Dlg, Min_Ctrl, 0 );

  DlgSetInt( Dlg, Space_Ctrl, ( TmpHdr.Flags & _db_tmf_SpaceExpand ) != 0 );
	DlgUpdateCtrl( Dlg, Space_Ctrl, 0 );

  DlgSetInt( Dlg, id_ted_ExpandComment,
      ( TmpHdr.Flags & _db_tmf_CmntExpand ) != 0 );
	DlgUpdateCtrl( Dlg, id_ted_ExpandComment, 0 );

  DlgSetInt( Dlg, id_ted_Eol, TmpHdr.ExpandWhere + 1 );
	DlgUpdateCtrl( Dlg, id_ted_Eol, 0 );

  DlgSetInt( Dlg, id_ted_NoShowInList,
      ( TmpHdr.Flags & _db_tmf_NoListShow ) != 0 );
	DlgUpdateCtrl( Dlg, id_ted_NoShowInList, 0 );

//  DlgSetStr( Dlg, id_ted_HelpCtx, TmpHdr.HelpCtx );
//  DlgUpdateCtrl( Dlg, id_ted_HelpCtx, 0 );

	// put new template result in window
	if ( Switch_Win_Id( g_Edit_Window ) ) {
		Erase_Window;
		Window_Attr |= 0x81;
		File_Name = "TMP_RSLT.TMP";

		int Edit_Window_Num = Cur_Window;
    int Jx = 0;

		Switch_Win_Id( g_Data_Window );
		if ( Cur_Char == "\f" ) {
      Mark_Pos;
			Down;
			while ( ( Cur_Char != "\f" ) && !At_Eof ) {
				Put_Line_To_Win( Get_Line( ), ++Jx, Edit_Window_Num, 0 );
				Down;
			}
      Goto_Mark;
		}
	}
  DlgUpdateCtrl( Dlg, edit_Ctrl, 0 );
	Switch_Win_Id( ActiveWindow );
  Refresh = SavRefresh;

}  // _TmpUpdateTmp

int _TmpCopyData( str SelStr, int Cut )
/******************************************************************************
															 Multi-Edit Macro
															 23-Jan-96  15:59

  Function: Copy or cut the SelStr template data to buffer 52.
	Entry   : str SelStr		- The template name
						int Cut				- True to cut else copy data

	Exit    : int
							False				- No data copied/cut
							True				- Data copied/cut

							 Copyright (C) 1996 by American Cybernetics, Inc.
********************************************************************( ldh )***/
{
	int Result = False;

	str TStr;

	if ( Switch_Win_Id( g_Data_Window ) ) {
    if ( _TmpLocateData( SelStr, 0 ) ) {
			Mark_Pos;
			Block_Begin;
			do {
				Down;
			} while ( ( Cur_Char != "\f" ) && !At_Eof );
			Up;
			Block_End;
			if ( Cut ) {
				TStr = "/M";
			}
      Rm( "Cut /B=52/NM=1" + TStr );
			Goto_Mark;
			Result = True;
		}
	}
	return ( Result );

}  // _TmpCopyData

void _TmpInsert(
			int Dlg 	 = Parse_Int( "/DATAHANDLE=", MParm_Str ),
			int DoCopy = Parse_Int( "/COPY=", MParm_Str )
)
/*
	triggered from the template insert button
*/
{
	if ( Dlg ) {

		int ActiveWindow = Window_Id;
		int TRefresh = Refresh;
		int TInsert_Mode = Insert_Mode;
		int Jx;

		str TStr;
		str CurTmpStr;
		str Title = " Template";

		Refresh = False;
		_TmpAccept( Dlg, 1 );
		_TmpSaveData( False );
		if ( Switch_Win_Id( g_Data_Window ) ) {
			if ( Switch_Win_Id( g_List_Window ) ) {
				if ( DoCopy ) {
					Title = "Copy" + Title;
				}
				else {
					Title = "Add" + Title;
				}
				Return_Str = "";
				Rm( "QueryBox /W=32/T=" + Title );
				if ( Return_Int ) {
					Mark_Pos;
					Tof;
					if ( Find_Text( "^" + Make_Literal_X( Return_Str ) + "$", 0, _RegExp ) ) {
						Rm( "MessageBox /B=2/T=Template Editing Error/M=The template: " +
								Return_Str + " already exists." );
						Goto_Mark;
					}
					else {
						Goto_Mark;
						CurTmpStr = Get_Line( );
						Goto_Col( 1 );
						if ( !At_Eof ) {
							Cr;
							Up;
						}
						Put_Line( Return_Str );
						if ( DoCopy ) {
							Jx = _TmpCopyData( CurTmpStr, False );
						}
						else {
							Switch_Win_Id( g_Data_Window );
              Jx = _TmpLocateData( CurTmpStr, 0 );
						}
            Insert_Mode = True;
            if ( DoCopy && Jx ) {
              Rm( "Paste /B=52/O=1/A=0" );
              TStr = Get_Line( );
              Jx = XPos( " ", TStr, 1 );
              if ( Jx ) {
                TStr = Copy( TStr, Jx, Svl( TStr ) - Jx + 1 );
              }
            }
            else {
              if ( Jx == 0 ) {
                Eof;
                Down;
              }
              Goto_Col( 1 );
              Cr;
              Up;
              // Set defaults to expand anywhere
              TStr = " \x7F" + _db_tmp_FirstWord + "=2" +
                  "\x7F" + _db_tmp_EOL + "=2";
            }
            Put_Line( "\f" + Return_Str + tmp_Data_Ext + TStr );
						g_Template_Name = Return_Str;
						_TmpUpdateTmp( Dlg, True );
						DlgUpdateCtrl( Dlg, List_Ctrl, 0 );
						DlgSetFocus( Dlg, List_Ctrl );
						Insert_Mode = TInsert_Mode;
            g_Tmp_Was_Changed = True;
					}
				}
			}
		}
	//	SetDefaultButton( Parse_Int( "/DLGHANDLE=", MParm_Str ), insert_Ctrl );
		Switch_Win_Id( ActiveWindow );
		Refresh = TRefresh;
	}
}  // _TmpInsert

void _TmpDelete( int Dlg = Parse_Int( "/DATAHANDLE=", MParm_Str ) ) {
/*
	invoked from the template delete button
*/
	if ( Dlg ) {

		int ActiveWindow = Window_Id;
		int TRefresh = Refresh;

		str Sel_Str;

		Refresh = False;
		if ( Switch_Win_Id( g_Data_Window ) ) {
			if ( Switch_Win_Id( g_List_Window ) ) {

				Sel_Str = Get_Line( );
        if ( Svl( Sel_Str ) != 0 ) {
          Return_Int = VerifyDlg( "Delete the template \"" + Sel_Str + "\"?",
              "Edit Templates", "", 0, False ) == id_Std_Yes;
          if ( Return_Int ) {
            Del_Line;
            if ( At_Eof ) {
              Up;
            }
            Switch_Win_Id( g_Data_Window );
            if ( _TmpLocateData( Sel_Str, 0 ) ) {
              do {
                Del_Line;
              } while ( ( Cur_Char != "\f" ) && ( !At_Eof ) );
            }
            if ( Cur_Char != "\f" ) {
              do {
                Up;
              } while ( ( Cur_Char != "\f" ) && ( C_Line != 1 ) );
            }
            if ( C_Line == 1 ) {
              Eof;
              Down;
            }
            _TmpUpdateTmp( Dlg, XPos( Tmp_Data_Ext, Get_Line( ), 1 ) );
            DlgUpdateCtrl( Dlg, List_Ctrl, 0 );
            DlgSetFocus( Dlg, List_Ctrl );
            g_Tmp_Was_Changed = True;
          }
        }
      }
		}
	//	SetDefaultButton( Parse_Int( "/DLGHANDLE=", MParm_Str ), delete_Ctrl );
		Switch_Win_Id( ActiveWindow );
		Refresh = TRefresh;
	}
}  // _TmpDelete

void _TmpMoveUp( int Dlg = Parse_Int( "/DATAHANDLE=", MParm_Str ) )
/******************************************************************************
															 Multi-Edit Macro
															 23-Jan-96  12:59

	Function: Move the current template data up in the list and template file.
	Entry   : int Dlg		- Dialog data handle

							 Copyright (C) 1996 by American Cybernetics, Inc.
********************************************************************( ldh )***/
{
	if ( Dlg ) {

		int ActiveWin  = Window_Id;
		int SavRefresh = Refresh;

		str SelStr;

		Refresh = False;
		if ( Switch_Win_Id( g_Data_Window ) ) {
			if ( Switch_Win_Id( g_List_Window ) ) {
				if ( 1 < C_Line ) {
					SelStr = Get_Line( );
          Rm( "Cut /B=52/M=1/NM=1" );
					Up;
          Rm( "Paste /B=52/O=1/A=0" );
					if ( _TmpCopyData( SelStr, True ) ) {
						do {
							Up;
						} while ( ( "\f" != Cur_Char ) && ( 1 != C_Line ) );
            Rm( "Paste /B=52/O=1/A=0" );
					}
					_TmpUpdateTmp( Dlg, XPos( Tmp_Data_Ext, Get_Line( ), 1 ) );
					DlgUpdateCtrl( Dlg, List_Ctrl, 0 );
					DlgSetFocus( Dlg, List_Ctrl );
          g_Tmp_Was_Changed = True;
				}
			}
		}
		Switch_Win_Id( ActiveWin );
		Refresh = SavRefresh;
	}
}  // _TmpMoveUp

void _TmpMoveDn( int Dlg = Parse_Int( "/DATAHANDLE=", MParm_Str ) )
/******************************************************************************
															 Multi-Edit Macro
															 23-Jan-96  13:00

	Function: Move the current template data down in the list and template file.
	Entry   : int Dlg		- Dialog data handle

							 Copyright (C) 1996 by American Cybernetics, Inc.
********************************************************************( ldh )***/
{
	if ( Dlg ) {

		int ActiveWin  = Window_Id;
		int SavRefresh = Refresh;

		str SelStr;

		Refresh = False;
		if ( Switch_Win_Id( g_Data_Window ) ) {
			if ( Switch_Win_Id( g_List_Window ) ) {
				Down;
				if ( !At_Eof ) {
					Up;
					SelStr = Get_Line( );
          Rm( "Cut /B=52/M=1/NM=1" );
					Down;
          Rm( "Paste /B=52/O=1/A=0" );
					if ( _TmpCopyData( SelStr, True ) ) {
						do {
							Down;
						} while ( ( "\f" != Cur_Char ) && !At_Eof );
            Rm( "Paste /B=52/O=1/A=0" );
					}
					_TmpUpdateTmp( Dlg, XPos( Tmp_Data_Ext, Get_Line( ), 1 ) );
					DlgUpdateCtrl( Dlg, List_Ctrl, 0 );
					DlgSetFocus( Dlg, List_Ctrl );
          g_Tmp_Was_Changed = True;
				}
			}
			else {
				Up;
			}
		}
		Switch_Win_Id( ActiveWin );
		Refresh = SavRefresh;
	}
}  // _TmpMoveDn

void _TmpSetInsert(
			int Dlg = Parse_Int( "/DATAHANDLE=", MParm_Str ),
			str Passed_Set = Parse_Str( "/SET=", MParm_Str )
)
/*
	invoked from the set insert button
*/
{
	if ( Dlg || ( Svl( Passed_Set ) !=  0 ) ) {

		int ActiveWindow = Window_Id;
		int TRefresh = Refresh;

		str New_Set;

		Refresh = False;
		Return_Str = "";
		if ( Svl( Passed_Set ) != 0 ) {
			Return_Str = Passed_Set;
			Return_Int = True;
		}
		else {
			Rm( "QueryBox /T=Add Template Set/W=8" );
		}
		if ( Return_Int ) {
			New_Set = Caps( Return_Str );
			Return_Str = User_Path + New_Set + tmp_File_Ext;
			if ( File_Exists( Return_Str ) ) {
				Rm( "MessageBox /B=2/T=Template Editing Error/M=The template set: " +
						New_Set + " already exists." );
			}
			else {
				Create_Window;
				Window_Attr |= 0x81;
				File_Name = Return_Str;
				Put_Line( "\f" + Truncate_Path( File_Name ) );
				Error_Level = 0;
				Save_File;
				if ( Error_Level ) {
					Rm( "MessageBox /B=2/T=Template Editing Error/M=Error #" +
							Str( Error_Level ) + " attempting to create template set data file: " +
							File_Name + "." );
					Delete_Window;
				}
				else {
					Delete_Window;
					if ( Svl( Passed_Set ) == 0 ) {
						Switch_Win_Id( ActiveWindow );
						Goto_Col( 1 );
						Cr;
						Up;
						Put_Line( New_Set );
					}
				}
			}
		}
		if ( Svl( Passed_Set ) == 0 ) {
			DlgUpdateCtrl( Dlg, List_Ctrl, 0 );
			DlgSetFocus( Dlg, List_Ctrl );
		}
		Switch_Win_Id( ActiveWindow );
		Refresh = TRefresh;
	}
}  // _TmpSetInsert

void _TmpSetDelete( int Dlg = Parse_Int( "/DATAHANDLE=", Mparm_Str ) ) {
/*
	invoked from the set delete button
*/
	if (dlg) {
		int t_refresh = refresh,
				active_window = window_id;
		refresh = false;
		Return_Int = VerifyDlg( "Delete the template set \"" + Get_Line( ) + "\"?",
				"Delete Template Set", "", 0, False ) == id_std_Yes;
		if (return_int) {
			return_str = user_path + get_line + tmp_file_ext;
			if (file_exists(return_str)) {
				if (switch_file(return_str)) {
					if (window_id == g_data_window) {
						erase_window;
						window_attr |= 0x81;
					} else {
						delete_window;
					}
				}
				switch_win_id(active_window);
				error_level = 0;
				// delete the actual data file on disk for this set
				Del_File(return_str);
				if (error_level) {
					RM("MESSAGEBOX /B=2/T=Template Editing Error/M=Error #" +
						str(error_level) + " attempting to delete template set data file: " + return_str + ".");
				} else {
					switch_win_id(active_window);
					del_line;
				}
			}
		}
		DlgUpdateCtrl(dlg, list_ctrl, 0);
		DlgSetFocus(dlg, list_ctrl);
		switch_win_id(active_window);
		refresh = t_refresh;
	}
}

void _TmpDeactive( int Dlg = Parse_Int( "/DATAHANDLE=", MParm_Str ) )
/*
	This runs if the modeless dialog is switched away from
*/
{
  _TmpAccept( Dlg, 1 );
  _TmpSaveData( True );

}  // _TmpDeactive

void _TmpDone( int Dlg = Parse_Int( "/DATAHANDLE=", Mparm_Str ) ) {
/*
	activated via the /EXITMAC= parameter of the DlgExectute() call
*/

	int ActiveWindow = Window_Id;
	int TRefresh = Refresh;

	Refresh = False;
  _TmpAccept( Dlg, 1 );
  _TmpSaveData( True );
	_TmpMetaExit( Dlg );

	if ( Switch_Win_Id( g_List_Window ) ) {
		Delete_Window;
	}
	if ( Switch_Win_Id( g_Edit_Window ) ) {
		Delete_Window;
	}
	Switch_Win_Id( ActiveWindow );
	Refresh = TRefresh;
	// Clear template globals
	g_hTmpEditDlg = 0;
	g_List_Window = 0;
	g_Edit_Window = 0;
	g_Data_Window = 0;
  g_TmpEditLine = 0;

	Return_Int = 0;

}  // _TmpDone

void _TmpListChange(
      int Dlg     = Parse_Int( "/DATAHANDLE=", MParm_Str ),
      str Sel_Str = Parse_Str( "/SELSTR=", MParm_Str )
)
/*
	invoked via the /CHANGEMAC= parameter of the template list control
*/
{
  if ( Dlg ) {

    int Active_Window = Window_Id;
    int SavRefresh    = Refresh;
    int Flags;

    _TmpAccept( Dlg, 0 );
//    if ( _TmpAccept( Dlg, 0 ) ) {
//      _TmpSaveData( False );
//    }

    Refresh = False;
    if ( Switch_Win_Id( g_List_Window ) ) {
      g_Template_Name = Get_Line( );
      Flags = g_TmpEditLine;
      g_TmpEditLine = C_Line;
      if ( C_Line <= Flags ) {
        Flags = -1;
      }
      if ( Switch_Win_Id( g_Data_Window)) {
				// grab the data from the data file and update the controls
        _TmpUpdateTmp( Dlg, _TmpLocateData( Sel_Str, Flags ) );
			}
		}
    Switch_Win_Id( Active_Window );
    Refresh = SavRefresh;
	}
  Return_Int = 0;
  return ( );

}  // _TmpListChange

void _TmpSetChange(
			int Dlg = Parse_Int( "/DATAHANDLE=", MParm_Str ),
			str Sel_Str = Parse_Str( "/SELSTR=", MParm_Str ),
			str Tmp_Sel_Str = Parse_Str( "/TMPSTR=", MParm_Str )
)
/*
	invoked via the /CHANGEMAC= parameter of the template set control
*/
{
	if ( Dlg ) {

		int ActiveWindow = Window_Id;
		int TRefresh = Refresh;

    _TmpAccept( Dlg, 0 );
    if ( Svl( Tmp_Sel_Str ) == 0 ) {
      _TmpSaveData( True );
    }
		Refresh = False;
		if ( Switch_Win_Id( g_List_Window ) ) {

			int List_Window_Num = Cur_Window;

			Erase_Window;
			Window_Attr |= 0x81;
			File_Name = "TMP_LIST.TMP";
			if ( Switch_Win_Id( g_Data_Window ) ) {
				if ( _TmpLdDataFile( Sel_Str, 1 ) ) {
					g_Data_Window = Window_Id;

					int T_Int;
					int Count = 0;

					// put stuff in the templates list
					Tof;
					Eol;
					g_Template_Name = "";
					while ( Find_Text( "^\f", 0, _RegExp ) ) {
						Eol;
						if ( T_Int = Xpos( ".", Get_Line( ), 1 ) ) {
							if ( g_Template_Name == "" ) {
								g_Template_Name = Copy( Get_Line( ), 2, T_Int - 2);
							}
              Put_Line_To_Win( Copy( Get_Line( ), 2, T_Int - 2 ), ++Count,
                  List_Window_Num, 0 );
						}
					}
          Tof;
          // DlgSetInt() updates the menu item data structure,
          // then DlgUpdateCtrl() updates the control itself
          DlgSetInt( Dlg, case_Ctrl,
              Parse_Int( "\x7F" + _gf_tmp_Case + "=", Get_Line( ) ) );
          DlgUpdateCtrl( Dlg, case_Ctrl, 0 );

          DlgSetInt( Dlg, sense_Ctrl,
            Parse_Int( "\x7F" + _gf_tmp_CaseSense + "=", Get_Line( ) ) );
          DlgUpdateCtrl( Dlg, sense_Ctrl, 0 );

          if ( Svl( Tmp_Sel_Str ) ) {
            Switch_Win_Id( g_List_Window );
            Tof;
						if ( Find_Text( "^" + Make_Literal_X( Tmp_Sel_Str ) + "$", 0,
								_RegExp ) ) {
              Switch_Win_Id( g_Data_Window );
							if ( Find_Text( "^\f" + Make_Literal_X( Tmp_Sel_Str) + "\.", 0,
									_RegExp ) ) {
                Up;
							}
							else {
                Tof;
                Eol;
                if ( Find_Text( "^\f", 0, _RegExp ) ) {
                  Up;
                }
                else {
                  Eof;
                  Up;
                  Goto_Col( 1 );
                }
							}
						}
						Switch_Win_Id( g_Data_Window );
					}
					else {
						Tof;
            Eol;
            if ( Find_Text( "^\f", 0, _RegExp ) ) {
              Up;
            }
            else {
              Eof;
              Up;
              Goto_Col( 1 );
            }
					}
					Right;
					Down;
					DlgUpdateCtrl( Dlg, List_Ctrl, 0 );

					_TmpListChange( Dlg, Get_Word( "." ) );
					DlgSetFocus( Dlg, List_Ctrl );
				}
			}
      g_TmpEditLine = 0;
		}
		Switch_Win_Id( ActiveWindow );
		Refresh = TRefresh;
	}
	Return_Int = 0;

}  // _TmpSetChange

int _TmpAccept( int Dlg, int Focus_Flag )
/*
	updates the template set data file from the template dialog box controls
*/
{
  int Result = g_Tmp_Was_Changed;

  if ( g_Tmp_Was_Changed ) {

    str Name = g_Template_Name;

    int T_Refresh     = Refresh;
    int Active_Window = Window_Id;
		int Jx;
		int Jy;

    struct TTmpHdr TmpHdr;

    Refresh = False;
    if ( Switch_Win_Id( g_List_Window ) ) {

      str T_Str[ Max_Line_Length ];

      if ( !Svl( Name ) ) {
        Name = Get_Line( );
			}
      if ( Switch_Win_Id( g_Edit_Window ) ) {

        int Edit_Win_Num = Cur_Window;

				// update data structures from controls
				DlgSetFields( Dlg );
//        Jx = DlgGetInt( Dlg, id_ted_Eol ) - 1;
//        Jy = Jx / 3;
//        Jx -= Jy * 3;
//        Jy = 0x03 ^ ( Jy + 1 );
//        Jx = 0x03 ^ ( Jx + 1 );
//        T_Str = " " + "\x7F" + "TEMPLATE=" + DlgGetStr( Dlg, Keyw_Ctrl ) +
//            "\x7F" + "COMMENT=" + DlgGetStr( Dlg, Desc_Ctrl ) +
//            "\x7F" + "MINMATCH=" + Str( DlgGetInt( Dlg, Min_Ctrl ) ) +
//            "\x7F" + "EXCMNT=" + Str( DlgGetInt( Dlg, id_ted_ExpandComment ) ) +
//            "\x7F" + "SPACEBAR=" + Str( DlgGetInt( Dlg, Space_Ctrl ) ) +
//            "\x7F" + "FIRSTWORD=" + Str( Jy ) + "\x7F" + "EOL=" + Str( Jx ) +
//            "\x7F" + "NOSHOW=" + Str( DlgGetInt( Dlg, id_Ted_NoShowInList ) ) +
//            "\x7F" + "HSTR=" + DlgGetStr( Dlg, id_Ted_HelpFile );
        TmpHdr.Name = Name;
        TmpHdr.Comment = DlgGetStr( Dlg, Desc_Ctrl );
        TmpHdr.HelpCtx = DlgGetStr( Dlg, id_ted_HelpCtx );
        TmpHdr.Keyword = DlgGetStr( Dlg, Keyw_Ctrl );
        TmpHdr.MinMatch = DlgGetInt( Dlg, Min_Ctrl );
        TmpHdr.ExpandWhere = DlgGetInt( Dlg, id_ted_Eol ) - 1;
        TmpHdr.Flags = 0;
        if ( DlgGetInt( Dlg, id_ted_ExpandComment ) ) {
          TmpHdr.Flags |= _db_tmf_CmntExpand;
        }
        if ( DlgGetInt( Dlg, Space_Ctrl ) ) {
          TmpHdr.Flags |= _db_tmf_SpaceExpand;
        }
        if ( DlgGetInt( Dlg, id_ted_NoShowInList ) ) {
          TmpHdr.Flags |= _db_tmf_NoListShow;
        }
        T_Str = DbTmpHdr2Rec( TmpHdr );

        int T_Stream_Block_Mode = Stream_Block_Mode;

        Tof;
        Stream_Block_Mode = false;
        Str_Block_Begin;
        Eof;
        Block_End;
        Stream_Block_Mode = T_Stream_Block_Mode;
        if ( Switch_Win_Id( g_Data_Window ) ) {

          int T_Insert_Mode = Insert_Mode;

          if ( _TmpLocateData( Name, 0 ) ) {
//            Put_Line( "\f" + Name + Tmp_Data_Ext + T_Str );
            Put_Line( T_Str );
            Down;
            if ( ( Cur_Char != "\f" ) && ( !At_Eof ) ) {
              Block_Begin;
              while ( !At_Eof && ( Cur_Char != "\f" ) ) {
                Down;
							}
              Up;
              Delete_Block;
						}
            Up;
            Insert_Mode = true;
            Eol;
            Cr;
            Window_Copy( Edit_Win_Num );
            Insert_Mode = T_Insert_Mode;
					}
          g_Tmp_Was_Changed = false;
          if ( !Focus_Flag ) {
            DlgSetFocus( Dlg, list_Ctrl );
					}
				}
			}
		}
    Switch_Win_Id( Active_Window );
    Refresh = T_Refresh;
	}
  return ( Result );

}  // _TmpAccept

void _TmpCancelEdit( int Dlg = Parse_Int( "/DATAHANDLE=", MParm_Str ) )
/******************************************************************************
															 Multi-Edit Macro
															 03-Oct-95  14:35

	Function: Restore the edit template settings to the last saved values.
	Entry   : int Dlg		- The data handle

							Copyright (C) 1995-96 by American Cybernetics, Inc.
********************************************************************( ldh )***/
{
	int ActiveWindow = Window_Id;

	str Template;

	g_Tmp_Was_Changed = False;
	DlgSetFields( Dlg );
	Switch_Win_Id( g_List_Window );
	Template = Get_Line( );
	Switch_Win_Id( ActiveWindow );
	_TmpListChange( Dlg, Template );

}  // _TmpCancelEdit

void _TmpSetFieldEvent( int Set, str Misc )
/******************************************************************************
															 Multi-Edit Macro
															 05-Oct-95  14:00

	Function: Set or clear the template field search events.

	Entry   : int Set     - True to set the events.
						int Misc		- Parameters to be passed to the event macro.

							Copyright (C) 1995-96 by American Cybernectic, Inc.
********************************************************************( ldh )***/
{
	str GStr = "!TmpEventSav_";

	if ( Set ) {

		int SavedPB = g_TmpSavedPB;

		// Save current event macro and mode
		Set_Global_Str( GStr + Str( Window_Id ), Event_Macro );
		Set_Global_Int( GStr + Str( Window_Id ), Event_Mode );
		if ( SavedPB == 0 ) {
			SavedPB = Persistent_Blocks + 1;
		}
		g_TmpSavedPB = 0;
		// Set new event macro and mode
		Event_Macro = "_TmpFieldEvent /PB=" + Str( SavedPB - 1 ) +
				"/TOB=" + Str( Typing_Overwrites_Block ) + Misc;
		Event_Mode = EVENT_MODE_ENHANCED | EVENT_WCMD | EVENT_KEY_ENHANCED |
				EVENT_CURSOR_LINE | EVENT_CURSOR_COL;
		Persistent_Blocks = False;
		Typing_Overwrites_Block = True;
	}
	else {
		Persistent_Blocks = Parse_Int( "/PB=", Event_Macro );
		Typing_Overwrites_Block = Parse_Int( "/TOB=", Event_Macro );
		if ( Parse_Int( "/BP=", Event_Macro ) ) {
			PopBlock( True );
			Block_End;
		}
		// Restore previous Event_Macro and Event_Mode
		GStr += Str( Window_Id );
		Event_Macro = Global_Str( GStr );
		Event_Mode = Global_Int( GStr );
		Set_Global_Str( GStr, "" );
		Set_Global_Int( GStr, 0 );
	}
}  // _TmpClrFieldEvent

int _TmpFieldEvent( int Event )
/******************************************************************************
															 Multi-Edit Macro
															 04-Oct-95  15:12

	Function: The template fields event macro.
	Entry   : int Event		- The triggered event type
	Exit    : int 				- True

							Copyright (C) 1995-96 by American Cybernectic, Inc.
********************************************************************( ldh )***/
{
	switch ( Event & 0xFFFF ) {
		case EVENT_DELETE_WIN :
		case EVENT_DEACTIVATE_WIN :
			Persistent_Blocks = Parse_Int( "/PB=", MParm_Str );
			Typing_Overwrites_Block = Parse_Int( "/TOB=", MParm_Str );
			break;

		case EVENT_ACTIVATE_WIN :
			Persistent_Blocks = False;
			Typing_Overwrites_Block = True;
			break;
	}
	if ( Block_Stat == 0 ) {
		_TmpSetFieldEvent( False, "" );
	}
	return ( True );

}  // _TmpFieldEvent

void TmpGotoField(
			int Backward = Parse_Int( "/B=", MParm_Str ),
			int Scope    = Parse_Int( "/LS=", MParm_Str )
)
/******************************************************************************
															 Multi-Edit Macro
															 30-Jun-95  16:18

	Function: Position the cursor on the next or previous template field string.
	Entry   : int Backward  - True to search backward for field           (/B=)
						int Scope			- The number of lines to restrict the search  (/LS=)

							Copyright (C) 1995-96 by American Cybernectic, Inc.
********************************************************************( ldh )***/
{
	int SavRefresh = Refresh;
	int Flags 		 = _RegExp;
	int EventFound = Copy( Event_Macro, 1, 14 ) == "_TmpFieldEvent";
	int NextFind 	 = CursorInBlock( True ) && ( Cur_Char == "\x60" ) && EventFound;
	int OrgLine		 = C_Line;
	int BlkPushed	 = False;
	int SavLine;

	struct tCommentChars rCC;

	str FndStr = "(\x60.@\x60)";
	str CmtStr;

	Refresh = False;
	Push_Undo;
	Mark_Pos;
	if ( EventFound ) {
		// clear event macro
		_TmpSetFieldEvent( False, "" );
	}
	else {
		BlkPushed = PushBlock( True );
	}
	if ( Backward ) {
		Flags |= _Backward;
		if ( NextFind ) {
			Rm( "TopBlock" );
			Left;
		}
	}
	else if ( NextFind ) {
		Rm( "EndBlock" );
		Right;
	}
	Block_Off;
	GetCommentChars( rCC );
	if ( Length( rCC.szOpenComment1 ) && Length( rCC.szCloseComment1 ) ) {
		CmtStr = rCC.szOpenComment1 + "?" + rCC.szCloseComment1;
		FndStr += "|(" + Make_Literal_X( CmtStr ) + ")";
	}
	if ( Find_Text( FndStr, Scope, Flags ) ) {
		if ( C_Line > OrgLine ) {
			if ( ( C_Line - OrgLine ) <= ( Win_Y2 - Win_Y1 - C_Row ) ) {
				SavLine = C_Line;
				Goto_Line( OrgLine );
				while ( C_Line != SavLine ) {
					Down;
				}
			}
			else {
				Rm( "MidWin /ML=1" );
			}
		}
		else {
			if ( ( OrgLine - C_Line ) < C_Row ) {
				SavLine = C_Line;
				Goto_Line( OrgLine );
				while ( C_Line != SavLine ) {
					Up;
				}
			}
			else {
				Rm( "MidWin /ML=1" );
			}
		}
		if ( Found_Str == CmtStr ) {
			Del_Chars( Length( Found_Str ) );
		}
		else {
			Mark_Pos;
			Goto_Col( Search_End_Col );
			if ( Stream_Block_Mode ) {
				Left;
			}
			Str_Block_Begin;
			Goto_Mark;
			Block_End;
			// Set event macro
			_TmpSetFieldEvent( True, "/BP=" + Str( BlkPushed ) );
		}
		Pop_Mark;
	}
	else {
		Goto_Mark;
	}
	Pop_Undo;
	Refresh = SavRefresh;

}  // TmpGotoField

str DbTmpHdr2Rec( struct TTmpHdr TmpHdr )
/******************************************************************************
                               Multi-Edit Macro
                               30-Jan-96  13:08

  Function: Convert a template structure to the template header string
  Entry   : struct TTmpHdr    - The template header structure
  Exit    : str               - The template header string

               Copyright (C) 1996 by American Cybernetics, Inc.
********************************************************************( ldh )***/
{
  str DbRecord[ Max_Line_Length ];

  int Jx;
  int Jy;

  if ( TmpHdr.Name != "" ) {
    DbRecord = "\f" + TmpHdr.Name + tmp_Data_Ext + " ";
    DbRecord += _db_Delimit + _db_tmp_Keyword + "=" + TmpHdr.Keyword;
    DbRecord += _db_Delimit + _db_tmp_Comment + "=" + TmpHdr.Comment;
    DbRecord += _db_Delimit + _db_tmp_MinMatch + "=" + Str( TmpHdr.MinMatch );
    DbRecord += _db_Delimit + _db_tmp_CmntExpand + "=";
    if ( TmpHdr.Flags & _db_tmf_CmntExpand ) {
      DbRecord += "1";
    }
    else {
      DbRecord += "0";
    }
    DbRecord += _db_Delimit + _db_tmp_SpaceExpand + "=";
    if ( TmpHdr.Flags & _db_tmf_SpaceExpand ) {
      DbRecord += "1";
    }
    else {
      DbRecord += "0";
    }
    if ( ( TmpHdr.ExpandWhere < 0 ) || ( TmpHdr.ExpandWhere > 8 ) ) {
      TmpHdr.ExpandWhere = 0;
    }
    Jx = TmpHdr.ExpandWhere;
    Jy = Jx / 3;
    Jx -= Jy * 3;
    Jy = 0x03 ^ ( Jy + 1 );
    DbRecord += _db_Delimit + _db_tmp_FirstWord + "=" + Str( Jy );

    Jx = 0x03 ^ ( Jx + 1 );
    DbRecord +=  _db_Delimit + _db_tmp_EOL + "=" + Str( Jx );
    DbRecord += _db_Delimit + _db_tmp_NoListShow + "=";
    if ( TmpHdr.Flags & _db_tmf_NoListShow ) {
      DbRecord += "1";
    }
    else {
      DbRecord += "0";
    }
    DbRecord += _db_Delimit + _db_tmp_HelpCtx + "=" + TmpHdr.HelpCtx;
  }
  return ( DbRecord );

}  // DbTmpHdr2Rec

void DbRec2TmpHdr( struct TTmpHdr TmpHdr, str DbRecord[ Max_Line_Length ] )
/******************************************************************************
															 Multi-Edit Macro
                               30-Jan-96  14:45

  Function: Fills a TTmpHdr structure with the data from a TmpHdr Db record.

               Copyright (C) 1996 by American Cybernectics, Inc.
********************************************************************( ldh )***/
{
  int Jx;

  TmpHdr.Name = "";
  if ( Copy( DbRecord, 1, 1 ) == "\f" ) {
    if ( Jx = XPos( tmp_Data_Ext + " ", DbRecord, 2 ) ) {
      TmpHdr.Name = Copy( DbRecord, 2, Jx );
    }
  }
  TmpHdr.Comment = Parse_Str( _db_Delimit + _db_tmp_Comment + "=", DbRecord );
  TmpHdr.HelpCtx = Parse_Str( _db_Delimit + _db_tmp_HelpCtx + "=", DbRecord );
  TmpHdr.Keyword = Parse_Str( _db_Delimit + _db_tmp_Keyword + "=", DbRecord );
  TmpHdr.MinMatch = Parse_Int( _db_Delimit + _db_tmp_MinMatch + "=", DbRecord );

  Jx = Parse_Int( _db_Delimit + _db_tmp_FirstWord + "=", DbRecord );
  Jx = ( ( 0x03 ^ Jx ) - 1 ) * 3;
  Jx += ( 0x03 ^ Parse_Int( _db_Delimit + _db_tmp_Eol + "=", DbRecord ) ) - 1;
  TmpHdr.ExpandWhere = Jx;

  TmpHdr.Flags = 0;
  if ( Parse_Int( _db_Delimit + _db_tmp_CmntExpand + "=", DbRecord ) != 0 ) {
    TmpHdr.Flags |= _db_tmf_CmntExpand;
  }
  if ( Parse_Int( _db_Delimit + _db_tmp_SpaceExpand + "=", DbRecord ) != 0 ) {
    TmpHdr.Flags |= _db_tmf_SpaceExpand;
  }
  if ( Parse_Int( _db_Delimit + _db_tmp_NoListShow + "=", DbRecord ) != 0 ) {
    TmpHdr.Flags |= _db_tmf_NoListShow;
  }
}  // DbRec2CmdMap
