/*------------------------------------------------------------------------------*
 * File Name:Matlab Console	 													*
 * Creation:CPY 12/27/02														*
 * Purpose: OriginC Source C file for Dialog Buidler Matlab Console				*
 * Copyright (c) Originlab Corporation, 2002, 2003								*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	DVT	1/2/03 QA70-3606 v7.0467 MATLAB_IMPORT_DIALOG_USE_MATLAB_CLASS			*
 *	DVT 7/1/03 QA70-4753 v7.0614 MATLAB_CONSOLE_PUT_COMPLEX						*
 *	DVT 8/14/03 MATLAB_SINGLE_INSTANCE_FOR_MENU_IMPORT							*
 *	AW 09/07/03 QA70-3859 FIX_SOME_CHARACTER_INPUT_PROBLEM						*
 *  Soapy 9/19/03 INCREASE_TEXT_LIMIT_IN_RICHEDIT								*
 *  Soapy 9/19/03 NO_DELETE_PROMPT												*
 *  Soapy 9/19/03 SUPPORT_MULTILINE_COMMAND										*
 *  Soapy 9/19/03 CHECK_MATRIX_SIZE_BEFORE_PUT_MATRIX							*
 *	Soapy 9/26/03 REMOVE_DUPLICATED_CODE										*
 *	Soapy 9/27/03 MORE_EFFECT_ON_COMMAND_WINDOW									*
 *	Soapy 10/22/03	DELETE_SPACE_BEFORE_COMMAND									*
 *  Soapy 11/4/03  	FIX_BUG_ON_BRACKET											*
 *  Soapy 11/12/03 GET_REAL_MATRIX_BY_VARIABLE_NAME								*
 *  SY 12/29/2004 v8.0181 USING_DIALOGEX_H_INSTEAD_OF_DIALOG_H					*
 *	CPY 2/1/05 MATLAB_7_PR_NOT_WORKING											*
 *  SY 02/08/2004 QA70-7383 MATLAB_CONSOLE_SEND_WKS_COL							*
 *  Jasmine 8/02/05 CHANGE_TO_MATLABCMDCONTROL_CLASS							*
 *	Jasmine 8/12/05 QA70-7998 v8.0286 CHECK_MATLAB_AVAILABILITY 				*
 *	Jasmine 8/15/05 MOVE_TO_MATCMDCONTROL										*
 *  Jasmine 08/24/05 QA70-7998 v8.0292 PROMTPOSITION_UPDATE						*
 *  Jasmine 08/24/05 QA70-7998 v8.0292 SENDMESSAGE_TO_CLOSE_WND					*
 *	Jasmine 08/25/05 VARIANT_NAME_CHANGE										*
 *	Jasmine 10/11/05 QA70-7998 ADD_CONTEXT_MENU									*
 *	DSC 4/20/06 MOVE_OCUTILS_TO_MFC												*
 *	Jake 07/13/07 ADD_EXPORT_BUTTON												*
 *	Folger 07/16/07 INVOKE_MATLAB_EXPORT_BY_FIND_FUNCTION						*
 *------------------------------------------------------------------------------*/
 
#include <Origin.h>
//#include <Project.h>
//#include <sys_utils.h> // basic routines implemeted through Origin C, see sys_utils.c
/// SY 12/29/2004 v8.0181 USING_DIALOGEX_H_INSTEAD_OF_DIALOG_H
///#include <Dialog.h>
#include "DialogEx.h"     // Dialog class
/// end USING_DIALOGEX_H_INSTEAD_OF_DIALOG_H
//#include <utilities.h>
///	#include "ResizeDialog.h" /// SY 12/29/2004 v8.0181 USING_DIALOGEX_H_INSTEAD_OF_DIALOG_H

#pragma labtalk(0) //CPY 12/6/06 QA70-12736 LT_NEED_MORE_CNTRL_ON_ALLOWING_OC_FUNCS

#include <externApps.h> // matlab class
/// SY 12/29/2004 v8.0181 USING_DIALOGEX_H_INSTEAD_OF_DIALOG_H
///	#include "ODlg.h" // resource IDs, ODlg.dll also use this file for its res ids
///	#include "HelpID.h"			// dialog ID
/// end USING_DIALOGEX_H_INSTEAD_OF_DIALOG_H

/// DSC 4/20/06 MOVE_OCUTILS_TO_MFC
//#include "ocUtils.h" /// SY 02/09/2004 QA70-7383 MATLAB_CONSOLE_SEND_WKS_COL
#include <ocu.h> // new name, and moved to system folder
/// end MOVE_OCUTILS_TO_MFC

///Jasmine 08/24/05 QA70-7998 v8.0292 SENDMESSAGE_TO_CLOSE_WND
//#define WM_USER_CLOSE_WND  (WM_USER +1040)
#include "MatlabCmdControl.h"

////////////////////////////////////////////////////////////////////////////////////
///Arvin/Cheney 2007-3-16 REWRITE_DO_ORIGIN_CMD	
//defined in MatlabCmdControl.h
//#define STR_NO_MATLAB "Matlab not available"
///end REWRITE_DO_ORIGIN_CMD
#define STR_PROMPT	">>" //matlab prompt
#define STR_PROMPT_LEN 2

///---------- SY 02/08/2004 QA70-7383 MATLAB_CONSOLE_SEND_WKS_COL
///	enum {CMDID_PUT_REAL, CMDID_GET_REAL, CMDID_PUT_COMPLEX, CMDID_GET_COMPLEX, CMDID_EXIT, CMDID_QUIT, CMDID_CLC, CMDID_COUNT};
///	// for simple list, we just keep the list consistent with CMDID_PUT etc
///	static StringArray s_asCmdList = {"pr", "gr", "pc", "gc",                   "exit",     "quit",     "clc"};
/*///Jasmine 8/02/05 CHANGE_TO_MATLABCMDCONTROL_CLASS
enum {CMDID_PUT_REAL, CMDID_GET_REAL, CMDID_PUT_COMPLEX, CMDID_GET_COMPLEX, CMDID_EXIT, CMDID_QUIT, CMDID_CLC, CMDID_PUT_WKS_REAL, CMDID_PUT_WKS_COMPLEX, CMDID_PUT_WKS_STRING, CMDID_COUNT};
static StringArray s_asCmdList = {"pr", "gr", "pc", "gc",                   "exit",     "quit",     "clc", 	"pwr", 	"pwc", "pws"};
*/
///End CHANGE_TO_MATLABCMDCONTROL_CLASS
///---------- end MATLAB_CONSOLE_SEND_WKS_COL

BOOL	MatlabImport(LPCSTR lpcszMatlabWkspaceName = NULL, HWND hParent = NULL, BOOL bSinle = FALSE);
BOOL 	MatlabExport(LPCSTR lpcszMatlabWkspaceName = NULL, HWND hParent = NULL, BOOL bSingle = FALSE);///Jake 07/13/07 ADD_EXPORT_BUTTON

typedef BOOL (*FUNC_LPCSTR_HWND_BOOL)(LPCSTR lpcszMatlabWkspaceName = NULL, HWND hParent = NULL, BOOL bSingle = FALSE);		//-------Folger 07/16/07 INVOKE_MATLAB_EXPORT_BY_FIND_FUNCTION

///Soapy 9/19/03 INCREASE_TEXT_LIMIT_IN_RICHEDIT
//#define TEXT_LIMITS 90000	///Jasmine 8/02/05 CHANGE_TO_MATLABCMDCONTROL_CLASS
///END INCREASE_TEXT_LIMIT_IN_RICHEDIT

//enum {UNEDITABLE = 1, PARTEDITABLE, EDITABLE};  //Selection range status ///Jasmine 8/02/05 CHANGE_TO_MATLABCMDCONTROL_CLASS

///Jasmine 10/11/05 QA70-7998 ADD_CONTEXT_MENU
enum {
	MATLABCONSOLE_MENU_CUT, 
	MATLABCONSOLE_MENU_COPY, 
	MATLABCONSOLE_MENU_PASTE, 
	MATLABCONSOLE_MENU_CLEAR,
	
	MATLABCONSOLE_MENU_LAST_ITEM = 10000
};

class MATLABConsoleMenu : public Menu
{
public:	
	MATLABConsoleMenu(bool bIsSel, bool bEditable)
	{
		m_nChoice = -1;		
		
		UINT nSelFlags = bIsSel? MF_ENABLED : MF_DISABLED | MF_GRAYED;  
		UINT nEditableFlags = bEditable ? MF_ENABLED : MF_DISABLED | MF_GRAYED;
		UINT nSelEditableFlags = bIsSel&&bEditable ? MF_ENABLED : MF_DISABLED | MF_GRAYED;
				
		Add(_L("Cut"), OnMenuItem, nSelEditableFlags);		
		Add(_L("Copy"), OnMenuItem, nSelFlags);
		Add(_L("Paste"), OnMenuItem, nEditableFlags);
		Add(_L("Clear"), OnMenuItem);	
	}
	void OnMenuItem(UINT nPos)
	{
		m_nChoice = nPos;
	}
	
	bool GetCommand(int& nChoice)
	{
		if(m_nChoice >= MATLABCONSOLE_MENU_CUT && m_nChoice < MATLABCONSOLE_MENU_LAST_ITEM)
		{
			nChoice = m_nChoice;
			return true;
		}
		return false;
	}
	void EmptySepFunc(uint nCmd)
	{
	}

private:
	int	m_nChoice;
};
///End ADD_CONTEXT_MENU

class MATLABConsoleDlg : public ResizeDialog
{
public:
	MATLABConsoleDlg() : ResizeDialog(IDD_MATLAB_CONSOLE, "ODlg")
	{
		//m_pMATLABObj = NULL;	///Jasmine 8/02/05 CHANGE_TO_MATLABCMDCONTROL_CLASS
		//m_reCntrl.MatlabobjInit()	///Jasmine 8/15/05 MOVE_TO_MATCMDCONTROL
	}
	int Create(HWND hWndParent = NULL)
	{
		//if(!m_reCntrl.IsMatlabAvailable())	///Jasmine 8/12/05 QA70-7998 v8.0286 CHECK_MATLAB_AVAILABILITY 
		if(!m_MCCntrl.IsMatlabAvailable())	///Jasmine 08/25/05 VARIANT_NAME_CHANGE
			return 0;
		
		InitMsgMap();// will be called from internal later
		int nRet = ResizeDialog::Create(hWndParent);
		
		return nRet;
	}
	
///----------------------------------------------
///----------------- Message Map ----------------
///
protected:
		
EVENTS_BEGIN
	ON_INIT(OnInitDialog) 
	ON_SIZE(OnDlgResize)
	ON_KEY(IDC_MATLAB_RICHEDIT, OnKeyCmdWindow)
	ON_TIMER(OnTimer)
	ON_DESTROY(OnDestroy)

	ON_BN_CLICKED(IDC_MATLAB_OPEN_IMPORT, OnClickImport)
	ON_BN_CLICKED(IDC_MATLAB_OPEN_EXPORT, OnClickExport)///Jake 07/13/07 ADD_EXPORT_BUTTON
	///Jasmine 08/24/05 QA70-7998 v8.0292 SENDMESSAGE_TO_CLOSE_WND
	//ON_USER_MSG(WM_USER_CLOSE_WND, OnCloseWndCmd)
	ON_CONTEXTMENU(OnShowMenu)	///Jasmine 10/11/05 QA70-7998 ADD_CONTEXT_MENU
EVENTS_END
///----------------------------------------------
///	DVT	1/2/03 QA70-3606 v7.0467 MATLAB_IMPORT_DIALOG_USE_MATLAB_CLASS
// pending on Matlab::Attach(mlObj) or two BEGIN_EVENT_MAP in the same file (pending OriginC ## merge)
//	ON_BN_CLICKED(IDC_MATLAB_BTN_IMPORT, OnClickImport)

	BOOL OnInitDialog()
	{
		waitCursor junk;
		ResizeDialog::OnInitDialog();
		GetWindow().Text = "Connecting to Matlab...";
		
		///Jasmine 8/02/05 CHANGE_TO_MATLABCMDCONTROL_CLASS
		//m_reCntrl = GetItem(IDC_MATLAB_RICHEDIT);	///Jasmine 08/25/05 VARIANT_NAME_CHANGE
		m_MCCntrl = GetItem(IDC_MATLAB_RICHEDIT);
		///end CHANGE_TO_MATLABCMDCONTROL_CLASS
		
		//m_reCntrl.Enable = FALSE;// until ready by timer	///Jasmine 08/25/05 VARIANT_NAME_CHANGE
		m_MCCntrl.Enable = FALSE;
				
				
		///Jake 07/13/07 ADD_EXPORT_BUTTON
		Control cntrlExpBtn = GetItem(IDC_MATLAB_OPEN_EXPORT);
		cntrlExpBtn.Visible = true;
		///end ADD_EXPORT_BUTTON
		
		///Soapy 9/19/03 INCREASE_TEXT_LIMIT_IN_RICHEDIT
		///Jasmine 8/02/05 CHANGE_TO_MATLABCMDCONTROL_CLASS
		//m_reCntrl.LimitText(TEXT_LIMITS);
		///end CHANGE_TO_MATLABCMDCONTROL_CLASS
		///END INCREASE_TEXT_LIMIT_IN_RICHEDIT
		
		//m_pMATLABObj = new Matlab(FALSE);			///DVT 	//Jasmine 8/02/05 CHANGE_TO_MATLABCMDCONTROL_CLASS
		//m_reCntrl.MatlabobjCreate();	///Jasmine 08/25/05 VARIANT_NAME_CHANGE
		m_MCCntrl.MatlabobjCreate();
		
		m_nTimerID = SetTimer(5432,300);
		return TRUE;
	}
	
	BOOL OnTimer(UINT nTimerID)   
	{
		ASSERT(nTimerID == m_nTimerID);
		
		KillTimer(m_nTimerID);
		m_nTimerID = 0;
		
		//Jasmine 8/02/05 CHANGE_TO_MATLABCMDCONTROL_CLASS
		//if(m_pMATLABObj && m_pMATLABObj->Attach(TRUE, FALSE, TRUE))		///	DVT MATLAB_SINGLE_INSTANCE_FOR_MENU_IMPORT using: Attach( bUseRunningInstance, bSingle, bKeepMatlabRunning )
		//if(m_reCntrl.IsReadyMatlabobj())	///Jasmine 08/25/05 VARIANT_NAME_CHANGE
		if(m_MCCntrl.IsReadyMatlabobj())
		{
			//add_str( STR_PROMPT, FALSE);
			/* ///Jasmine 08/24/05 QA70-7998 PROMTPOSITION_UPDATE
			m_reCntrl.addString( STR_PROMPT, FALSE);
			GetWindow().Text = "Matlab Console";
			m_PromptPosition = 2;  		///Soapy 9/19/03 NO_DELETE_PROMPT
			*/
			GetWindow().Text = _L("MATLAB Console");
			//m_reCntrl.ShowPrompt();	///Jasmine 08/25/05 VARIANT_NAME_CHANGE
			m_MCCntrl.ShowPrompt();
			///End PROMTPOSITION_UPDATE
		}
		///End CHANGE_TO_MATLABCMDCONTROL_CLASS
		else
			GetWindow().Text = STR_NO_MATLAB;
			
		//m_reCntrl.Enable = TRUE; // allow this no matter what	///Jasmine 08/25/05 VARIANT_NAME_CHANGE
		m_MCCntrl.Enable = TRUE;
		///	DVT	1/2/03 QA70-3606 v7.0467 MATLAB_IMPORT_DIALOG_USE_MATLAB_CLASS
		//Import button added, have to set focus to the re control, Tarak will add SetFocus to Window class
		//reCntrl.SetFocus(TRUE);
		///	end MATLAB_IMPORT_DIALOG_USE_MATLAB_CLASS
	
		return TRUE;
	}
	
	BOOL OnDestroy(void)
	{
		//Jasmine 8/02/05 CHANGE_TO_MATLABCMDCONTROL_CLASS
		/*
		// we keep this running so next time dialog open the workspace is still there
		//m_mlObj.Detach();
		///	DVT in case m_pMATLABObj->Attach(TRUE, FALSE, TRUE) overwritten externally:
		m_pMATLABObj->KeepMatlabRunning = TRUE;
		delete m_pMATLABObj;
		m_pMATLABObj = NULL;
		*/
		///End CHANGE_TO_MATLABCMDCONTROL_CLASS
		//m_reCntrl.DelMatlabobj();	///Jasmine 08/25/05 VARIANT_NAME_CHANGE
		m_MCCntrl.DelMatlabobj();
		return TRUE;
	}
	
	BOOL OnClickImport(Control ctrl)
	{
		MatlabImport(NULL, GetSafeHwnd() );
		return TRUE;
	}
	
	BOOL OnClickExport(Control ctrl)
	{
		//-------Folger 07/16/07 INVOKE_MATLAB_EXPORT_BY_FIND_FUNCTION
		//MatlabExport(NULL, GetSafeHwnd() );
		string strPath = "Originlab\\MatlabExportDlg.c";
		FUNC_LPCSTR_HWND_BOOL pfn = Project.FindFunction("MatlabExport", strPath);
		if (pfn)
			return pfn(NULL, GetSafeHwnd());
		//-------End INVOKE_MATLAB_EXPORT_BY_FIND_FUNCTION
		return TRUE;
	}
	
	///Jasmine 10/11/05 QA70-7998 ADD_CONTEXT_MENU
	BOOL OnShowMenu(UINT nResIDCtrl, int nx, int ny)
	{
		int	nCmd; 
		MATLABConsoleMenu	myMenu(!m_MCCntrl.IsSelEmpty(), m_MCCntrl.IsEditable());
		
		myMenu.TrackPopupMenu(0,  nx, ny, GetSafeHwnd());
		if(myMenu.GetCommand(nCmd))
		{
			switch(nCmd)
			{				
			case MATLABCONSOLE_MENU_CUT: 
				m_MCCntrl.OnCut();
				return TRUE;
				break;
				
			case MATLABCONSOLE_MENU_COPY:
				m_MCCntrl.Copy();
				return TRUE;
				break;
				
			case MATLABCONSOLE_MENU_PASTE:
				m_MCCntrl.Paste();
				return TRUE;
				break;
				
			case MATLABCONSOLE_MENU_CLEAR:
				m_MCCntrl.OnClear();
				return TRUE;
				break;
			default:
				return FALSE;
			}
		}
		return FALSE;
	}
	///End ADD_CONTEXT_MENU
	
	BOOL OnDlgResize(int nType, int cx, int cy)
	{
		RECT r1;
		Control cntrlRichEdit;
		GetControlClientRect(IDC_MATLAB_RICHEDIT, r1, &cntrlRichEdit);
		r1.bottom = cy;
		r1.right = cx;		
		cntrlRichEdit.MoveWindow(&r1);
		return TRUE;
	}
	
	//return FALSE if not handled, and continue to be processed
	//return TRUE will stop default processing
	BOOL OnKeyCmdWindow(Control oCntrl, UINT msg, UINT wParam, UINT lParam)
	{
		///Jasmine 8/02/05 change, CHANGE_TO_MATLABCMDCONTROL_CLASS
		/////Soapy 9/27/03 MORE_EFFECT_ON_COMMAND_WINDOW		
		//int nStart, nEnd;
		//int nSelectionStatus = checkAndReturnSelectionRange(nStart, nEnd);
		//
		//if( !is_sys_cmd_key(wParam) )
		//{
			//if( nSelectionStatus != EDITABLE)
					//m_reCntrl.SetSel(-1,-1);
			//
			//return false;  // indicate default processing
		//}
		/////END MORE_EFFECT_ON_COMMAND_WINDOW	
		//
		///// AW 09/07/03 QA70-3859 FIX_SOME_CHARACTER_INPUT_PROBLEM
		//if(msg == WM_CHAR)
			//return FALSE;
		///// END FIX_SOME_CHARACTER_INPUT_PROBLEM
		//
		//if(msg != WM_KEYDOWN)
			//return TRUE;// we need to eat all other message related to Enter key
		//
		//switch(wParam)
		//{
		//case VK_RETURN:
			/////Soapy 9/27/03 MORE_EFFECT_ON_COMMAND_WINDOW
			//if(nSelectionStatus == UNEDITABLE) // Support selection execution
			//{
				//string strAddText = m_reCntrl.GetSelText();
				//strAddText.Replace(">>","");
				//m_reCntrl.SetSel(-1,-1);
				//m_reCntrl.ReplaceSel(strAddText);
			//}
			/////END MORE_EFFECT_ON_COMMAND_WINDOW
			//return OnEnterKey(nStart, nEnd);
			//break;
			//
		/////Soapy 9/27/03 MORE_EFFECT_ON_COMMAND_WINDOW
		///*
		//case VK_LEFT: case VK_BACK:
			//// should not go left on prompt
			//if(nStart - nLineStart <= strlen(STR_PROMPT))
				//break;
			//
			//return FALSE;
		//*/
		//case VK_LEFT: case VK_RIGHT:
			//return false;
			//break;
			//
		//case VK_BACK:
			//if(nSelectionStatus != EDITABLE)
			//{
				//m_reCntrl.SetSel(-1,-1);				
			//}
			//else
			//{
				//if((nStart == nEnd) &&(nStart>m_PromptPosition))
					//m_reCntrl.SetSel(nStart-1,nEnd);
				//m_reCntrl.ReplaceSel("");				
			//}
			//return true;
			//break;
			//
		//case VK_DELETE:
			//if(nSelectionStatus != EDITABLE)
			//{
				//m_reCntrl.SetSel(-1,-1);
			//}
			//return false;
			//break;
		//}
		/////END MORE_EFFECT_ON_COMMAND_WINDOW
					//
		//return TRUE; // no more default processing	
		
		/////End CHANGE_TO_MATLABCMDCONTROL_CLASS
		
		//return m_reCntrl.OnKeyCmd(msg, wParam, lParam);	///Jasmine 08/25/05 VARIANT_NAME_CHANGE	
		return m_MCCntrl.OnKeyCmd(msg, wParam, lParam);
	}
	
	///Jasmine 8/02/05 change, CHANGE_TO_MATLABCMDCONTROL_CLASS
	//BOOL OnEnterKey(int nStart, int nEnd)
	//{
		/////Soapy 9/19/03 SUPPORT_MULTILINE_COMMAND	
		///*
		//if(nEnd > nStart)		
		//{
			//// selected range, not supported for now,
			//MessageBeep(0);
			//return TRUE;// no more default processing
		//}
		//
		//string strCmd = ed.GetLine();
		//strCmd.TrimRight();
		//string strPrompt = strCmd.Left(STR_PROMPT_LEN);
		//
		//if(strPrompt.Compare(STR_PROMPT) != 0)
			//return TRUE;
				//
		//add_str("\r\n", FALSE);
		//strCmd = strCmd.Mid(STR_PROMPT_LEN);
		//*/
		//
		//m_reCntrl.SetSel(m_PromptPosition,-1);		
		//string strCmd = m_reCntrl.GetSelText();
		//m_reCntrl.SetSel(-1,-1);
		//
	 	//if(!isBracketMatch(strCmd,'[',']') ||!isBracketMatch(strCmd,'{','}' ))
			//return false;
				//
		//add_str("\r\n", FALSE);		
		/////END SUPPORT_MULTILINE_COMMAND
	//
		//string strOutput = STR_NO_MATLAB;
		//if(m_pMATLABObj && !is_Origin_command(strCmd, strOutput) && *m_pMATLABObj)
		//{
			//strOutput = m_pMATLABObj->Execute(strCmd);
		//}
		//
		//add_str(strOutput);	
		//
		////we need put Enter in ourself as we were switching to anther control above
		//add_str(STR_PROMPT, FALSE);
		//
		/////Soapy 9/19/03 NO_DELETE_PROMPT
		//m_reCntrl.SetSel(-1,-1);
		//m_reCntrl.GetSel(nStart,m_PromptPosition); //Record the position of latest prompt
		/////END Soapy 9/19/03 NO_DELETE_PROMPT
		//
		//return TRUE;
				//
	//}
	///End CHANGE_TO_MATLABCMDCONTROL_CLASS
	/*///Jasmine 08/24/05 QA70-7998 v8.0292 SENDMESSAGE_TO_CLOSE_WND
	void OnCloseWndCmd()
	{
		GetWindow().SendMessage(WM_CLOSE);
	}*/
private:
	///Jasmine 8/04/05 CHANGE_TO_MATLABCMDCONTROL_CLASS
	/*
	void add_str(LPCSTR lpcszText, BOOL bAddNewLine=TRUE)
	{
		m_reCntrl.SetSel(-1,-1);
		m_reCntrl.ReplaceSel(lpcszText);
		m_reCntrl.SetSel(-1,-1);
		if(bAddNewLine)
		{
			m_reCntrl.ReplaceSel("\r\n");
			m_reCntrl.SetSel(-1,-1);
		}
	}
	
	bool is_sys_cmd_key(UINT nKey)
	{
		if(nKey == VK_RETURN || nKey == VK_LEFT || nKey == VK_BACK || nKey == VK_UP || 
			nKey == VK_DOWN || nKey == VK_DELETE || nKey == VK_RIGHT)  ///Soapy 9/19/03 NO_DELETE_PROMPT
			return true;
		
		return false;
	}
	
	bool is_Origin_command(LPCSTR lpcszCmd, string& strResult)	
	{
		string strCmdstr = lpcszCmd;
		
		strCmdstr.TrimLeft();	//Soapy 10/22/03 DELETE_SPACE_BEFORE_COMMAND
		
		//----- CPY 1/10/03
		// GetTokens has a bug, if str has ', will generate runtime error
		//int nArgs = strCmdstr.GetTokens(strCmdArgs);
		//if(nArgs < 1)
		//	return false;
		//string strCmd = strCmdArgs[0];
		int nSpace = strCmdstr.Find(' ');
		if(strCmdstr.IsEmpty() || nSpace == 0)
			return false;
	
		string strCmd = strCmdstr;
		if(nSpace > 0)
			strCmd = strCmdstr.Left(nSpace);
		//-----
	
		for(int nCmdID = 0; nCmdID < CMDID_COUNT; nCmdID++)
		{
			if(strCmd.CompareNoCase(s_asCmdList[nCmdID]) == 0)
			{
				//----- CPY 1/10/03
				StringArray	strCmdArgs;
				int nArgs = strCmdstr.GetTokens(strCmdArgs);
				if(nArgs < 1)
					return false;
				//-----
				do_Origin_commad(nCmdID, strCmdArgs, strResult);
				return true;
			}
		}
		return false;
	}
		
	// reutrn true if matrix does not exist and has to be created
	bool get_Origin_matrix(string strMatName, MatrixLayer& mLayer)
	{
		MatrixLayer mltemp(strMatName);
		if(!mltemp)
		{
			mltemp.Create();
			mltemp.GetPage().Rename(strMatName);
			mLayer = mltemp;
			return true;
		}
		mLayer = mltemp;
		return false;
	}
	*/
	
	//void do_Origin_commad(int nCmdID, StringArray& asArgs, string& strResult)	
	//{
		/////---------- SY 02/08/2004 QA70-7383 MATLAB_CONSOLE_SEND_WKS_COL
		/////	uint nArgSize = asArgs.GetSize();
		/////	if(nArgSize < 2 && nCmdID <= CMDID_GET_COMPLEX) // no argument
		/////	{
		/////		strResult = "Usage:" + asArgs[0];
		/////		strResult += " matName1 matName2 ...";
		/////		return;
		/////	}
		/////	///	DVT 7/1/03 QA70-4753 v7.0614 MATLAB_CONSOLE_PUT_COMPLEX
		/////	if(nArgSize < 3 && nCmdID == CMDID_PUT_COMPLEX) // not enough arguments
		/////	{
		/////		strResult = "Usage:" + asArgs[0];
		/////		strResult += " matNameReal matNameImag [matlNameResult (= matNameReal)]";
		/////		return;
		/////	}
		/////	///	end MATLAB_CONSOLE_PUT_COMPLEX
		/////---------- end MATLAB_CONSOLE_SEND_WKS_COL
	//
		//if(NULL == m_pMATLABObj)
		//{
			//strResult = STR_NO_MATLAB;
			//return;
		//}
			//
		///// SY 02/08/2004 QA70-7383 MATLAB_CONSOLE_SEND_WKS_COL
		//uint nArgSize = asArgs.GetSize();
		//// Parse argument
		//switch( nCmdID )
		//{
		//case CMDID_PUT_REAL:
		//case CMDID_GET_REAL:
		//case CMDID_PUT_COMPLEX:
			//if( nArgSize < 2 )
			//{
				//strResult = "Usage:" + asArgs[0];
				//strResult += " matName1 matName2 ...";
				//return;
			//}
			//break;
			//
		//case CMDID_GET_COMPLEX:
			//if( nArgSize < 3 ) // not enough arguments
			//{
				//strResult = "Usage:" + asArgs[0];
				//strResult += " matNameReal matNameImag [matlNameResult (= matNameReal)]";
				//return;
			//}
			//break;
			//
		//case CMDID_PUT_WKS_REAL:
		//case CMDID_PUT_WKS_STRING:
			//if( nArgSize != 2 && nArgSize != 3 )
			//{
				//strResult = "Usage:" + asArgs[0];
				//strResult += " DatasetName [matName]";
				//return;
			//}
			//break;
			//
		//case CMDID_PUT_WKS_COMPLEX:
			//if( nArgSize != 3 && nArgSize != 4 )
			//{
				//strResult = "Usage:" + asArgs[0];
				//strResult += " DatasetName1 DatasetName2 [matName (= DatasetName1)]";
				//return;
			//}
			//break;
			//
		//case CMDID_EXIT:
		//case CMDID_QUIT:
		//case CMDID_CLC:
		//case CMDID_COUNT:
			//break;
			//
		//default:
			//return;
		//}
		///// end MATLAB_CONSOLE_SEND_WKS_COL
			//
		//strResult.Empty();
		//int ii;
		//bool bSuccess;
		//
		//switch(nCmdID)
		//{
		//case CMDID_PUT_REAL:
			//for(ii = 1; ii < nArgSize; ii++)
			//{
				//MatrixLayer mlay(asArgs[ii]);
				//if(!mlay)
				//{
					//strResult = "???\r\n " + asArgs[ii];
					//strResult += " is not an Origin matrix.\r\n";
					//return;
				//}
				//Matrix<double> mm(mlay);
				////--- CPY 2/1/05 MATLAB_7_PR_NOT_WORKING
				////m_pMATLABObj->PutMatrix(mm.GetName(), &mm);
//#ifndef _USE_COMPLEX_TO_FIX_PR_FOR_MATLAB_7
				//m_pMATLABObj->PutMatrix(mm.GetName(), &mm);
//#else	// easwar found if imaginary matrix = 0, MATLAB automatically create real matrix, so since sending just real didn't work, this is a workaround
				//matrix m1;
				//m1 = mm;m1 = 0;
				//m_pMATLABObj->PutMatrix(mm.GetName(), &mm, &m1);
//#endif //!_USE_COMPLEX_TO_FIX_PR_FOR_MATLAB_7
				////---
			//}
			//break;
		/////	DVT 7/1/03 QA70-4753 v7.0614 MATLAB_CONSOLE_PUT_COMPLEX
		//case CMDID_PUT_COMPLEX:
		//{
			//MatrixLayer mlayReal(asArgs[1]);
			//if(!mlayReal)
			//{
				//strResult = "???\r\n " + asArgs[1];
				//strResult += " is not an Origin matrix.\r\n";
				//return;
			//}
			//Matrix<double> mmR(mlayReal);
			//
			//MatrixLayer mlayImag(asArgs[2]);
			//if(!mlayImag)
			//{
				//strResult = "???\r\n " + asArgs[2];
				//strResult += " is not an Origin matrix.\r\n";
				//return;
			//}
			//Matrix<double> mmI(mlayImag);
			//
			/////Soapy 9/19/03 CHECK_MATRIX_SIZE_BEFORE_PUT_MATRIX
			//if(mmI.GetNumRows()!=mmR.GetNumRows() || mmI.GetNumCols()!=mmR.GetNumCols())
			//{
				//strResult = "\r\nInconsistent Matrix Size.\r\n ";
				//return;
			//}
			/////END CHECK_MATRIX_SIZE_BEFORE_PUT_MATRIX
			//
			//m_pMATLABObj->PutMatrix(  nArgSize >= 4 ? asArgs[3] : mmR.GetName(), &mmR, &mmI );
			//break;
		//}
		/////	end MATLAB_CONSOLE_PUT_COMPLEX
		//case CMDID_GET_REAL:
			//for(ii = 1; ii < nArgSize; ii++)
			//{
				/////Soapy 9/26/03 REMOVE_DUPLICATED_CODE
				///*
				//bool bNew=false;
				//MatrixLayer mlay(asArgs[ii]);
				//if(!mlay)
				//{
					//mlay.Create();
					//mlay.GetPage().Rename(asArgs[ii]);
					//bNew = true;
				//}*/
				//MatrixLayer mlay;
				//bool bNew = get_Origin_matrix(asArgs[ii], mlay);
				/////END REMOVE_DUPLICATED_CODE
				//
				//Matrix<double> mm(mlay);
				/////Soapy 11/12/03 GET_REAL_MATRIX_BY_VARIABLE_NAME	
				////bSuccess = m_pMATLABObj->GetMatrix(mm.GetName(), &mm);
				//bSuccess = m_pMATLABObj->GetMatrix(asArgs[ii], &mm);
				/////END GET_REAL_MATRIX_BY_VARIABLE_NAME
				//if(!bSuccess )
				//{
					//if(bNew)
						//mlay.Destroy();
					//strResult += asArgs[ii] + " ";
				//}
			//}
			//if(!strResult.IsEmpty())
				//strResult += ": matrices not found in Matlab!\r\n";
				//
			//break;
		//case CMDID_GET_COMPLEX:
			//// may need to see how to share code with CMDID_GET_REAL
			//for(ii = 1; ii < nArgSize; ii++)
			//{
				//MatrixLayer mlay_r, mlay_i;
				//bool bNewR= get_Origin_matrix(asArgs[ii]+"r", mlay_r);
				//bool bNewI= get_Origin_matrix(asArgs[ii]+"i", mlay_i);
				//
				//Matrix<double> mr(mlay_r), mi(mlay_i);
				//bSuccess = m_pMATLABObj->GetMatrix(asArgs[ii], &mr, &mi);
				//if(!bSuccess)
				//{
					//if(bNewR)
						//mlay_r.Destroy();
					//if(bNewI)
						//mlay_i.Destroy();
					//
					//strResult += asArgs[ii] + " ";
				//}
			//}
			//if(!strResult.IsEmpty())
				//strResult += ": matrices not found in Matlab!";
				//
			//break;
			//
		///// SY 02/08/2004 QA70-7383 MATLAB_CONSOLE_SEND_WKS_COL
		//case CMDID_PUT_WKS_STRING:
		//case CMDID_PUT_WKS_REAL:
			//{
				//Dataset ds(asArgs[1]);
				//
				//if( !ds.IsValid() )
				//{
					//strResult.Format("\r\nDataset %s is invalid.\r\n", asArgs[1]); 
					//return;
				//}
				//
				//if( nArgSize == 3 && lstrcmpi(asArgs[1], asArgs[2]) )
				//{
					//Dataset dsTmp(asArgs[2]);
					//if( dsTmp.IsValid() )
					//{
						//strResult.Format("\r\nThe variable %s is one of Origin dataset name.\r\nUsage: %s DatasetName [matName]\r\n", asArgs[2], asArgs[0]);
						//return;
					//}
				//}
				//
				//if( nCmdID == CMDID_PUT_WKS_STRING )
				//{
					//StringArray sa;
					//if( !ds.GetStringArray(sa) )
						//return;
					//
					//string str;
					//make_vector_string_to_string(sa, str);
					//
					////bSuccess = m_pMATLABObj->PutString((nArgSize == 3 ? asArgs[2] : ds.GetName()), str);
					//string strCmd;
					//strCmd.Format("%s = cellstr(%s)", (nArgSize == 3 ? asArgs[2] : ds.GetName()), str);
					//bSuccess = m_pMATLABObj->Execute(strCmd, strResult);
				//}
				//else
				//{
					//matrix mm(ds);
					//matrix m1;
					//m1 = mm; m1 = 0;
					//
					//ocUtils_NANUM_to_nan((double *)mm, mm.GetNumRows() * mm.GetNumCols());
					//
					//bSuccess = m_pMATLABObj->PutMatrix((nArgSize == 3 ? asArgs[2] : ds.GetName()), &mm, &m1);
				//}
			//}
			//break;
			//
		//case CMDID_PUT_WKS_COMPLEX:
			//{
				//// Assumed that datasetname1 and datasetname2 referes to columns in Origin that have real data.
				//Dataset ds1(asArgs[1]), ds2(asArgs[2]);
				//
				//if( !ds1.IsValid() )
				//{
					//strResult.Format("\r\nDataset %s is invalid.\r\n", asArgs[1]); 
					//return;
				//}
				//
				//if( !ds2.IsValid() )
				//{
					//strResult.Format("\r\nDataset %s is invalid.\r\n", asArgs[2]); 
					//return;
				//}
				//
				//int nr1 = ds1.GetLowerBound();
				//int nr2 = ds2.GetLowerBound();
				//
				//if( nr1 != nr2 || ds1.GetSize() != ds2.GetSize() )
				//{
					//strResult.Format("\r\nDataset %s and %s is not match.\r\n", asArgs[1], asArgs[2]); 
					//return;
				//}
				//
				//matrix mmR(ds1);
				//matrix mmI(ds2);
				//
				//ocUtils_NANUM_to_nan((double *)mmR, mmR.GetNumRows() * mmR.GetNumCols());
				//ocUtils_NANUM_to_nan((double *)mmI, mmI.GetNumRows() * mmI.GetNumCols());
				//
				//bSuccess = m_pMATLABObj->PutMatrix((nArgSize == 4 ? asArgs[3] : ds1.GetName()), &mmR, &mmI);
			//}
			//break;
		///// end MATLAB_CONSOLE_SEND_WKS_COL
//
		//case CMDID_EXIT:
		//case CMDID_QUIT:
			//m_pMATLABObj->Detach();
			//GetWindow().SendMessage(WM_CLOSE);
			//break;
		//case CMDID_CLC: // clear screen display
			//m_reCntrl.Text="";
			////add_str_to_richEdit(cCmdWindow, STR_PROMPT, FALSE);
			//break;
		//}
		//return;
	//}
		
	/*
	int checkAndReturnSelectionRange(int& nStart, int& nEnd)	
	{
		m_reCntrl.GetSel(nStart, nEnd);
		
		if(nEnd<m_PromptPosition)
			return UNEDITABLE ;
		else if(nStart < m_PromptPosition)
			return PARTEDITABLE;
		else
			return EDITABLE;
	}
		
	// Check if '[',']' and '{','}' match
	bool isBracketMatch(string str, char char1, char char2)
	{
		int nLength = str.GetLength();
		int nL, nR;
		
		str.Remove(char1);
		nL = nLength - str.GetLength();
		str.Remove(char2);
		nR = nLength - nL - str.GetLength();
		
		return (nR>=nL);  ///Soapy 11/4/03  	FIX_BUG_ON_BRACKET
	}
		
	/// SY 02/10/2004 QA70-7383 MATLAB_CONSOLE_SEND_WKS_COL
	void make_vector_string_to_string(vector<string>& vs, string& str)
	{
		if( 0 == vs.GetSize() )
			return;
		
		str = "[";
		check_and_padding(vs);
		
		for( int ii = 0; ii < vs.GetSize(); ii++)
		{
			// MATLAB uses single quote and ; as delimitor
			str += "\'"+ vs[ii] + "\';";
		}
		str.Delete( str.GetLength() - 1 ); // Delete the last ;
		str += "]";
	}
	
	// Get all length and return the max length also
	int get_lengths(vector<string>& vs, vector<int> &vret)
	{
		int nMaxWidth = 0;
		int nTemp;
		int nSize = vs.GetSize();
		
		vret.SetSize(nSize);
		for(int ii = 0; ii < nSize; ii++)
		{
			nTemp = lstrlen(vs[ii]);
			if( nTemp > nMaxWidth )
				nMaxWidth = nTemp;
			
			vret[ii] = nTemp;
		}
		
		return nMaxWidth;
	}
	
	// In MATLAB string array, all rows in the bracketed expression must have the same number of columns.
	void check_and_padding(vector<string>& vs)
	{
		vector<int> vlen;
		int nMaxLen = get_lengths(vs, vlen);

		int iNumPad;
		for( int ii = 0; ii < vlen.GetSize(); ii++ )
		{
			iNumPad = nMaxLen - vlen[ii];
			if( iNumPad > 0 )
			{
				while( iNumPad-- > 0 )
					vs[ii] += " ";
			}
		}
	}
	/// end MATLAB_CONSOLE_SEND_WKS_COL	
	*/
	///End CHANGE_TO_MATLABCMDCONTROL_CLASS		
private:
	int 		m_nTimerID;
	//RichEdit	m_reCntrl;	///Jasmine 8/02/05 CHANGE_TO_MATLABCMDCONTROL_CLASS
	MatlabCmdControl m_MCCntrl;//m_reCntrl;	///Jasmine 08/25/05 VARIANT_NAME_CHANGE
	//Matlab* 	m_pMATLABObj;	///Jasmine 8/02/05 CHANGE_TO_MATLABCMDCONTROL_CLASS
	//LONG 		m_PromptPosition; ///Soapy 9/19/03 NO_DELETE_PROMPT///Jasmine 08/24/05 QA70-7998 PROMTPOSITION_UPDATE no need
	
};

static MATLABConsoleDlg MyDlg;
////////////////////////////////////////////////////////////////////////////////////
// opens the MatlabConsole
#pragma labtalk(2) //CPY 12/6/06 QA70-12736 LT_NEED_MORE_CNTRL_ON_ALLOWING_OC_FUNCS

BOOL MatlabConsole(BOOL bClose=FALSE)
{
	if(MyDlg.GetWindow())
	{
		if(!bClose)
		{
			out_str("Matlab Console already open");
			return FALSE; //already open
		}
		//we will need to close it
		return TRUE;
	}
	
	return MyDlg.Create();
}
