/*------------------------------------------------------------------------------*
 * File Name: CmdControl.h														*
 * Creation: CPY 7/30/05														*
 * Purpose: Script Window for LT commands				 						*
 * Copyright (c) OriginLab Corp.	2005										*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	CPY 8/3/05 KEY_UP_DOWN_BUFFER												*
 *	CPY 8/10/05 CMD_BUFFER_MOVED_TO_CMD_CONTROL									*
 *	DSC 8/11/05 QA70-7974 ADD_TO_OC_RICHEDIT_CTR								*
 *	CPY 8/17/05 AUTO_COMPLETE_HOOK												*
 *	CPY 9/9/05 AUTO_COMPLETE_OBJ												*
 *  Jasmine 9/16/05 START_BY_RIGHT_ARROW										*
 *	CPY 9/18/05 XF_CMD_UPDATE_LIST_UPON_CHANGING_XF_NAME						*
 *	Jasmine 09/26/05 AUTO_COMPLETE_POP_UP_MENU									*
 *  Iris 9/28/05 ADD_NEW_LINE_BEFORE_SHOW_PROMPT								*
 *	CPY 10/30/05 BACK_SPACE_TO_CLOSE_AND_RESET_AUTO_COMPLETE_WHEN_PASSED_STARTING_PT
 *	Jasmine 03/24/06 QA70-7998 v8.0378 MOVE_TO_CMD_CONTROL_H					*
 *  Joe  4/24/06  SET_NORMAL_TIME_PATH_PROMPT                                   *
 *  Joe  5/10/06  BACKSPACE_SHOW_AUTOCOPLETE                                    *
 *  Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS                                    *
 *  Joe  5/23/06  SPLITTER_HORIZONTALLY_VERTICALLY                              *
 *  Joe  6/13/06  QA70-8601 DOWN_KEY_FUCNTION                                   *  
 *  Joe  6/14/06  QA70-8601 P6 ON_PASTE_PROMPT_HIDE                             *
 *  Joe  7/11/06  AUTOCOMPLETE_GLOBALFUNCTION_USED                              *
 *  Joe  7/18/06  UP_DOWN_KEY_SHOW												*
 *  Joe  7/19/06  ON_ENTER_LAST_CMD_EXECUTED                                    *   
 *  Joe  7/24/06  ON_BACK_DELETE_CHINESE_CHARACTER                              *
 *  Joe  8/24/06  ADD_PREFENCE_ON_CONTEXT_MENU									*	
 *	Joe  8/29/06  ROLLBACK_AND_MODIFY_UPDOWN_KEY								*	
 *	Joseph 12/02/06	UPDOWN_KEY_LOAD_HISTORY										*
 *	Joseph 01/25/07 SUPPORT_HOME_END_KEY										*
 *	CPY 4/11/06 HIDE_DEBUG_MSG													*
 *	Folger 08/22/08 QA80-11966 FIX_RUNTIME_ERROR_IN_COMMAND_WINDOW_CAUSED_BY_STRING_GET_TOKENS
 *	Sophy 2/26/2010 QA81-12697-P1 OC_OUTPUT_TO_CMD_WND_SHOULD_FOLLOW_TARGET_FONT_SETTINGS
 *------------------------------------------------------------------------------*/
#ifndef _CMD_CONTROL_H
#define _CMD_CONTROL_H

//#include "ACBase.h"       ///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS

enum {REPOS_UNEDITABLE = 1, REPOS_PARTEDITABLE, REPOS_EDITABLE};  //Selection range status 
///Joe  8/24/06    ADD_PREFENCE_ON_CONTEXT_MENU
//enum{AUTOCOMPLETE_OFF = 0, AUTOCOMPLETE_ON, AUTOCOMPLETE_BY_CMD};///Jasmine 9/16/05 START_BY_RIGHT_ARROW	///Jasmine 09/26/05 AUTO_COMPLETE_POP_UP_MENU
enum{AUTOCOMPLETE_BY_CMD, AUTOCOMPLETE_OFF , AUTOCOMPLETE_ON};///Jasmine 9/16/05 START_BY_RIGHT_ARROW	///Jasmine 09/26/05 AUTO_COMPLETE_POP_UP_MENU
///End ADD_PREFENCE_ON_CONTEXT_MENU
enum {SHOW_NORMAL = 0, SHOW_TIME, SHOW_PATH};  ///Joe  4/24/06  SET_NORMAL_TIME_PATH_PROMPT    add the PromptState type;
enum {HISTORY_PANE_LEFT = 0, HISTORY_PANE_RIGHT, HISTORY_PANE_TOP, HISTORY_PANE_BOTTOM, HISTORY_PANE_NONE}; ///Joseph	05/23/06  SPLITTER_HORIZONTALLY_VERTICALLY
#define MAX_CMD_BUFFER	25 //CPY 8/10/05 CMD_BUFFER_MOVED_TO_CMD_CONTROL
#define STR_UPDOWN_KEY_BUFFERFILE	GetAppPath(0) + "UpDown_Buffer.txt"		///Joseph 12/02/06	UPDOWN_KEY_LOAD_HISTORY
#define	BUFFER_FILE_MAXSIZE	2000		///Joseph 12/02/06	UPDOWN_KEY_LOAD_HISTORY
//#define CMDKEY_OPEN_AUTO_COMPLETE	((UINT)(-1))  ///Joe  7/11/06  AUTOCOMPLETE_GLOBALFUNCTION_USED

//enum { UN_CCSA_RIGHT_ARROW = 0, CCSA_RIGHT_ARROW}; ///Jasmine 9/16/05 START_BY_RIGHT_ARROW	///Jasmine 09/26/05 AUTO_COMPLETE_POP_UP_MENU

class CmdControl : public RichEditEx
{
public:
	CmdControl()
	{
		m_nPromptPosition = -1;//CPY
		m_nHistoryIndex = 0; //--- CPY 8/10/05 CMD_BUFFER_MOVED_TO_CMD_CONTROL
		//---- CPY 8/17/05 AUTO_COMPLETE_HOOK
		//m_nAutoCompleteStart = -1;    ///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS
		/*	Jasmine 09/26/05 AUTO_COMPLETE_POP_UP_MENU
		m_bAutoCompleteOn = true;
		m_nStartAutoCompleteBy = UN_CCSA_RIGHT_ARROW;///Jasmine 9/16/05 START_BY_RIGHT_ARROW
		*/		
		//m_nAutoCompleteState = AUTOCOMPLETE_ON;	///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS
		///End AUTO_COMPLETE_POP_UP_MENU
		m_nPromptState = SHOW_NORMAL;   ///Joe  4/24/06  SET_NORMAL_TIME_PATH_PROMPT    Set the PromtState SHOW_NORMAL 
		//m_pACobj = NULL;           ///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS
		//m_bAutocompletBackSpace = false;  ///Joe  5/10/06  BACKSPACE_SHOW_AUTOCOPLETE  ///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS
		//----
	}
	virtual void 	OnSetFocus() {out_str("do nothing");}	
protected:
	virtual string 	GetPrompt() { return ">>"; }
	virtual bool	GetPromptColor(COLORREF& cr, bool& bBold, bool& bUnderline, bool& bStrikeOut) {return false;}
	virtual void OnCmd(const string& strCmd, bool bAddNewLine = true) ///Iris  8/09/05 change to public, need call this outside
	{
		string str = strCmd;
		str += ": not implemented";
		if(bAddNewLine)
			WriteLine();
			
		WriteLine(str);
		ShowPrompt();
	}	
public:	
	virtual bool OnEnterKey(int nStart, int nEnd)
	{
		string strCmd = GetCmdLine();
		//------- CPY 8/13/05 EXECUTE_HISTORY_NEEDED_TO_ADD_TO_HISTORY
//		WriteLine();
//		OnCmd(strCmd);
//		AddCmdBuffer(strCmd); //CPY 8/10/05 CMD_BUFFER_MOVED_TO_CMD_CONTROL 
//		ShowPrompt();
		OnCmd(strCmd);
		//AddCmdBuffer(strCmd);      ///Joe  7/18/06  UP_DOWN_KEY_SHOW
		//-------
		return TRUE;
	}
	virtual bool OnUpKey()
	{
		///Joseph 01/25/07 SUPPORT_HOME_END_KEY
		string strGetSel = GetCmdLine();
		int nIndex = strGetSel.Find("\n");
		if(nIndex > 0)
		{
			return true;
		}
		///End SUPPORT_HOME_END_KEY
		string strNewCmd;
		if(getCmdBuffer(strNewCmd, false))
			ReplaceAfterPrompt(strNewCmd);
		return true;
	}
	
	virtual bool OnDownKey()
	{
		///Joe 06/13/06 QA70-8601 DOWN_KEY_FUCNTION
		//---
		//if(IsInAutoCompleteMode())
			//return false; 
		//---
		///End DOWN_KEY_FUCNTION
		string strNewCmd;
		if(getCmdBuffer(strNewCmd, true))
			ReplaceAfterPrompt(strNewCmd);
		return true;
	}	
	///Joseph 01/25/07 SUPPORT_HOME_END_KEY
	virtual bool OnHomeKey()
	{
		int nStart, nEnd;
		int nCount = GetSel(nStart, nEnd);
	
		if(SHIFT_DOWN)
		{
			SetSel(m_nPromptPosition,nStart);
		}
		else
			SetSel(m_nPromptPosition, m_nPromptPosition);
		return true;
	}
	
	virtual bool OnEndKey()
	{
		int nStart, nEnd;
		int nCount = GetSel(nStart, nEnd);
		SetSel(0,-1);
		string strTemp = GetSelText();
		int nEditEnd = strTemp.GetLength();
		if(SHIFT_DOWN)
		{
			SetSel(nStart,nEditEnd);
		}
		else
			SetSel(nEditEnd,nEditEnd);
		return true;
	}
	///End SUPPORT_HOME_END_KEY
	virtual bool OnOpen()
	{
		string strPath;
		StringArray saFiletypes;
		saFiletypes.SetSize( 2 );
		saFiletypes[0]="[Text File (*.txt)] *.txt";
		saFiletypes[1]="[Origin LabTalk Script File (*.ogs)] *.ogs";
		strPath = GetOpenBox( saFiletypes, GetAppPath(false) );
		if(strPath.IsEmpty())
			return false;
		
		if(Load(strPath))
			m_strPath = strPath;
			
		return false;
	}	
	//-- CPY 8/9/05 AFTER_TD_MOVE_SAVE_TO_VC_LEVEL
	// we may need to rewrite this, right now, it is assumed that with selection, only sel is saved, but if no sel, whole file is saved, 
	// we really should enabled diff menu based on sel and when it comes to here, it should be very clear if saving sel or saving whole file
	/*
	virtual bool OnSave()
	{		
		bool 	bSaveAll = true;
		string 	str = GetSelText();		
		if( !str.IsEmpty() ) 
			bSaveAll = false; //save selected text
		
		return Save(m_strPath, bSaveAll);
	}
	*/
	virtual bool OnSave(LPCSTR lpscFileType = NULL)
	{
		string strFilename = lpscFileType;
		if(strFilename.IsEmpty())
			strFilename = m_strPath;
		if(strFilename.IsEmpty())
			return error_report("OnSave found empty filename");
		
		string 	str = GetSelText();		
		if( str.IsEmpty() )
		{
			if(Save(strFilename))
			{
				m_strPath = strFilename; // update internal filename only if the whole thing is saved into a file, selection saving should not change internal filename
				return true;
			}
		}
		return SaveSelection(strFilename);
	}
	//-- end CPY 8/9/05
	virtual bool OnSaveAs(LPCSTR lpscFileType = NULL)
	{
		string strPath;
		string strFileType(lpscFileType);
		if(strFileType.IsEmpty())
			strFileType = "[Text File (*.txt)] *.txt";
		
		StringArray saFiletypes;
		saFiletypes.SetSize( 1 );
		//saFiletypes[0]="[TEXT FILE (*.TXT)] *.TXT";
		saFiletypes[0] = strFileType;
		strPath = GetSaveAsBox( saFiletypes, GetAppPath(false) );
		//---- CPY 8/9/05 AFTER_TD_MOVE_SAVE_TO_VC_LEVEL
		/*
		bool 	bSaveAll = true;
		string 	str = GetSelText();		
		if( !str.IsEmpty() ) 
			bSaveAll = false; //save selected text
		
		if(Save(strPath, bSaveAll))
			m_strPath = strPath;
		
		return false;
		*/
		if(strPath.IsEmpty())
			return false; // user cancel
		return OnSave(strPath);
	}
	
	virtual bool OnClear()
	{
		string str = GetSelText();
		if(str.IsEmpty()) //clear all
		{			
			if(IDOK == MessageBox(GetSafeHwnd(), _L("Are you sure?"), GetDlgName(), MB_OK|MB_OKCANCEL|MB_ICONQUESTION)) // --- Iris 8/08/05 SHOW_MB_BEFORE_CLEAR
				Reset();
		}
		else
		{
			ReplaceSel("");
			MoveToEnd();
		}
		return false;
	}

	///Joe  6/14/06    QA70-8601 P6 ON_PASTE_PROMPT_HIDE
	void OnPaste()
	{
		if(!OpenClipboard(NULL))
			return;
		string str;
		if(IsClipboardFormatAvailable(CF_TEXT))     //delete the "<<" on the clipboard
		{
			HANDLE hData = GetClipboardData(CF_TEXT);
			LPCSTR lpData = (LPCSTR)GlobalLock(hData);
			str = lpData;
			str.Replace(">>","");
			GlobalUnlock(hData);
			out_str(str);
		}
		else
			out_str("No Text in clipboard");
		
		int nMemSize = str.GetLength() + 1;// need terminating zero
		HANDLE hData = GlobalAlloc(GHND,nMemSize);
		LPSTR lpData = (LPSTR)GlobalLock(hData);
		lstrcpyn(lpData, str, nMemSize);
		GlobalUnlock(hData);
		EmptyClipboard();
		SetClipboardData(CF_TEXT,hData);	
		CloseClipboard();
		Paste();
	}
	///End ON_PASTE_PROMPT_HIDE
	virtual bool OnCut()
	{
		Copy();
		ReplaceSel("");
		return true;
	}
	// ---
	
	// --- Iris 8/08/05 SHOW_MB_BEFORE_CLEAR
	virtual string GetDlgName()
	{
		return m_strDlgName;
	}
	
	void SetDlgName(LPCSTR lpcsName)
	{
		m_strDlgName = lpcsName;
	}
	// ---
	virtual void ShowPrompt()
	{
		string strPrompt = GetPrompt();
		/// Iris 9/28/05 ADD_NEW_LINE_BEFORE_SHOW_PROMPT
		//sometimes function print text without \n, prompt will not local at the start of line
		if( str_end_char(Text) != '\n' && !Text.IsEmpty() ) 
			WriteLine();
		///End ADD_NEW_LINE_BEFORE_SHOW_PROMPT
		Write(strPrompt);
		int nStart;
		GetSel(nStart, m_nPromptPosition); //Record the position of latest prompt
		nStart = m_nPromptPosition - strPrompt.GetLength();
		int nEnd = m_nPromptPosition;
		COLORREF cr;
		bool bBold, bUnderline, bStrikeout;
		if(GetPromptColor(cr, bBold, bUnderline, bStrikeout))
		{
			SetTextColor(nStart, nEnd, cr);
			if(bBold || bUnderline || bStrikeout)
			{
				CHARFORMAT cf = {0};
				if(bBold)
					cf.dwEffects = CFE_BOLD,  cf.dwMask = CFM_BOLD;
				if(bUnderline)
					cf.dwEffects |= CFE_UNDERLINE, cf.dwMask |= CFM_UNDERLINE;
				if(bStrikeout)
					cf.dwEffects |= CFE_STRIKEOUT, cf.dwMask |= CFM_STRIKEOUT;
					
				SetSelectionCharFormat(cf);// SetTextColor above already set Sel, so we can just continue
			}
		}
		MoveToEnd(true);
		OnShowPrompt();//---- CPY 9/9/05 AUTO_COMPLETE_OBJ

	}
	
	/// Iris 8/26/05 DISABLE_CUT_CLEAR_MENU_IF_NOT_EDITABLE
	bool IsEditable()
	{
		int nStart, nEnd;
		if( REPOS_EDITABLE == GetSelCheckPos(nStart, nEnd) )
			return true;
		return false;
	}
	///End DISABLE_CUT_CLEAR_MENU_IF_NOT_EDITABLE
	
	///Joseph 12/02/06	UPDOWN_KEY_LOAD_HISTORY
	void LoadFileToCmdBuffer()
	{
		FILE* stdFILE;
		if(stdFILE = fopen(STR_UPDOWN_KEY_BUFFERFILE, "r"))
		{
			char cBuffer[BUFFER_FILE_MAXSIZE];
	
			fread(cBuffer, sizeof(char), BUFFER_FILE_MAXSIZE, stdFILE);
			
			string strBuffer(cBuffer, BUFFER_FILE_MAXSIZE);
			
			str_separate(strBuffer, "\r\n", m_vsCmdBuffer);
			fclose(stdFILE);
		}				
	}
	
	void SaveBuffertoFile()
	{
		int nSize = m_vsCmdBuffer.GetSize();
		for(int ii = 0; ii < (nSize - 1); ii++)
		{
			if(! m_vsCmdBuffer[ii].CompareNoCase(m_vsCmdBuffer[ii+1]))
			{
				m_vsCmdBuffer.RemoveAt(ii);
				ii--;
			}
			nSize = m_vsCmdBuffer.GetSize();
		}
		string strCmdBuffer = str_combine(m_vsCmdBuffer, "\r\n");
		FILE* FILEBuffer;
		if(FILEBuffer = fopen(STR_UPDOWN_KEY_BUFFERFILE, "w"))
		{
			fwrite(&strCmdBuffer, sizeof(char), strCmdBuffer.GetLength(), FILEBuffer);
			fclose(FILEBuffer);
		}
	}
	///End UPDOWN_KEY_LOAD_HISTORY
	
	//---- CPY 8/17/05 AUTO_COMPLETE_HOOK
	// nStart<0 to clear
	// nCurrent < 0 assume already up and just to update
	///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS
	//virtual void OnAutoComplete(int nStart= -1 , int nCurrent = -1, UINT nCharCmd = 0);
	//virtual void OnAutoCompleteClose(Window& wndToNotify, int nStart, int nEnd){};
	//virtual bool OnAutoCompleteGetHelpInfo(int nIconID, LPCSTR lpcszSrc, string& strDisplay);
	//virtual bool OnAutoCompleteDoneReplaceSel(int nStart, int nEnd);
	//void CloseAutoComplete()
	//{
		//DebugMsg("CloseAutoComplete");
		//vector<string> vsNames;
		//AutoComplete(-1, vsNames);	// to close autocomplete window
	//}
	//void ResetAutoComplete();
	///End AUTOCOMPLETE_CONTROL_CLASS
protected:
	// ---Iris 8/05/05 ADD_CONTEXT_MENU
	virtual void Reset()
	{
		Text  = "";
		SetSel(-1,-1);
		ShowPrompt();
	}
	// ---
	

	///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS
    //bool IsInAutoCompleteMode() { return m_nAutoCompleteStart >=0? true:false;}
     virtual bool IsInAutoCompleteMode(){ return false; }
    ///End AUTOCOMPLETE_CONTROL_CLASS
     
	//----
//---- CPY 8/17/05 AUTO_COMPLETE_HOOK
	virtual void OnShowPrompt(){}//---- CPY 9/9/05 AUTO_COMPLETE_OBJ
	///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS
	//virtual bool CheckStartAutoComplete(UINT nCharCmd, int nStart, int nEnd)
	//{
		//if( IsInAutoCompleteMode() )
		//{
			//OnAutoComplete(m_nAutoCompleteStart, -1, nCharCmd);
			//return true;
		//}
//
		//if(IsCharStartAutoComplete(nCharCmd))
		//{
			//OnAutoComplete(m_nPromptPosition, nStart, nCharCmd);
			//return true;
		//}
		//
		//return false;
	//}
	//virtual bool IsCharStartAutoComplete(UINT nCharCmd);
	///End AUTOCOMPLETE_CONTROL_CLASS
//---- end CPY 8/17/05 AUTO_COMPLETE_HOOK
///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS
//private:
protected:
///End AUTOCOMPLETE_CONTROL_CLASS
	//----------- CPY 8/23/05 added check for VK_CONTROL
	bool IsCntrlOrCntrlC(UINT msg, UINT wParam, UINT lParam)
	{
		if(wParam == VK_CONTROL)
			return true;
		if(wParam < VK_MBUTTON)
			return true; // for some reason, seeing a VK_CANCEL
		//string str;
		if(wParam == 'C' && CNTRL_DOWN)
		{
			//str.Format("cntrl = %d, msg = %d, lParam = %d", CNTRL_DOWN?1:0, msg, lParam);
			//SetStatusBarText(str);
			return true;
		}
		//str.Format("key = %d, msg = %d, lParam = %d", wParam, msg, lParam);
		//SetStatusBarText(str);
		return false;
	}
	//----------- 
public:
	virtual void OnInit()
	{
		/// Iris 2/05/06 v8.0364 QA70-7892 RESET_FONT_AFTER_PASTE
		//SetFont(ANSI_FIXED_FONT);
		SetFont(GetFont());
		///End RESET_FONT_AFTER_PASTE
		LimitText(200 * 1024); //200K might still need to make bigger later

		ShowPrompt();
	}
	/// Iris 2/05/06 v8.0364 QA70-7892 RESET_FONT_AFTER_PASTE
	virtual int GetFont()
	{
		return ANSI_FIXED_FONT;
	}
	
	void ResetFontAfterPaste()
	{
		//select the pasted text
		int nBegin = m_nPromptPosition + lstrlen(GetPrompt());
		out_int("", nBegin);
		
		SetSel(nBegin, -1);
		
		//set font
		SetFont(GetFont());
		
		//cancel selection
		SetSel(-1, -1);
		
	}
	///End RESET_FONT_AFTER_PASTE
	
	///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS 
	virtual bool  OnNotCmdKey(UINT msg, UINT wParam, UINT lParam, int nStart, int nEnd, int nSel){return false;}	
	
	virtual void  OnBackSpaceCmd(int nEnd){}
	
	virtual bool  OnLeftRightCmd(int nStart, int nEnd, UINT wParam){return false;}
	///End AUTOCOMPLETE_CONTROL_CLASS
	// return true to execute command
	bool OnKeyCmd(UINT msg, UINT wParam, UINT lParam)
	{
		int nStart, nEnd;
		int nSel = GetSelCheckPos(nStart, nEnd);
		
#ifdef _SHOW_DEBUG_INFO
		m_nLastKey = wParam;
		m_nLastKeyPos = nEnd;
#endif		
		if( !IsCmdKey(wParam) )
		{
			if( nSel != REPOS_EDITABLE && !IsCntrlOrCntrlC(msg, wParam, lParam)) //--CPY 8/23/05 added check for VK_CONTROL, otherwise cntrl-C will not work when trying to copy from earlier code in command window
				MoveToEnd();			
			///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS 
			//---- CPY 8/17/05 AUTO_COMPLETE_HOOK
			//if(IsAutoCompleteOn())///Jasmine 09/26/05 AUTO_COMPLETE_POP_UP_MENU
			//if(GetAutoCompleteState() == AUTOCOMPLETE_ON)
			//{
				//if(wParam == VK_ESCAPE)
				//{
					//if(IsInAutoCompleteMode())
					//{
						/////Joe  5/10/06  BACKSPACE_SHOW_AUTOCOPLETE
						////ResetAutoComplete();// to close AutoComplete on Esc						
						//OnAutoComplete();
						/////End BACKSPACE_SHOW_AUTOCOPLETE
					//}
					//return true;// esc key will otherwise mess up dialog, so always eat it up
				//}
				//else if(msg == WM_KEYDOWN && REPOS_EDITABLE == nSel && IsAtEndOfLineNoSel(nStart, nEnd))
				//{
					//if(IsCharStartAutoComplete(wParam))
						//CheckStartAutoComplete(wParam, nStart, nEnd);
						//
				//}
			//}
			//----
			//return false;
			return OnNotCmdKey(msg, wParam, lParam, nStart, nEnd, nSel);  // indicate default processing
			///End AUTOCOMPLETE_CONTROL_CLASS
		}
		
		if(msg == WM_CHAR)
			return false; // indicate default processing
		
		if(msg != WM_KEYDOWN)
			return true;// we need to eat all other message related to Enter key
		switch(wParam)
		{

		case VK_RETURN:
			if(nSel == REPOS_UNEDITABLE) // Support selection execution
			{
				string strAddText = GetSelText();
				///Joe  7/19/06  ON_ENTER_LAST_CMD_EXECUTED
				//strAddText.Replace(GetPrompt(),"");
				//MoveToEnd();
				//ReplaceSel(strAddText);
				//SetSel(m_nPromptPosition, -1); //---Iris 8/08/05 should set selection execution selected
			//}
				if(strAddText.GetLength()>0)
				{					
					strAddText.Replace(GetPrompt(),"");
					MoveToEnd();
					ReplaceSel(strAddText);
					SetSel(m_nPromptPosition, -1); //---Iris 8/08/05 should set selection execution selected
				}
				else
				{
					int nLine = LineFromChar(nStart);
					string strCmd = GetLine(nLine);
					strCmd.Replace(GetPrompt(),"");
					strCmd.Replace("\r\n","");
					SetSel(m_nPromptPosition, -1);	
					ReplaceSel(strCmd);
					SetSel(m_nPromptPosition, -1);
				}
				///ON_ENTER_LAST_CMD_EXECUTED
			}
			m_nHistoryIndex = 0;
			//---- CPY 8/17/05 AUTO_COMPLETE_HOOK
			//----
			return OnEnterKey(nStart, nEnd);
			break;
		case VK_LEFT: case VK_RIGHT:
			//---- CPY 8/17/05 AUTO_COMPLETE_HOOK
			//if(nEnd <= m_nPromptPosition && wParam == VK_LEFT)
			//{
				//OnAutoComplete();
				//return true;// eat up left key to prevent going pass prompt
			//}			
			///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS
			//else if(CCSA_RIGHT_ARROW == m_nStartAutoCompleteBy && nEnd == nStart && IsAtEndOfLine(nEnd) && nEnd - m_nPromptPosition < 10 && VK_RIGHT == wParam)
				//OnAutoComplete(m_nPromptPosition, nStart);
			//----
			/*	Jasmine 09/26/05 AUTO_COMPLETE_POP_UP_MENU
			///Jasmine 9/16/05 START_BY_RIGHT_ARROW
			else if(CCSA_RIGHT_ARROW == m_nStartAutoCompleteBy && nEnd == nStart && IsAtEndOfLine(nEnd) && nEnd - m_nPromptPosition < 10 && VK_RIGHT == wParam)
			{
				ToggleAutoComplete();
				OnAutoComplete(m_nPromptPosition, nStart, CMDKEY_OPEN_AUTO_COMPLETE);
				ToggleAutoComplete();
				return true;
			}
			///End*/
			//else if(AUTOCOMPLETE_BY_CMD == m_nAutoCompleteState && nEnd == nStart && IsAtEndOfLine(nEnd) && nEnd - m_nPromptPosition < 10 && VK_RIGHT == wParam)
			//{
				//SetAutoCompleteState(AUTOCOMPLETE_ON);
				//OnAutoComplete(m_nPromptPosition, nStart, CMDKEY_OPEN_AUTO_COMPLETE);
				//SetAutoCompleteState(AUTOCOMPLETE_BY_CMD);
				//return true;
			//}
			return OnLeftRightCmd(nStart, nEnd,  wParam);
			///Emd AUTO_COMPLETE_POP_UP_MENU
			//return false;
			///End AUTOCOMPLETE_CONTROL_CLASS
			break;			
		case VK_BACK:	
			if(nSel != REPOS_EDITABLE)
			{
				MoveToEnd();				
			}
			else
			{
				///Joe  7/24/06  ON_BACK_DELETE_CHINESE_CHARACTER
				string strTemp = GetText(nStart-2,nEnd);
				bool bIsEnglish = true;
				for(int ii=0; ii<strTemp.GetLength(); ii++)
				{
					if(strTemp.GetAt(ii)<32 || strTemp.GetAt(ii)>126)
					{
						bIsEnglish = false;
						break;
					}
				}							
				if((nStart == nEnd) && (nStart > m_nPromptPosition))
				{
					if(bIsEnglish)
						SetSel(nStart-1, nEnd);
					else
						SetSel(nStart-2, nEnd);
				}
				//if((nStart == nEnd) && (nStart > m_nPromptPosition))
					//SetSel(nStart-1, nEnd);
				///End ON_BACK_DELETE_CHINESE_CHARACTER
				ReplaceSel("");				
			}
			///Joe 5/10/06  BACKSPACE_SHOW_AUTOCOPLETE
			////--- CPY 10/30/05 BACK_SPACE_TO_CLOSE_AND_RESET_AUTO_COMPLETE_WHEN_PASSED_STARTING_PT		
			////if(m_nAutoCompleteStart > m_nPromptPosition)
			////{
				////if(nEnd <= m_nAutoCompleteStart)
					////ResetAutoComplete();
			////}
			//---			
			//if(m_nAutoCompleteStart >= m_nPromptPosition)
			//{
				//m_bAutocompletBackSpace = true; 
				//if(nEnd <= m_nAutoCompleteStart)
					//ResetAutoComplete();
			//}
			OnBackSpaceCmd(nEnd);
			///End BACKSPACE_SHOW_AUTOCOPLETE
			return true;
			break;
		case VK_DELETE:
			if(nSel != REPOS_EDITABLE)
			{
				MoveToEnd();
			}
			return false;
			break;
		case VK_UP:
			return OnUpKey();
			break;
		case VK_DOWN:
			return OnDownKey();
			break;		
		///Joseph 01/25/07 SUPPORT_HOME_END_KEY
		case VK_HOME:
			return OnHomeKey();
			break;
		case VK_END:
			return OnEndKey();
			break;
		///End SUPPORT_HOME_END_KEY
		}			
		return TRUE; // no more default processing	
	}
	
	void GetLineRange(int nLineIndex, int& nBegin, int& nEnd, bool bSkipPrompt = true)
	{
		string strContents;
		for(int index = 0; index<nLineIndex; index++)
		{
			strContents += GetLine(index);
		}
		
		int 	nPrompt = 0;
		string 	strPrompt = GetPrompt();
		if(bSkipPrompt && -1 != GetLine(nLineIndex).Find(strPrompt))
		{
			nPrompt = strPrompt.GetLength();
		}
			
		nBegin = strContents.GetLength() + nPrompt;
		nEnd = nBegin + GetLine(nLineIndex).GetLength();		
	}
	
	void SetLineColor(int nLineIndex, COLORREF cr, bool bMoveToEnd = true)
	{
		int nBegin, nEnd;
		GetLineRange(nLineIndex, nBegin, nEnd);
		
		SetSel(nBegin, nEnd);	
		SetTextColor(nBegin, nEnd, cr);
		if(bMoveToEnd)
			MoveToEnd();
	}
protected:
	int GetSelCheckPos(int& nStart, int& nEnd)
	{	
		GetSel(nStart, nEnd);
		
		if(nEnd < m_nPromptPosition)
			return REPOS_UNEDITABLE ;
		else if(nStart < m_nPromptPosition)
			return REPOS_PARTEDITABLE;
		else
			return REPOS_EDITABLE;
	}
	
	bool IsCmdKey(UINT nKey)
	{
		///Joseph 01/25/07 SUPPORT_HOME_END_KEY
		//if(nKey == VK_RETURN || nKey == VK_LEFT || nKey == VK_BACK || nKey == VK_UP || 
			//nKey == VK_DOWN || nKey == VK_DELETE || nKey == VK_RIGHT )
		if(nKey == VK_RETURN || nKey == VK_LEFT || nKey == VK_BACK || nKey == VK_UP || 
			nKey == VK_DOWN || nKey == VK_DELETE || nKey == VK_RIGHT || nKey == VK_HOME || nKey == VK_END)
		///End SUPPORT_HOME_END_KEY
			return true;
		
		return false;
	}	
public:
	void 	MoveToEnd(bool bCheckScroll = false)
	{
		SetSel(-1,-1);
		//---- debug
		/*
		static int s_nCount = 1;
		string str;
		str.Format("---- %d ---- : MoveToEnd was called", s_nCount++);
		SetStatusBarText(str);
		*/
		//----
		
		//--- CPY 10/7/05 AUTO_SCROLL_SO_MORE_EMPTY_SPACES_FOR_AUTO_COMPLETE
		if(bCheckScroll)
		{
			int nStart, nEnd;
			GetSel(nStart, nEnd);
			/*
			int nLines = GetLineCount();
			int n1st = GetFirstVisibleLine();
			int nLinesToKeep = 10; // this value will later need to get from GetClientRect
			if(nLines - n1st > nLinesToKeep)
				LineScroll(nLinesToKeep); // somehow this is not working, we will need to add more command, when lines reach bottom of rect
			*/
			string str = "\r\n\r\n"; // add 2 lines
			ReplaceSel(str); // force a few new line
			SetSel(nEnd, -1);
			ReplaceSel(""); // retore back
		}
		//---
	}
	//--- CPY 8/3/05 KEY_UP_DOWN_BUFFER
	void ReplaceAfterPrompt(LPCSTR lpcstr)
	{
		if(m_nPromptPosition < 1)
			return;
		
		SetSel(m_nPromptPosition, -1);
		ReplaceSel(lpcstr);
		MoveToEnd();
	}
	//---
	
	//----CPY CPY 11/1/2007 QA70-10638 CMD_WND_OUTPUT_ERR_BY_DEFAULT
	void ReplaceBeforePrompt(LPCSTR lpcstr)
	{
		int nStart = 0, nEnd;
		if(m_nPromptPosition < 1)
		{
			SetSel(-1, -1);
		}
		else
		{
			string strPrompt = GetPrompt();
			nStart = m_nPromptPosition - strPrompt.GetLength();
			SetSel(nStart, nStart);
		}
		ReplaceSel(lpcstr);
		nEnd = lstrlen(lpcstr);
		if(m_nPromptPosition > 1)
			m_nPromptPosition += nEnd;
		nEnd += nStart;
		///Sophy 2/26/2010 QA81-12697-P1 OC_OUTPUT_TO_CMD_WND_SHOULD_FOLLOW_TARGET_FONT_SETTINGS this seems a bug in MFC RichEdit control's ReplaceSel method, this fix is as a workaround.
		//SetTextColor(nStart, nEnd, COLOR_BLACK);
		SetSel(nStart, nEnd);
		CHARFORMAT cf;
		GetDefaultCharFormat(cf);
		SetSelectionCharFormat(cf);
		///end OC_OUTPUT_TO_CMD_WND_SHOULD_FOLLOW_TARGET_FONT_SETTINGS
		MoveToEnd();
	}
	//----
	
	string GetCmdAfterPrompt()
	{
		string strCmd;
		if(m_nPromptPosition < 1)
			return strCmd;
		
		strCmd = GetText(m_nPromptPosition, -1); //get text from prompt to end
		TrimCmd(strCmd);
		
		return strCmd;
	}	
	
	
	virtual void TrimCmd(string& strCmd)
	{
		strCmd.TrimLeft();
		strCmd.TrimRight();
		//--- CPY 8/10/05 should not do this here, CmdControl is a generaic base class, should not assume
		// special characters
		/*
		strCmd.TrimLeft('<');
		strCmd.TrimRight('<');
		
		strCmd.TrimLeft('#');
		strCmd.TrimRight('#');
		*/
	}
	
	string 	GetCmd() 
	{
		return m_strCmd;
	}
	
	void 	SetCmd(LPCSTR lpcszCmd)
	{
		if(lpcszCmd)
			m_strCmd = lpcszCmd;
	}
	//--- CPY 8/4/05 PROPER_MULTIPLE_CMDS
	char GetLastChar(bool bSkipSpaces = true, char* pLastCharBeforeTrip = NULL)
	{
		//---- Iris 8/08/05 SUPPORT_SELECTION_EXECUTE
		//int nLine = GetLineCount() - 1;
		//if(nLine < 0)
		//	return 0;
		//string strLine = GetLine(nLine);
		string strLine = GetCmdLine();
		//-----
		//-------- CPY 8/16/05 MULTI_LINE_EXECUTE_SHOULD_NOT_NEED_SEL
		if(pLastCharBeforeTrip)
			*pLastCharBeforeTrip = str_end_char(strLine);
		//--------
		if(bSkipSpaces)
			strLine.TrimRight();
		
		int nn = str_end_char(strLine);
		return nn < 0? 0 : nn;
	}
	//---
	string GetCmdLine()
	{
		//---- Iris 8/08/05 SUPPORT_SELECTION_EXECUTE
		//SetSel(m_nPromptPosition, -1);		
		int nBegin, nEnd;
		int nSel = GetSelCheckPos(nBegin, nEnd);
		if(REPOS_EDITABLE != nSel || nBegin == nEnd)
		{
			nBegin = m_nPromptPosition;
			nEnd = -1;
		}
		//----
		string strCmd = GetText(nBegin, nEnd);
		
		m_strCmd = strCmd; //CPY 10/22/05 why is this needed?
		return strCmd;
	}
	string 	GetAllText()
	{
		string strText;
		for(int nLine; nLine<GetLineCount(); nLine++)
			strText += GetLine(nLine);
		
		return strText;
	}	
	
	bool 	IsSelEmpty()
	{
		int nBegin, nEnd;
		GetSelCheckPos(nBegin, nEnd);
		if(nBegin == nEnd)
			return true;
		
		return false;
	}
	//----- CPY 8/10/05 CMD_BUFFER_MOVED_TO_CMD_CONTROL
protected:
	//-------- CPY 8/10/05 CMD_BUFFER_MOVED_TO_CMD_CONTROL
	virtual void TrimCmdSeparator(string& strCmd) {}
	virtual void CheckAddCmdSeparator(string& strCmd) {}
	bool	AddCmdBuffer(const string& strCmd)
	{
		int nCount = 0;
		vector<string> vsCmdList;
		//------ Folger 08/22/08 QA80-11966 FIX_RUNTIME_ERROR_IN_COMMAND_WINDOW_CAUSED_BY_STRING_GET_TOKENS
		//strCmd.GetTokens(vsCmdList, '\r');
		okutil_get_tokens(strCmd, &vsCmdList, '\r', NULL);
		//------
		for(int ii = 0; ii < vsCmdList.GetSize(); ii++)
		{
			string str=vsCmdList[ii];
			TrimCmd(str);
			TrimCmdSeparator(str);
			if(!str.IsEmpty())
			{
				nCount++;
				addOneCmdBuffer(str);
			}
		}
		return nCount>0? true:false;
	}
private:
	
	bool	addOneCmdBuffer(const string& strCmd)
	{
		if(strCmd.IsEmpty())
			return false;
		///Joe  8/29/06  ROLLBACK_AND_MODIFY_UPDOWN_KEY
		int nCmdBufferSize = m_vsCmdBuffer.GetSize();
		string strLastCmd;
		if(nCmdBufferSize > 0)
			strLastCmd = m_vsCmdBuffer[nCmdBufferSize -1];
		if(! strLastCmd.CompareNoCase(strCmd))
			return false;	
		///End 	ROLLBACK_AND_MODIFY_UPDOWN_KEY
		if(m_vsCmdBuffer.GetSize() > MAX_CMD_BUFFER)
			m_vsCmdBuffer.RemoveAt(0);
		
		m_vsCmdBuffer.Add(strCmd);
		m_nHistoryIndex = 0;
		return true;		
	}	
	bool getCmdBuffer(string& strCmd, bool bGetNext) // false = prev, true = next
	{
		int inc = bGetNext? 1:-1;
		int nRet;
		while(1)
		{
			m_nHistoryIndex += inc;
			nRet = getLineCheckCmd(strCmd, m_vsCmdBuffer.GetSize() + m_nHistoryIndex );
			if(nRet < 0)
			{
				m_nHistoryIndex -= inc;
				return false;
			}
			if(nRet) // found cmd from past
				return true;		
		}
		return false;	
	}
	int getLineCheckCmd(string& str, int nIndex)
	{
		if(nIndex < 0 || nIndex > m_vsCmdBuffer.GetSize())
			return -1;
		if(nIndex == m_vsCmdBuffer.GetSize())
		{
			str.Empty();
			return 1; // we should allow coming back to an empty line by keep hitting down key
		}
		
		str = m_vsCmdBuffer[nIndex];
		TrimCmd(str);
		return str.IsEmpty()? 0:1;
	}
	//---- CPY 8/17/05 AUTO_COMPLETE_HOOK
///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS 
protected:
///End  AUTOCOMPLETE_CONTROL_CLASS
	bool IsAtEndOfLineNoSel(int nStart, int nEnd)
	{
		if(nEnd != nStart)
			return false;
		
		return IsAtEndOfLine(nEnd);
	}
	bool IsAtEndOfLine(int nEnd)
	{
		int nLineStart = LineIndex();
		int nLen = LineLength();
		return nEnd - nLineStart + 1 >= nLen? true:false;
	}
	//----
private:
	int				m_nHistoryIndex;
public:			///Joseph 12/02/06	UPDOWN_KEY_LOAD_HISTORY	
	///Joe  8/29/06  ROLLBACK_AND_MODIFY_UPDOWN_KEY
	vector<string>	m_vsCmdBuffer;           ///Joe  7/18/06  UP_DOWN_KEY_SHOW
	///End ROLLBACK_AND_MODIFY_UPDOWN_KEY
    //bool     		m_bAutocompletBackSpace;     ///Joe  5/10/06  BACKSPACE_SHOW_AUTOCOPLETE ///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS 
	//----- end CPY 8/10/05 CMD_BUFFER_MOVED_TO_CMD_CONTROL
	//--- CPY 10/30/05 BACK_SPACE_TO_CLOSE_AND_RESET_AUTO_COMPLETE_WHEN_PASSED_STARTING_PT
#ifdef _SHOW_DEBUG_INFO
private:
	int			m_nLastKey; 
	int			m_nLastKeyPos;	
public:
	string		GetDebugInfo()
	{
		string str = "Key:" + m_nLastKey;
		str += " n1=" + m_nAutoCompleteStart + " n2=" + m_nLastKeyPos;
		return str;
	}
#endif
	//---
protected:
	string 		m_strCmd;
	string		m_strPath;  // ---Iris 8/05/05 ADD_CONTEXT_MENU
	string		m_strDlgName;
	LONG 		m_nPromptPosition;
private:
	//---- CPY 8/17/05 AUTO_COMPLETE_HOOK
	//int			m_nAutoCompleteStart;  ///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS 
	///Jasmine 09/26/05 AUTO_COMPLETE_POP_UP_MENU
	//bool		m_bAutoCompleteOn;
	//---------------------- CPY 9/9/05 AUTO_COMPLETE_OBJ
	//int			m_nStartAutoCompleteBy;///Jasmine 9/16/05 START_BY_RIGHT_ARROW ///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS
	//int 		m_nAutoCompleteState; ///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS
	///End AUTO_COMPLETE_POP_UP_MENU
	int         m_nPromptState;
	//ACBase*		m_pACobj;  ///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS
protected:
	void		DebugMsg(LPCSTR lpcsz, int nVal = -320000, LPCSTR lpcszVal = NULL)
	{
		//------- CPY 4/11/06 HIDE_DEBUG_MSG
		// per http://beta.originlab.com/forum/topic.asp?TOPIC_ID=1728
		return;
		//-------
		string str;
		string str1 = lpcszVal;
		if(nVal != -320000)
			str.Format("%s = %d  %s", lpcsz, nVal, str1);
		else
			str.Format("%s%s", lpcsz, str1);		
		str.WriteLine(WRITE_COMPILER_OUTPUT);
	}
	///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS
	//void		ClearAllACObjects()
	//{
		//if(m_pACobj)
			//delete m_pACobj;
		//
		//m_pACobj = NULL;
	//}
	//bool		SetACObject(ACBase* pACobj)
	//{
		//ClearAllACObjects();
		//m_pACobj = pACobj;
		//if (m_pACobj)
		//{
			//DebugMsg("set new AC class obj", 0, m_pACobj->GetClassName());
			//return true;
		//}
		//
		//DebugMsg("set AC class obj to NULL");
		//return false;
	//}
	//ACBase*		GetACObject() {return m_pACobj;}
	///End AUTOCOMPLETE_CONTROL_CLASS
public:
	///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS
	//string		GetCurrentACObjectName()
	//{
		//string str = "NULL";
		//if(m_pACobj)
			//str = m_pACobj->GetClassName();
		//return str;
	//}
	///End AUTOCOMPLETE_CONTROL_CLASS
	//---------------------- end AUTO_COMPLETE_OBJ
	/*	Jasmine 09/26/05 AUTO_COMPLETE_POP_UP_MENU
	void		ToggleAutoComplete() { m_bAutoCompleteOn = m_bAutoCompleteOn? false:true;}
	bool		IsAutoCompleteOn() { return m_bAutoCompleteOn;}
	----
	void		ToggleStartBy() { m_nStartAutoCompleteBy = m_nStartAutoCompleteBy? UN_CCSA_RIGHT_ARROW:CCSA_RIGHT_ARROW;}
	int		IsStartByRightArrow() { return m_nStartAutoCompleteBy;}
	*/	
	///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS
	//void	SetAutoCompleteState(int nState){m_nAutoCompleteState = nState;}
	//int		GetAutoCompleteState(){ return m_nAutoCompleteState;}
	///End AUTOCOMPLETE_CONTROL_CLASS
///End AUTO_COMPLETE_POP_UP_MENU

///Joe  4/24/06  SET_NORMAL_TIME_PATH_PROMPT  set and get the Prompt State
	void    SetPromptState(int nState){m_nPromptState = nState;}
	int     GetPromptState(){return m_nPromptState;}
///End 	 SET_NORMAL_TIME_PATH_PROMPT

};


///Joe  5/19/06  AUTOCOMPLETE_CONTROL_CLASS
///Jasmine 03/24/06 MOVE_TO_CMD_CONTROL_H 
//move from ScriptWindow.
//the codes below should keep in CmdControl.h 
//to make CmdControl independent from ScriptWindow
//-------- CPY 9/18/05 XF_CMD_UPDATE_LIST_UPON_CHANGING_XF_NAME
//virtual 
//
//bool CmdControl::IsCharStartAutoComplete(UINT nCharCmd)
//{
	//if(m_pACobj)
	//{
		//if(m_pACobj->IsUpdateListKey(nCharCmd))
			//return true;
		//
		//return m_pACobj->IsNextStepKey(nCharCmd);
	//}
	//// do not use this anymore, should all be decided by ACobj
	///*
	//if( IsCharAlpha(nCharCmd) || ' ' == nCharCmd || '.' == nCharCmd || '_' == nCharCmd || '(' == nCharCmd)
	//{
		//// next test ACobj
			//
		//
		//return true;
	//}
	//*/
	//return false;
//}

//-------

//---- CPY 10/23/05 WHEN_IN_VARIABLE_MODE_NEED_ALLOW_USER_ENTER_SOMETHING_ELSE
/*
void CmdControl::ResetAutoComplete()
{
	///Joe  5/10/06  BACKSPACE_SHOW_AUTOCOPLETE 
	int nAutoCompleteStart = m_nAutoCompleteStart;
	OnAutoComplete(nAutoCompleteStart,nAutoCompleteStart);
	m_nAutoCompleteStart = nAutoCompleteStart;

	//OnAutoComplete();
	//ACBase* pACobj = GetACObject();
	//if(pACobj)
	//{
		//DebugMsg("ResetAutoComplete currentn ACobj ", 0, pACobj->GetClassName());
		//string strCmd = GetCmdLine();
		//int nChar = str_end_char(strCmd);
		//DebugMsg("Cmd", nChar, strCmd);
		//
		//ACBase* pNextACobj = pACobj->GetResetACObj(strCmd);
		//SetACObject(pNextACobj);
		//DebugMsg("ResetAutoComplete next ACobj ", 0, pNextACobj->GetClassName());
	//}
	//else
		//DebugMsg("ResetAutoComplete found NULL ACobj");	
	///End BACKSPACE_SHOW_AUTOCOPLETE 
}*/
//----

//--------	CPY 9/9/05 AUTO_COMPLETE_OBJ
// nCharCmd = CMDKEY_OPEN_AUTO_COMPLETE to indicate the case of immediate start AutoComplete
// nStart = nCurrent = -1 to close
/*
void CmdControl::OnAutoComplete(int nStart, int nCurrent, UINT nCharCmd)// = -1 = -1 = 0 
{
	//if(!IsAutoCompleteOn())///Jasmine 09/26/05 AUTO_COMPLETE_POP_UP_MENU
	if(GetAutoCompleteState() != AUTOCOMPLETE_ON)
		return;
	m_nAutoCompleteStart = nStart;
	
	vector<string> saNames;
	
	if(!IsInAutoCompleteMode())
	{
		//SetStatusBarText(NULL, 1);
		if(nCurrent < 0)// indicate called from OC level, then tell VC level to close
			CloseAutoComplete();
		return;
	}
	string	strCmd;
	int     nAutoCompleteStart = -1;
	bool	bImediateOpenAutoComplete = false;
	bool	bOpenAutoComplete = false;
	bool	bContinueUsingCurrentACobj = false; //---- CPY 9/18/05 XF_CMD_UPDATE_LIST_UPON_CHANGING_XF_NAME
	ACBase* pACobj = GetACObject();
	if(CMDKEY_OPEN_AUTO_COMPLETE == nCharCmd)
	{
		if(!pACobj)
			return;			
		DebugMsg("OnAutoComplete CMDKEY_OPEN_AUTO_COMPLETE", nStart, pACobj->GetClassName());
		
		bImediateOpenAutoComplete = true;
		bOpenAutoComplete = true;
		//----- Kevin 09/12/05 need to get the whole CMD, not only the variable name;
		//strCmd = GetText(nStart, nCurrent);
		strCmd = GetCmdLine();
		DebugMsg("OnAutoComplete CMDKEY_OPEN_AUTO_COMPLETE", nCurrent, strCmd);
	}
	else
	{
		strCmd = GetCmdLine();
		//---- CPY 9/18/05 XF_CMD_UPDATE_LIST_UPON_CHANGING_XF_NAME
		// if(IsCharStartAutoComplete(nCharCmd))
		if(pACobj && pACobj->IsUpdateListKey(nCharCmd))
		{
			bContinueUsingCurrentACobj = true;
			//DebugMsg("OnAutoComplete IsUpdateListKey", nCurrent, pACobj->GetClassName());
		}
		
		if(bContinueUsingCurrentACobj || IsCharStartAutoComplete(nCharCmd))
		//----
		{
			//---- CPY 10/12/05 GET_NEXT_OBJ_NEEDS_TYPED_CHAR
			// the following code can put junk into last char of strCmd, so we
			// may need to improve this, or make sure subsequent code know about this problem
			// this will happen when nCharCmd == VK_OEM_PLUS, VK_OEM_MINUS when user hit = or - key
			//-----
			char szLast[2] = {0, 0};
			szLast[0] = nCharCmd;
			strCmd += szLast;
			if(pACobj)
				bOpenAutoComplete = true;
		}
		strCmd.TrimLeft();// temp, need better checking for operators etc later
		strCmd.MakeLower();
	}
	///Joe  5/10/06  BACKSPACE_SHOW_AUTOCOPLETE
	if(m_bAutocompletBackSpace)
	{
		ACBase* pNextACobj = pACobj->GetResetACObj(strCmd);
		SetACObject(pNextACobj);
		m_bAutocompletBackSpace = false;
	}
	///End BACKSPACE_SHOW_AUTOCOPLETE
	///Joe  5/10/06  BACKSPACE_SHOW_AUTOCOPLETE
	//---- CPY 9/18/05 XF_CMD_UPDATE_LIST_UPON_CHANGING_XF_NAME
	//if(bOpenAutoComplete)
	//if(bOpenAutoComplete && !bContinueUsingCurrentACobj
	//----
	if(bOpenAutoComplete && !bContinueUsingCurrentACobj  && !m_bAutocompletBackSpace)
	///End BACKSPACE_SHOW_AUTOCOPLETE
	{
		ACBase* pNextACobj = pACobj->GetNextACObj(strCmd, nCharCmd);
		if(!SetACObject(pNextACobj))
		{
			DebugMsg("SetACObject failed. ", 0, pACobj->GetClassName());
			OnAutoComplete();// to close AutoComplete	
			return;
		}
		//DebugMsg("ready to start AutoComplete ", 0, pNextACobj->GetClassName());
	}
	int nlist = 0;
	BOOL bSort = false;
	vector<int> viAttributes;
	ACBase* pNewACobj = GetACObject();
	if((pNewACobj->GetClassName()).Compare("ACXF") == 0)
		strCmd.TrimRight();
	int nList = pNewACobj->GetDisplayList(strCmd, saNames, viAttributes, bSort);
	if(bImediateOpenAutoComplete)
	{
		nAutoCompleteStart = nCurrent;
	}
	else
	{
		if(pNewACobj->IsReplaceFromPrompt())
			nAutoCompleteStart = m_nPromptPosition;
		else
			nAutoCompleteStart = m_nPromptPosition + strCmd.GetLength();
	}
	
	m_nAutoCompleteStart = nAutoCompleteStart;
	//DebugMsg("ready to start AutoComplete. ", nAutoCompleteStart, pNewACobj->GetClassName());
	
	if(nList > 0)
		AutoComplete(nAutoCompleteStart, saNames, viAttributes, bSort);
	else
		CloseAutoComplete();
}*/
//virtual
/* 
bool CmdControl::OnAutoCompleteGetHelpInfo(int nIconID, LPCSTR lpcszSrc, string& strDisplay)
{
	ACBase* pACobj = GetACObject();
	if(pACobj)
	{
		//DebugMsg("OnAutoCompleteGetHelpInfo. icon", nIconID, pACobj->GetClassName());
	//---- Kevin 09/13/05 AUTO_COMPLETE_OBJ
		//strDisplay = pACobj->GetHelpInfo(lpcszSrc, nIconID);
		string strCmd = GetCmdLine();
		strDisplay = pACobj->GetHelpInfo(lpcszSrc, strCmd, nIconID);
	//---- end AUTO_COMPLETE_OBJ
		return true;
	}
	DebugMsg("OnAutoCompleteGetHelpInfo found no AC obj");
	return false;
}
*/
//virtual 
/*bool CmdControl::OnAutoCompleteDoneReplaceSel(int nStart, int nEnd)
{
	string strEnd = "- " + nEnd;
	DebugMsg("OnAutoCompleteDoneReplaceSel", nStart, strEnd);
	ACBase* pACobj = GetACObject();
	if(pACobj)
	{
		DebugMsg("test IsImmediateStartNext ", nStart, pACobj->GetClassName());
		
		if(pACobj->IsImmediateStartNext())
		{
			// somehow nEnd is always same as nStart, so we will reget it 
			int n1, n2;
			GetSel(n1, n2);
			nEnd = n2;
			DebugMsg("IsImmediateStartNext is true, will start next ", nEnd, pACobj->GetClassName());
			OnAutoComplete(nStart, nEnd, CMDKEY_OPEN_AUTO_COMPLETE);
			return true;
		}
	}
	return false;
}*/
// called when AutoComplete window is to close
/*void CmdControl::OnAutoCompleteClose(Window& wndToNotify, int nStart, int nEnd)
{
	DebugMsg("OnAutoCompleteClose, this is not used anymore, please report to CP");
	//OnAutoComplete(-1, 0); // CPY 2nd arg = 0 to indicate called from VC level
	OnAutoComplete();// to close AutoComplete
	if(wndToNotify)
	{
		DebugMsg("wndToNotify ", nEnd);
		if(nStart > 0 && nEnd > nStart)
		{
			DebugMsg("auto complete text replaced, posting notification", nStart);
			wndToNotify.PostMessage(WM_USER_AUTOCOMPLETE_ON_REPLACE_SEL, nStart, nEnd);
		}
	}
}
*/
//------ end CPY 8/27/05 AUTO_COMPLETE_HOOK
//End AUTOCOMPLETE_CONTROL_CLASS
///End MOVE_TO_CMD_CONTROL_H
#endif //_CMD_CONTROL_H




