
/***************************************************************************
**
**    $Header:   D:/EPSLDV1/SRC/LOG/SHLEDIT1.CPP   1.8   20 Jun 1996 09:29:06   ZJRD  $
**
**    $Log:   D:/EPSLDV1/SRC/LOG/SHLEDIT1.CPP  $
** 
**    Rev 1.8   20 Jun 1996 09:29:06   ZJRD
** EasyPack/SLD Version 1.20a
** 
**    Rev 1.6   10 Jun 1996 10:23:44   ZJRD
** EasyPack/SLD Version 1.20
** 
**    Rev 1.4   29 May 1996 09:35:10   ZJRD
** EasyPack/SLD Version 1.95
** 
**    Rev 1.3   16 May 1996 09:08:12   ZJRD
** EasyPack/SLD Version 1.94
** 
**    Rev 1.2   10 May 1996 09:08:44   ZJRD
** EasyPack/SLD Version 1.93
** 
**    Rev 1.1   02 May 1996 10:24:40   ZJRD
** EasyPack/SLD Version 1.92
** 
**    Rev 1.14   18 Apr 1996 13:00:22   Shirley
** EasyPack/SLD Version 1.91
** 
**    Rev 1.13   12 Apr 1996 10:35:40   Shirley
** EasyPack/SLD Version 1.90
** 
**    Rev 1.11   15 Feb 1996 08:49:38   Shirley
** No change.
** 
**    Rev 1.10   12 Feb 1996 14:02:06   Shirley
** No change.
** 
**    Rev 1.9   06 Feb 1996 15:27:20   Shirley
** No change.
** 
**    Rev 1.8   06 Feb 1996 13:42:58   Shirley
** No change.
** 
**    Rev 1.7   01 Feb 1996 10:15:50   Shirley
** No change.
** 
**    Rev 1.6   26 Jan 1996 09:12:42   Shirley
** No change.
** 
**    Rev 1.5   25 Jan 1996 13:13:22   Shirley
** No change.
** 
**    Rev 1.4   24 Jan 1996 10:40:20   Shirley
** No change.
** 
**    Rev 1.3   23 Jan 1996 11:22:20   Shirley
** EasypPack/SLD Version 0.34c
** 
**    Rev 1.2   18 Jan 1996 10:13:16   Shirley
** No change.
** 
**    Rev 1.1   15 Jan 1996 16:14:40   Shirley
** No change.
** 
**    Rev 1.0   04 Jan 1996 11:13:32   Shirley
** Initial revision.
**
****************************************************************************/

/////////////////////////////////////////////////////////////////////////////
//
//  File name:  SHLEDIT1.CPP
//
//  Description:The implement file of the class ShellEditor1
//
//  Author:     Roger Zhang
//
//  Date:       01/10/96
//
//  Modification:
//
//      1. 01/10/96, Initial version 
//
//
//  Copyright (C) 1996 Microtek International. All rights reserved.
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include <ctype.h>

#include "shlcom.h"                   
#include "shledit.h"                   
#include "shledit1.h"
#include "aliaspub.h"

/////////////////////////////////////////////////////////////////////////////
// refer to command table

//extern tagCmdTable* CommandRecord;
extern int nMaxCmdNo;
extern int nAsmFlag;
extern BOOL isFirstToken;

/////////////////////////////////////////////////////////////////////////////
// External function prototypes.

BOOL SearchCommand(const char* pszCommand, int& nArgc, char* pszArgv[]);
int ExpandCommand(const char* pszCommand, char* pszExpand, char* pszHints);
BOOL ExpandParameter(const char* pszCommand, const char* pszParameter, char* pszExpand);
int GetControlOption(CString &strReset,CString &strEa,CString &strEben);

/////////////////////////////////////////////////////////////////////////////
// Argument Table
/*
struct tagArgTable {
	char * m_pszArg;
	int m_nMin;
} ArgTable[] = { 
    "Address", 1,
    "AK", 2,
	"ALl", 2, 
	"APpend", 2,
	"ASsemble", 2,       
    "BAckward", 2,
	"BIt", 2,
    "Byte", 1,
    "C", 1,
    "CAll", 2,
    "CEnter", 2,
    "CLear", 2,
	"CLOse", 3,  
	"COde",  2,
	"COMmand", 3,
	"COUnt", 3,
	"CR", 2,
    "Datum", 1,
    "DElay", 2,
	"DEMand", 3,
	"DIsable", 2,
	"EA", 2,
    "EBen", 2,
    "EMulation", 2,
	"ENable", 2,  
	"ER", 2,
    "EVENTAddr", 6,
    "EVENTData", 6,
    "E", 1,
    "F" , 1,
    "FLy", 2,
	"FOrever", 2,
	"FORWard", 4,
	"FRom", 2,
	"G", 1,
	"GLobal", 2,
	"High", 1,      
	"I", 1,
	"INsensitive", 2,
	"IR", 2,
	"IS",  2,
	"Length", 1, 
	"LOw", 2,
	"LV1", 3,
	"LV2", 3,
    "Mixed", 1,
    "MAp", 2,
	"MOdule", 2,
    "MONitor", 3,
    "NOCode", 3,
	"NODemand", 3,
	"NOSymbols", 3, 
	"NOWarn", 3,
    "Number", 1,
	"On", 1,
	"OFf", 2, 
	"OVer", 2,
    "Pio", 1, 
    "R", 1,
	"RAnge", 2,
	"REset", 2, 
	"RET", 3,
	"RUn", 2,  
	"S", 1,
	"SOurce", 2,
    "SPoon", 2,
	"STatus", 2,
	"SYMBOLS", 7,
	"Then", 1,
    "TIll", 2,
	"TIMer", 3,
	"TRace", 2,
	"W", 1,  
	"WArn", 2
};          

//int nMaxArgs = 53;
int nMaxArgs = 74;
*/
BOOL isToupper = TRUE;                
BOOL isStr = FALSE;
BOOL isMultiple = FALSE;

/////////////////////////////////////////////////////////////////////////////
ShellEditor1::ShellEditor1()
{
	m_pszCommand = new char[260];
	m_pszEvent = new char[10];
	memset(m_pszEvent, 0, 10);	
}                           

ShellEditor1::~ShellEditor1()
{
	if (m_pszCommand) {
		delete []m_pszCommand;    
		m_pszCommand = 0;
	}	
	if (m_pszEvent) {
		delete []m_pszEvent;  
		m_pszEvent = 0;
	}	
}


/////////////////////////////////////////////////////////////////////////////
BOOL ShellEditor1::GetFirstToken(void)
{ 
	//m_nLeft = m_nLength - 1;
	m_nLeft = m_nPos-1;
	while (m_nLeft >= 0) {
		if ( ';' == m_pchText[m_nLeft]) {
			m_nLeft++;
			break;
		}         
		else {
			m_nLeft--;
		}	          	
	}                 
	

	if (m_nLeft >= 0) {	
		// skip space
		while (m_nLeft < m_nLength) {
			if ( isspace(m_pchText[m_nLeft])) ++m_nLeft;
			else break;	
		}

		// scan token                              
		m_nRight = m_nLeft;
		while(m_nRight < m_nLength) {
		 	if(!isspace(m_pchText[m_nRight]) && 
		 		';' != m_pchText[m_nRight])	
		 		++ m_nRight;
		 	else break;
		}                                             
		if ( m_nLeft != m_nRight)
			return TRUE;
		else 
			return FALSE;		
	}
	else {
		// Skip heading space
		
		m_nLeft = 0;
		while(m_nLeft < m_nLength) {
		 	if(isspace(m_pchText[m_nLeft]))	++ m_nLeft;
		 	else	break;
		}              
		
		// scan token                              
		m_nRight = m_nLeft;
		while(m_nRight < m_nLength) {
		 	if(!isspace(m_pchText[m_nRight]))	++ m_nRight;
		 	else break;
		}                                             
		
		if(m_nRight == m_nLeft) {	// No token found
			return	FALSE;	
		}            
		
		return	TRUE;	
	}	
}                
   
// return 0:Fail, 1:First token, 2:Not first token   
int ShellEditor1::GetToken(void)
{   
    m_nLeft = m_nPos-1;
	while(m_nLeft > 0) {
		if ( ';' == m_pchText[m_nLeft] ) {
			m_nLeft++;
			break;
		}         
		else {
			m_nLeft--;
		}	   
	}   
 	if ( m_nLeft > 0) {	
 		while (m_nLeft < m_nLength) {
 			if ( isspace(m_pchText[m_nLeft])) 
 				m_nLeft++;
 			else break;	
 		}
 	   
 	
 	/*    
	// Scan left
	m_nLeft = m_nPos;
	while(m_nLeft > 0) {
	 	if(isspace(m_pchText[m_nLeft-1]))	break;
	 	-- m_nLeft;
	}

	//m_nLeft = m_nLength - 1;
	while (m_nLeft >= 0) {
		if ( ';' == m_pchText[m_nLeft] || ' ' == m_pchText[m_nLeft]) {
			m_nLeft++;
			break;
		}         
		else {
			m_nLeft--;
		}	          	
	}                 
	*/
		if (m_nLeft == m_nLength) {	
			return	0;
		}
		else {		
			// scan token                              
			m_nRight = m_nLeft;
			while(m_nRight < m_nLength) {
			 	if(!isspace(m_pchText[m_nRight]) &&
			 		';' != m_pchText[m_nRight])	
			 		++ m_nRight;
			 	else break;
			}
			if ( m_nRight >= m_nPos ) {
				return 1;
			}
			else {
				// Scan left
				m_nLeft = m_nPos;
				while(m_nLeft > 0) {
				 	if(isspace(m_pchText[m_nLeft-1]))	break;
				 	-- m_nLeft;
				}              
				
				// Scan right
				m_nRight = m_nPos;                            
				while(m_nRight < m_nLength-1) {
				 	if(isspace(m_pchText[m_nRight]))	break;
				 	++ m_nRight;
				}               
				return 2;		
			}
				                                             
	    } 
	}
	else {
		// Scan left
		m_nLeft = m_nPos;
		while(m_nLeft > 0) {
		 	if(isspace(m_pchText[m_nLeft-1]))	break;
		 	-- m_nLeft;
		}              
		
		// Scan right
		m_nRight = m_nPos;                            
		while(m_nRight < m_nLength) {
		 	if(isspace(m_pchText[m_nRight]))	break;
		 	++ m_nRight;
		}               
	
		if(m_nLeft == m_nRight || m_nLeft == m_nPos) {	// No token found
			return	0;
		}
		                 
		                 
		// is first token
		int nTemp = 0;
		
		
		while(nTemp < m_nLeft) {
		 	if(!isspace(m_pchText[nTemp])) {	// Found first token
		 		return	2;
		 	}   
		 	++ nTemp;
		}    
		
		return	1;	// First token
	}	
}                                              
/*    
// return -1:No cmd match or can't expand, >=0:Cmd ID    
int ShellEditor1::SearchCommand(void)                           
{

	int nLen = m_nPos - m_nLeft;
	
	for(int i = 0; i < ::nMaxCmdNo; i ++) {
		if(strnicmp(::CommandRecord[i].pszCommandName, m_pchText + m_nLeft,	
			nLen) == 0) {
			if((m_nKeyLen = strlen(::CommandRecord[i].pszCommandName))
				 == nLen) {	// Can't expand
				return	-1;
			}              
			if(nLen >= ::CommandRecord[i].nMinKeyword) {	// Match command
				return	i;			
			}	
		}	
	}                     
	
	return	-1;	// No match;
	
}
        
// return -1:No arg match or can't expand, >=0:arg ID    
int ShellEditor1::SearchArgument(void)                           
{
	int nLen = m_nPos - m_nLeft;
	
	for(int i = 0; i < ::nMaxArgs; i ++) {
		if(strnicmp(::ArgTable[i].m_pszArg, m_pchText + m_nLeft,	
			nLen) == 0) {
			if((m_nKeyLen = strlen(::ArgTable[i].m_pszArg)) == nLen) {
			// Can't expand
				return	-1;
			}              
			if(nLen >= ::ArgTable[i].m_nMin) {	// Match arg
				return	i;			
			}	
		}	
	}                     
	
	return	-1;	// No match;
}
*/        
// will change m_nCmdID depend on current first token        
CString ShellEditor1::GetHints(void)
{   
	// Default no command valid
 	m_nCmdID = -1;
 	
 	CString str("");	// use to hold the hints            
 	                           
	// Get first token 	                           
 	if(!GetFirstToken())	return	str;
	
	int nRet = TestEvent();	
	
	if (nRet == 0 ) {
		char* pszCommand = new char[m_nRight - m_nLeft+2];
		char* pszExpand = new char[21];
		char* pszHints = new char[300];
		int nArgc = 20;
		char* pszArgv[20];
		for ( int i = 0; i < 20; i++ ) {
	        pszArgv[i] = new char[40];
	    }
		
		strncpy( pszCommand, m_pchText + m_nLeft, m_nRight - m_nLeft);
		pszCommand[m_nRight - m_nLeft] = '\0';	
		
		if (m_pchText[m_nRight] == ' ' /*&& m_nPos > m_nRight*/ ) {
			if (::ExpandCommand(pszCommand, pszExpand, pszHints) 
				!= CCommandSet::NO_COMMAND) {   
				if (0 == stricmp(pszExpand, "control")) {
				    CString strReset, strEa, strEben;
				    ::GetControlOption(strReset,strEa,strEben);
                	if (strEben.IsEmpty()) {
    					str = "CONtrol [{Reset|EA}{Enable|Disable}]";
    					strcpy(m_pszCommand, pszExpand);             	
	               	}
                	else {
						str = pszHints; 
						strcpy(m_pszCommand, pszExpand); 
                	} 
				}
				else {
					str = pszHints; 
					strcpy(m_pszCommand, pszExpand); 
				}	
			}
		}
		else {
			if (::SearchCommand(pszCommand, nArgc, pszArgv)) {
				for (int i = 0; i <nArgc; i++) {
					CString strCommand(pszArgv[i]);
					str += strCommand;
					str += ' ';
				} 
			}	
		}    
		
		if (pszCommand) {
			delete []pszCommand;           
			pszCommand = 0;
		}	
		if (pszExpand) {
			delete []pszExpand;
			pszExpand = 0;
		}	
		if (pszHints) {
			delete []pszHints;
			pszHints = 0;
		}	
	    for ( i = 0; i < 20; i++ ) {
	        if ( pszArgv[i] ) {
	            delete []pszArgv[i];
	            pszArgv[i] = 0;
	        }
	    }
	
	}
    //if "Event 1(2,3) ..."
    else { 
    	char* pszHints = new char[300];
    	
    	if (GetEventHints(m_pszEvent, pszHints))
	    	str = pszHints;
	    	
    	delete []pszHints;             
    	pszHints = 0;
    }   
    
	if(str == "") 	//	no match
	str = "No such command";
		
	return	str;	
}               

	/* 	
 	// For "@macroname ..."
 	if (*(m_pchText+m_nLeft) == '@' ) {
 		str = CommandRecord[0].pszHints;
 		m_nCmdID = 0;
 		return str;
 	}

 	// For "$a=1"
 	if (*(m_pchText+m_nLeft) == '$' ) {
 		str = CommandRecord[1].pszHints;
 		m_nCmdID = 1;
 		return str;
 	}
 	 	                  
 	for(int i = 0; i < ::nMaxCmdNo; i ++) {
 	 	if(strnicmp(::CommandRecord[i].pszCommandName, m_pchText + m_nLeft, 
 	 		m_nRight - m_nLeft) == 0) {	// Found match
 	 		if((int)strlen(::CommandRecord[i].pszCommandName) == 
 	 			m_nRight - m_nLeft 
 	 			&& m_pchText[m_nRight] == ' ') {	// exact match
 	 			str = CString(::CommandRecord[i].pszCommandName) +" ";
 	 			str += CString(::CommandRecord[i].pszHints);
 	 			m_nCmdID = i;
 	 			return	str; 	
 	 		} else {  // partial match
 	 			str += ::CommandRecord[i].pszCommandName;
 	 			str += " ";
 	 		}	
 	 	}	
 	}            
 	*/
/*
BOOL ShellEditor1::ExpandCommand(int nCmd)
{
 	ASSERT(nCmd >= 0 && nCmd < ::nMaxCmdNo);                           
 	
 	int nLen = m_nPos - m_nLeft;
 	
 	if(m_isIns)	
 		return	InsString(::CommandRecord[nCmd].pszCommandName + nLen, 
 					m_nKeyLen - nLen);
 	else		
 		return	OvrString(::CommandRecord[nCmd].pszCommandName + nLen, 
 					m_nKeyLen - nLen);						
}                                        
*/
BOOL ShellEditor1::ExpandCommand(void)
{
	char* pszCommand = new char[m_nRight - m_nLeft+2];
	char* pszExpand = new char[21];
	char* pszHints = new char[300];

	int nLen = m_nPos - m_nLeft;
	
	strncpy( pszCommand, m_pchText + m_nLeft, nLen);
	pszCommand[nLen] = '\0';	
    
    int nRet = ::ExpandCommand(pszCommand, pszExpand, pszHints);
	if ( nRet == CCommandSet::COMMAND) {
		int nComLen = strlen(pszCommand);
		int nExpLen = strlen(pszExpand);			
		if ( nExpLen > nComLen ) { 
			if (m_isIns) {
				InsString(pszExpand+nComLen, nExpLen - nComLen);
			}
			else {
				OvrString(pszExpand+nComLen, nExpLen - nComLen);
			}	
		}
		strcpy(m_pszCommand, pszExpand);                                                       		
		if (pszCommand) {
			delete []pszCommand;
			pszCommand = 0;
		}
		if (pszExpand) {
			delete []pszExpand;
			pszExpand = 0;
		}	         
		if (pszHints) {
			delete []pszHints;
			pszHints = 0;
		}
		return TRUE;	
	}
	else if (nRet == CCommandSet::ALIAS) {
		strcpy(m_pszCommand, pszExpand);
		if (pszCommand) {
			delete []pszCommand;
			pszCommand = 0;
		}
		if (pszExpand) {
			delete []pszExpand;
			pszExpand = 0;
		}	         
		if (pszHints) {
			delete []pszHints;
			pszHints = 0;
		}
		return TRUE;
	}              
	else if (nRet == CCommandSet::NO_COMMAND) {
		strcpy(m_pszCommand, pszCommand);      
				if (pszCommand) {
			delete []pszCommand;
			pszCommand = 0;
		}
		if (pszExpand) {
			delete []pszExpand;
			pszExpand = 0;
		}	         
		if (pszHints) {
			delete []pszHints;
			pszHints = 0;
		}
		return TRUE;
    }
	if (pszCommand) {
		delete []pszCommand;
		pszCommand = 0;
	}
	if (pszExpand) {
		delete []pszExpand;
		pszExpand = 0;
	}	         
	if (pszHints) {
		delete []pszHints;
		pszHints = 0;
	}
                
    return FALSE;
}

/*
BOOL ShellEditor1::ExpandArgument(int nArg)
{
 	ASSERT(nArg >= 0 && nArg < ::nMaxArgs);                           
 	
 	int nLen = m_nPos - m_nLeft;
 	
 	if(m_isIns)	return	InsString(::ArgTable[nArg].m_pszArg + nLen, 
 							m_nKeyLen - nLen);
	else		return	OvrString(::ArgTable[nArg].m_pszArg + nLen, 
 							m_nKeyLen - nLen); 							
}                                          
*/

BOOL ShellEditor1::ExpandArgument(void)
{                         
	int nLen = m_nPos - m_nLeft;
	
	char* pszExpand = new char[21];
	char* pszParameter = new char[nLen+2];
	                
	strncpy( pszParameter, m_pchText + m_nLeft, nLen);
	pszParameter[nLen] = '\0';	

 	int nRet = TestEvent();
 	if (nRet == 0) {	    
	    if (::ExpandParameter(m_pszCommand, pszParameter, pszExpand)) {
			int nParLen = strlen(pszParameter);
			int nExpLen = strlen(pszExpand);			
			if ( 0 == stricmp(pszExpand, "eben")) {
			    CString strReset, strEa, strEben;
			    ::GetControlOption(strReset,strEa,strEben);
            	if (!strEben.IsEmpty()) {
					if (m_isIns) {
						InsString(pszExpand + nParLen, nExpLen - nParLen);
					}
					else {
						OvrString(pszExpand + nParLen, nExpLen - nParLen);
					}	
            	}
			}
			else {
				if ( nExpLen > nParLen ) { 
					if (m_isIns) {
						InsString(pszExpand + nParLen, nExpLen - nParLen);
					}
					else {
						OvrString(pszExpand + nParLen, nExpLen - nParLen);
					}	
				}                                                       		
			}	
			if (pszParameter) {
				delete []pszParameter;
				pszParameter = 0;			
			}
			if (pszExpand) {	
				delete []pszExpand;
				pszExpand = 0;
			}	
			return TRUE;	
		}
		else {              
			if (pszParameter) {   
				delete []pszParameter;      
				pszParameter = 0;		
			}		            
			if (pszExpand) {	
				delete []pszExpand;
				pszExpand = 0;
			}	
			return TRUE;
		}        
	}
	else {
		if (ExpandEventPara(m_pszEvent, pszParameter, pszExpand)) {
			int nParLen = strlen(pszParameter);
			int nExpLen = strlen(pszExpand);			
			if ( nExpLen > nParLen ) { 
				if (m_isIns) {
					InsString(pszExpand + nParLen, nExpLen - nParLen);
				}
				else {
					OvrString(pszExpand + nParLen, nExpLen - nParLen);
				}	
			}                                                       		
			if (pszParameter) {   			
				delete []pszParameter;
				pszParameter = 0; 
			}	
			if (pszExpand) {		
				delete []pszExpand;   
	            pszExpand = 0;  
	        }    
			return TRUE;	
		}
		else {                 
			if (pszParameter) {   			
				delete []pszParameter;
				pszParameter = 0; 
			}	
			if (pszExpand) {		
				delete []pszExpand;   
	            pszExpand = 0;  
	        }    
			return TRUE;
		}        
			
	}	
	if (pszParameter) {   			
		delete []pszParameter;
		pszParameter = 0; 
	}	
	if (pszExpand) {		
		delete []pszExpand;   
        pszExpand = 0;  
    }    
    return FALSE;
}

BOOL ShellEditor1::OnSpace(void)
{   
	BOOL is = TRUE;
		
	// Get token at current position
 	int i = GetToken();   

/* 	if(!i) {	// No token
 		goto _SHLNOEXPAND;
 	}	
 	//else if(i == 1) {	// Command
	else if ( isFirstToken || i == 1) {
		i = SearchCommand();
		if(i == -1)	{ // no match 	
		 	goto _SHLNOEXPAND;
		} 
		else if(1 != nAsmFlag ) {
			is = ExpandCommand(i); 
		 	goto _SHLNOEXPAND;
		 	
		}
 	} else  {	// Argument
		i = SearchArgument();
		if(i == -1)	{ // no match 	
		 	goto _SHLNOEXPAND;
		} else if (1 != nAsmFlag ){
			is = ExpandArgument(i); 
		 	goto _SHLNOEXPAND;
		}
 	}        
*/          
	
 	if(!i) {	// No token
 		goto _SHLNOEXPAND;
 	}	
	else if ( /*isFirstToken ||*/ i == 1) {
		if(1 != nAsmFlag ) {
			is = ExpandCommand(); 
		 	goto _SHLNOEXPAND;
		}
 	} else  {	// Argument
		if (1 != nAsmFlag ){
			is = ExpandArgument(); 
		 	goto _SHLNOEXPAND;
		}
 	}        


_SHLNOEXPAND:   
	//Annie, 4/19/96	
    /*
	if ( isFirstToken ) {
		isFirstToken = FALSE;
	}               
    */                              
	if(is) {	
		if(m_isIns)	return ShellEditor::InsChar(' '); 	
		else		return ShellEditor::OvrChar(' '); 	
	} else	return FALSE;
}
    
    
BOOL ShellEditor1::BackChar(void)
{                                       
	// can't do back delete
	if(m_nPos == 0)	return TRUE;
	
	// Record old pos
	int nOld = m_nPos;
	                 
	// Back Delete a space if exist	                 
	if(isspace(m_pchText[m_nPos-1]))	ShellEditor::BackChar();
	
	//only delete a char when after "#" or "$"
	char* pszText = new char[m_nPos+1];
	memset(pszText, 0, m_nPos+1);
	strncpy(pszText, m_pchText, m_nPos);
	CString strLine(pszText);
	delete []pszText;
	
	int nFndWell = strLine.ReverseFind('#');
	int nFndSpace = strLine.ReverseFind(' ');
	int nFndDollar = strLine.ReverseFind('$');
	int nFndSemicolon = strLine.ReverseFind(';');
	BOOL isVar;
    //has no both "$" and "#"
    if (nFndWell == -1 && nFndDollar == -1) {
		// Back delete all lowercase chars
		isVar = FALSE;
    }                        
    //has "#"
    else if (nFndDollar == -1) {     
    	if (nFndSemicolon == -1) {
			if (nFndSpace < nFndWell) 
				isVar = TRUE;	
			else
				isVar = FALSE;
		}	 
		else {
			if (nFndSemicolon > nFndWell )
				isVar = FALSE;
			else
				isVar = TRUE;		      		
		}
    }
    //has "$"
    else if (nFndWell == -1) {     
    	if (nFndSemicolon == -1) {
			if (nFndSpace < nFndDollar) 
				isVar = TRUE;	
			else
				isVar = FALSE;
		}	 
		else {
			if (nFndSemicolon > nFndDollar )
				isVar = FALSE;
			else
				isVar = TRUE;		      		
		}
    }                                           
    //has both "#" and "$"
    else if (nFndWell != -1 && nFndDollar != -1) {
    	if (nFndWell > nFndDollar) {
	    	if (nFndSemicolon == -1) {
				if (nFndSpace < nFndWell) 
					isVar = TRUE;	
				else
					isVar = FALSE;
			}	 
			else {
				if (nFndSemicolon > nFndWell )
					isVar = FALSE;
				else
					isVar = TRUE;		      		
			}
    	}
    	else {
	    	if (nFndSemicolon == -1) {
				if (nFndSpace < nFndDollar) 
					isVar = TRUE;	
				else
					isVar = FALSE;
			}	 
			else {
				if (nFndSemicolon > nFndDollar )
					isVar = FALSE;
				else
					isVar = TRUE;		      		
			}
    	}
	}
	else {                      
		isVar = FALSE;			
	}
	if ( isVar == FALSE ) {		
		// Back delete all lowercase chars
		while(m_nPos > 0) {
		 	if(islower(m_pchText[m_nPos-1])) {
				ShellEditor::BackChar();
		 	} else break;
		}
	}                      
	else                                        
		ShellEditor::BackChar();
		                                  
	// if nothing deleted, back delete any char	                                  
	if(nOld == m_nPos)	ShellEditor::BackChar();
	
	return TRUE; 	
}           
                
BOOL ShellEditor1::DelChar(void)
{
	return ShellEditor::DelChar(); 	
}                     

BOOL ShellEditor1::InsChar(char ch)
{                        
	m_isIns = TRUE;
	//Add by Annie, 3/28/96	                             
	//if(ch == ' ')	return OnSpace();
    //else return ShellEditor::InsChar((char)toupper(ch));

    	//Annie, 4/19/96
	if ( ch == ';') {
		isFirstToken = FALSE;
		isMultiple = TRUE;
		//}
	}    	
	else if ( ch != ' ' ) {
		if (isMultiple == TRUE) {
			isMultiple = FALSE;
			isFirstToken = TRUE;
			isToupper = TRUE;
		}
    }

	if (ch == ' ' && isToupper == TRUE) {
		return OnSpace();                  
	}	
	else if (ch == ' ' && isToupper == FALSE && isStr == FALSE) {
		isToupper = TRUE;
		return OnSpace();
	}	                   	
	if(ch == '#' ) {
		isToupper = FALSE;	
	}
	else if ( ch == '$' ) {
		isToupper = FALSE;			
	}
	else if (ch == '\"') {
		isToupper = FALSE;
		isStr = TRUE;
	}	
    //if (m_nRight > m_nLeft) {
    //if (m_nPos < m_nLength) {
        //char* p = new char[strlen(m_pchText)];
		char* p = new char[m_nPos+2];
		strncpy(p, m_pchText, m_nPos);
		p[m_nPos] = '\0';
		CString str(p);
        //str = str.Left(m_nPos);
		int nFndWell = str.ReverseFind('#');
		int nFndQuotation = str.ReverseFind('\"');
		int nFndDollar = str.ReverseFind('$');
		if ( nFndWell != -1 && nFndDollar == -1) {
			if (nFndWell < m_nPos) {
				//str = str.Left(m_nPos);
				int nFndSpace = str.ReverseFind(' ');
				if ( nFndSpace != -1 ) {
					if ( nFndSpace < nFndWell ) {
						isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}
				else {
					int nFndSemicolon = str.ReverseFind(';');
					if ( nFndSemicolon < nFndWell) {
				    	isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}	 
			}
		}
		if ( nFndQuotation != -1) {                                
			if (nFndQuotation < m_nPos) {
				int nFndSpace = str.ReverseFind(' ');
				if ( nFndSpace != -1 ) {
					if ( nFndSpace < nFndQuotation ) {
						isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}
				else {
					int nFndSemicolon = str.ReverseFind(';');
					if ( nFndSemicolon < nFndQuotation) {
				    	isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}	 
			}
		}
		if ( nFndDollar != -1 && nFndWell == -1) {                                		                                
			if (nFndDollar < m_nPos) {
				int nFndSpace = str.ReverseFind(' ');
				if ( nFndSpace != -1 ) {
					if ( nFndSpace < nFndDollar ) {
						isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}
				else {
					int nFndSemicolon = str.ReverseFind(';');
					if ( nFndSemicolon < nFndDollar) {
				    	isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}	 
			}
		}                                   
		if (nFndDollar != -1 && nFndWell != -1) {                                		                                
			if (nFndDollar > nFndWell ) {
				if (nFndDollar < m_nPos) {
					int nFndSpace = str.ReverseFind(' ');
					if ( nFndSpace != -1 ) {
						if ( nFndSpace < nFndDollar ) {
							isToupper = FALSE;				
						}
						else {
						    isToupper = TRUE;
						}
					}
					else {
						int nFndSemicolon = str.ReverseFind(';');
						if ( nFndSemicolon < nFndDollar) {
					    	isToupper = FALSE;				
						}
						else {
						    isToupper = TRUE;
						}
					}	 
				}
			}
			else {
				if (nFndWell < m_nPos) {
					//str = str.Left(m_nPos);
					int nFndSpace = str.ReverseFind(' ');
					if ( nFndSpace != -1 ) {
						if ( nFndSpace < nFndWell ) {
							isToupper = FALSE;				
						}
						else {
						    isToupper = TRUE;
						}
					}
					else {
						int nFndSemicolon = str.ReverseFind(';');
						if ( nFndSemicolon < nFndWell) {
					    	isToupper = FALSE;				
						}
						else {
						    isToupper = TRUE;
						}
					}	 
				}
			}
		}
		if (nFndWell == -1 && nFndQuotation == -1 && nFndDollar == -1) {
			isToupper = TRUE;
		}
		delete []p;	                 
		p = 0;
	//}          
    if (isToupper == TRUE)
		return ShellEditor::InsChar((char)toupper(ch)); 	
	else {
        //isToupper = TRUE;
		return ShellEditor::InsChar(ch); 		
	}	
}           

BOOL ShellEditor1::OvrChar(char ch)
{
	m_isIns = FALSE;
	                             
	//Add by Annie, 3/28/96
	//if(ch == ' ')	return OnSpace();                       
	//else return ShellEditor::OvrChar((char)toupper(ch)); 	
    
    	//Annie, 4/19/96
	if ( ch == ';') {
		isFirstToken = FALSE;
		isMultiple = TRUE;
		//}
	}    	
	else if ( ch != ' ' ) {
		if (isMultiple == TRUE) {
			isMultiple = FALSE;
			isFirstToken = TRUE;
			isToupper = TRUE;
		}
	}		

	if (ch == ' ' && isToupper == TRUE) {
		return OnSpace();                  
	}	
	else if (ch == ' ' && isToupper == FALSE && isStr == FALSE) {
		isToupper = TRUE;
		return OnSpace();
	}	                   	
	if(ch == '#') {
		isToupper = FALSE;	
	}             
	else if ( ch == '$' ) {
		isToupper = FALSE;			
	}
	else if (ch == '\"') {
		isToupper = FALSE;
		isStr = TRUE;
	}
	//if (strlen(m_pchText) != 0) {
	//if (m_nRight > m_nLeft) {
	//if (m_nPos < m_nLength) {
		//char* p = new char[strlen(m_pchText)];
		char* p = new char[m_nPos+2];
		strncpy(p, m_pchText, m_nPos);
		p[m_nPos] = '\0';
		CString str(p);
		//str = str.Left(m_nPos);
		int nFndWell = str.ReverseFind('#');
		int nFndQuotation = str.ReverseFind('\"');
		int nFndDollar = str.ReverseFind('$');
		if ( nFndWell != -1 && nFndDollar == -1 ) {
			if (nFndWell < m_nPos) {
				//str = str.Left(m_nPos);
				int nFndSpace = str.ReverseFind(' ');
				if ( nFndSpace != -1 ) {
					if ( nFndSpace < nFndWell ) {
						isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}
				else {
					int nFndSemicolon = str.ReverseFind(';');
					if ( nFndSemicolon < nFndWell) {
				    	isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}	 
			}
		}
		if ( nFndQuotation != -1) {                                
			if (nFndQuotation < m_nPos) {
				int nFndSpace = str.ReverseFind(' ');
				if ( nFndSpace != -1 ) {
					if ( nFndSpace < nFndQuotation ) {
						isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}
				else {
					int nFndSemicolon = str.ReverseFind(';');
					if ( nFndSemicolon < nFndQuotation) {
				    	isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}	 
			}
		}
		if ( nFndDollar != -1 && nFndWell == -1 ) {                                		                                
			if (nFndDollar < m_nPos) {
				int nFndSpace = str.ReverseFind(' ');
				if ( nFndSpace != -1 ) {
					if ( nFndSpace < nFndDollar ) {
						isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}
				else {
					int nFndSemicolon = str.ReverseFind(';');
					if ( nFndSemicolon < nFndDollar) {
				    	isToupper = FALSE;				
					}
					else {
					    isToupper = TRUE;
					}
				}	 
			}
		}    
		if (nFndDollar != -1 && nFndWell != -1) {                                		                                
			if (nFndDollar > nFndWell ) {
				if (nFndDollar < m_nPos) {
					int nFndSpace = str.ReverseFind(' ');
					if ( nFndSpace != -1 ) {
						if ( nFndSpace < nFndDollar ) {
							isToupper = FALSE;				
						}
						else {
						    isToupper = TRUE;
						}
					}
					else {
						int nFndSemicolon = str.ReverseFind(';');
						if ( nFndSemicolon < nFndDollar) {
					    	isToupper = FALSE;				
						}
						else {
						    isToupper = TRUE;
						}
					}	 
				}
			}
			else {
				if (nFndWell < m_nPos) {
					//str = str.Left(m_nPos);
					int nFndSpace = str.ReverseFind(' ');
					if ( nFndSpace != -1 ) {
						if ( nFndSpace < nFndWell ) {
							isToupper = FALSE;				
						}
						else {
						    isToupper = TRUE;
						}
					}
					else {
						int nFndSemicolon = str.ReverseFind(';');
						if ( nFndSemicolon < nFndWell) {
					    	isToupper = FALSE;				
						}
						else {
						    isToupper = TRUE;
						}
					}	 
				}
			}
		}
		if (nFndWell == -1 && nFndQuotation == -1 && nFndDollar == -1) {
			isToupper = TRUE;
		}
		delete []p;	                 
		p = 0;
	//}          
	
	if (isToupper == TRUE)
		return ShellEditor::OvrChar((char)toupper(ch)); 	
	else {   
	    //isToupper = TRUE;
	    return ShellEditor::OvrChar(ch); 	
	}    
}                         

int ShellEditor1::TestEvent(void)
{
	char* pszBuf = new char[m_nPos+2];	
	for (int i=0 ; i<m_nPos; i++) {
		pszBuf[i] = m_pchText[i];	
	}                            
	pszBuf[i] = '\0';

	CString strBuf(pszBuf);
	delete []pszBuf;	
	pszBuf = 0;
	if (strBuf.Find(';') == -1) {		
		strBuf.TrimLeft();
		strBuf.MakeLower();
		if (strBuf.Find("event") == 0 ) {
	    	strcpy(m_pszEvent, "Event");
	    	strcat(m_pszEvent, " ");
			int nLen = strBuf.GetLength();
			if (nLen >= 8) {
				CString str = strBuf.Right(nLen -5);
				str.TrimLeft();
				if (str[0] == '1' && str[1] == ' ') {
					strcat(m_pszEvent, "1");
					return 1;                        
				}	
				else if (str[0] == '2' && str[1] == ' ') {
					strcat(m_pszEvent, "2");
					return 2;                             
				}	
				else if (str[0] == '3' && str[1] == ' ') {
					strcat(m_pszEvent, "3");
					return 3;	                          
				}	
				else
					return 0;	
			}
			else 
				return 0;		
		}	    
		else {
			return 0;		
		}
	}	               
	else {
		int nPos = strBuf.ReverseFind(';');
		CString str1 = strBuf.Right(strBuf.GetLength()-nPos-1);	
		str1.TrimLeft();
		str1.MakeLower();
		if (str1.Find("event") == 0 ) {
	    	strcpy(m_pszEvent, "Event");
	    	strcat(m_pszEvent, " ");
			int nLen = str1.GetLength();
			if (nLen >= 8) {
				CString str = strBuf.Right(nLen -5);
				str.TrimLeft();
				if (str[0] == '1' && str[1] == ' ') {
					strcat(m_pszEvent, "1");
					return 1;                        
				}	
				else if (str[0] == '2' && str[1] == ' ') {
					strcat(m_pszEvent, "2");
					return 2;                             
				}	
				else if (str[0] == '3' && str[1] == ' ') {
					strcat(m_pszEvent, "3");
					return 3;	                          
				}	
				else
					return 0;	
			}
			else 
				return 0;		
		}	    
		else {
			return 0;		
		}
	
	}
}