/*------------------------------------------------------------------------------*
 * File Name: OMLinkPage.h	 													*
 * Creation: SY 01/31/2005 QA70-1995 OC_MATHEMATICA_LINK						*
 * Purpose: OriginC Source C file												*
 * Copyright (c) ABCD Corp.	2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010		*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *  SY 2006-09-08 v8.0478 QA70-8759 NEW_NOTATION_FOR_TOOLS						*
 *	AW 10/11/07 MORE_ON_HELP													*
 *	Kenny 08/25/2009 QA81-14203 RESET_PAGE_NAME_IF_CREATED_FROM_OC				*
 *------------------------------------------------------------------------------*/

#ifndef _OMLINK_PAGE_H
#define _OMLINK_PAGE_H

#include <Dialog.h>
#include <okocUtils.h> 	///	SY 2006-09-08 v8.0478 QA70-8759 NEW_NOTATION_FOR_TOOLS

#include "OMLinkRes.h"
#include "OMLinkObj.h"
#include <o8dlg.h>


OMLinkObj g_MLObj;

class OMLinkColumnPage : public PropertyPage
{
public:
	// Constructor for OMLinkColumn page
	OMLinkColumnPage(int nID) : PropertyPage(nID) {}

	// Event handlers for OMLinkColumnPage
	EVENTS_BEGIN
		PAGE_ON_INIT(OnInitPage)
		PAGE_ON_ACTIVE(OnActivatePage)
		ON_BN_CLICKED(IDC_SENDCOL_SEND, OnClickSendCol)
		ON_BN_CLICKED(IDC_RECVCOL_RECEIVE, OnClickRecvCol)
		ON_HELPINFO(OnHelp) /// AW 10/11/07 MORE_ON_HELP

	EVENTS_END
	
	/// AW 10/11/07 MORE_ON_HELP
	BOOL OnHelp(int &nHelpID, int nIdCtrlFocus)	
	{
		nHelpID = IDD_OMATHMATIC_MAIN;
		return TRUE;
	}
	/// END MORE_ON_HELP

	BOOL OnInitPage()
	{
		m_ColSendMathVar 	= GetItem(IDC_SENDCOL_VARNAME);
		m_ColSendOrgDataSet	= GetItem(IDC_SENDCOL_DATASET);
		m_ColSendFrom		= GetItem(IDC_SENDCOL_FROM);
		m_ColSendTo		 	= GetItem(IDC_SENDCOL_TO);
		
		m_ColRecvMathVar 	= GetItem(IDC_RECVCOL_VARNAME);
		m_ColRecvOrgDataSet	= GetItem(IDC_RECVCOL_DATASET);
		m_ColRecvFrom	 	= GetItem(IDC_RECVCOL_FROM);
		
		// Initialize 
		m_ColSendFrom.Text.Format("%d", 0);
		m_ColSendTo.Text.Format("%d", 0);
		
		m_ColRecvFrom.Text.Format("%d", 0);

		return TRUE;		
	}

	BOOL OnActivatePage()
	{
		return TRUE;		
	}
	
	BOOL OnClickSendCol(Control ctrl)
	{
		if( !g_MLObj.IsLinkOpen() )
			MSG_RETURN(OMLINK_ERR_LINK_NOT_OPEN, FALSE)

	/// SY 2006-09-08 v8.0478 QA70-8759 NEW_NOTATION_FOR_TOOLS
		///	Dataset ds(m_ColSendOrgDataSet.Text);
	#if _OC_VER >= 0x0800
		Dataset ds;
		string strDataset;
		if( okoc_find_dataset(m_ColSendOrgDataSet.Text, &strDataset) )
			ds.Attach(strDataset);
		else
			ds.Attach(m_ColSendOrgDataSet.Text);	
	#else
		Dataset ds(m_ColSendOrgDataSet.Text);
	#endif
	/// end NEW_NOTATION_FOR_TOOLS

		if( !ds.IsValid() )
			MSG_RETURN(OMLINK_ERR_DATASET_INVALID, FALSE)
		
		if( ds.GetSize() < 1 )
			MSG_RETURN(OMLINK_ERR_DATASET_EMPTY, FALSE)
			
		int iFirstRow, iLastRow;
		int iSendFrom = atoi(m_ColSendFrom.Text);
		int iSendTo = atoi(m_ColSendTo.Text);
		
		// Check first row
		if( iSendFrom < 0 )
			MSG_RETURN(OMLINK_ERR_DATASET_ROW_INVALID, FALSE)
		else if( iSendFrom == 0 )
			iFirstRow = ds.GetLowerBound();
		else
		{
			iFirstRow = iSendFrom - 1; 
			if( iFirstRow < ds.GetLowerBound() || iFirstRow >= ds.GetUpperBound() )
				MSG_RETURN(OMLINK_ERR_DATASET_ROW_OUT_OF_RANGE, FALSE)
		}
		
		// Check last row
		if( iSendTo < 0 )
			MSG_RETURN(OMLINK_ERR_DATASET_ROW_INVALID, FALSE)
		else if( iSendTo == 0 )
			iLastRow = ds.GetUpperBound();
		else
		{
			iLastRow = iSendTo - 1; 
			if( iLastRow < ds.GetLowerBound() || iLastRow > ds.GetUpperBound() )
				MSG_RETURN(OMLINK_ERR_DATASET_ROW_OUT_OF_RANGE, FALSE)
		}
		
		if( iFirstRow > iLastRow )
			MSG_RETURN(OMLINK_ERR_FIRST_ROW_GREATER_THAN_LAST_ROW, FALSE)
		
		int iNumRows = iLastRow - iFirstRow + 1;
		double *pdCol = (double *)malloc(sizeof(double) * iNumRows);
	
		for( int i = 0; i < iNumRows; i++ )
			pdCol[i] = ds[i + iFirstRow];
	
		BOOL bSuccess = TRUE;
		if( g_MLObj.SendArray(m_ColSendMathVar.Text, pdCol, iNumRows) )
			MSG_SET(OMLINK_ERR_SENDARRAY_FAILED, bSuccess, FALSE)
		
		free(pdCol);
		
		return bSuccess;
	}
	
	BOOL OnClickRecvCol(Control ctrl)
	{
		if( !g_MLObj.IsLinkOpen() )
			MSG_RETURN(OMLINK_ERR_LINK_NOT_OPEN, FALSE)
		
		/// SY 2006-09-08 v8.0478 QA70-8759 NEW_NOTATION_FOR_TOOLS
		///	Dataset ds(m_ColRecvOrgDataSet.Text);
	#if _OC_VER >= 0x0800
		Dataset ds;
		string strDataset;
		if( okoc_find_dataset(m_ColRecvOrgDataSet.Text, &strDataset) )
			ds.Attach(strDataset);
		else
			ds.Attach(m_ColRecvOrgDataSet.Text);	
	#else
		Dataset ds(m_ColRecvOrgDataSet.Text);
	#endif
		/// end NEW_NOTATION_FOR_TOOLS

		if( !ds.IsValid() )
			MSG_RETURN(OMLINK_ERR_DATASET_INVALID, FALSE)
		
		int iFirstRow;
		int iRecvFrom = atoi(m_ColRecvFrom.Text);
		
		// Check row
		if( iRecvFrom < 0 )
			MSG_RETURN(OMLINK_ERR_DATASET_ROW_INVALID, FALSE)
		else if( iRecvFrom == 0 )
			iFirstRow = ds.GetLowerBound();
		else
			iFirstRow = iRecvFrom - 1; 
		
		double *pdRecvData;
		long lSize;

		if( g_MLObj.RecvArray(m_ColRecvMathVar.Text, ds, iFirstRow) )
			MSG_RETURN(OMLINK_ERR_RECVARRAY_FAILED, FALSE)
		
		ds.Update(FALSE, REDRAW_REFRESH);
		
		return TRUE;
	}
	
private:
	Edit m_ColSendMathVar;
	Edit m_ColSendOrgDataSet;
	Edit m_ColSendFrom;
	Edit m_ColSendTo;
	
	Edit m_ColRecvMathVar;
	Edit m_ColRecvOrgDataSet;
	Edit m_ColRecvFrom;
	
	Button m_ColSend;
	Button m_ColRecv;
};

class OMLinkMatrixPage : public PropertyPage
{
public:
	// Constructor for OMLinkMatrixPage
	OMLinkMatrixPage(int nID) : PropertyPage(nID) {}

	// Event handlers for OMLinkMatrix page
	EVENTS_BEGIN
		PAGE_ON_INIT(OnInitPage)
		PAGE_ON_ACTIVE(OnActivatePage)
		ON_BN_CLICKED(IDC_SENDMAT_ALL, OnClickSendAll)
		ON_BN_CLICKED(IDC_SENDMAT_SEND, OnClickSendMat)
		ON_BN_CLICKED(IDC_RECVMAT_RECEIVE, OnClickRecvMat)
	EVENTS_END

	BOOL OnInitPage()
	{
		m_MatSendMathVar = GetItem(IDC_SENDMAT_VARNAME);
		m_MatSendOrgMatName = GetItem(IDC_SENDMAT_MATNAME);
		
		m_MatSendAll = GetItem(IDC_SENDMAT_ALL);
		
		m_MatSendFirstCol = GetItem(IDC_SENDMAT_FIRSTCOL);
		m_MatSendLastCol = GetItem(IDC_SENDMAT_LASTCOL);
		m_MatSendFirstRow = GetItem(IDC_SENDMAT_FIRSTROW);
		m_MatSendLastRow = GetItem(IDC_SENDMAT_LASTROW);
		
		m_MatRecvMathVar = GetItem(IDC_RECVMAT_VARNAME);
		m_MatRecvOrgMatName = GetItem(IDC_RECVMAT_MATNAME);
		m_MatRecvFirstCol = GetItem(IDC_RECVMAT_FIRSTCOL);
		m_MatRecvFirstRow = GetItem(IDC_RECVMAT_FIRSTROW);
	
		// Initialize
		m_MatSendFirstCol.Text.Format("%d", 1);
		m_MatSendLastCol.Text.Format("%d", 0);
		m_MatSendFirstRow.Text.Format("%d", 1);
		m_MatSendLastRow.Text.Format("%d", 0);
		
		m_MatRecvFirstCol.Text.Format("%d", 1);
		m_MatRecvFirstRow.Text.Format("%d", 1);
		
		m_MatSendAll.Check = true;
		UpdateSendRange(false);
		
		return TRUE;		
	}

	BOOL OnActivatePage()
	{
		return TRUE;		
	}

	BOOL OnClickSendAll(Control ctrl)
	{
		BOOL bEnable = !m_MatSendAll.Check;

		UpdateSendRange(bEnable);
		return TRUE;
	}

	BOOL OnClickSendMat(Control ctrl)
	{
		if( !g_MLObj.IsLinkOpen() )
			MSG_RETURN(OMLINK_ERR_LINK_NOT_OPEN, FALSE)

		/// SY 2006-09-08 v8.0478 QA70-8759 NEW_NOTATION_FOR_TOOLS
		///	MatrixObject omatobj(m_MatSendOrgMatName.Text, 0);
	#if _OC_VER >= 0x0800
		MatrixObject omatobj;
		string strDataset;
		if( okoc_find_dataset(m_MatSendOrgMatName.Text, &strDataset, NULL, DATASET_MATRIX) )
			omatobj.Attach(strDataset);
		else
			omatobj.Attach(m_MatSendOrgMatName.Text);	
	#else
		MatrixObject omatobj(m_MatSendOrgMatName.Text, 0);
	#endif
		/// end NEW_NOTATION_FOR_TOOLS

		if( !omatobj.IsValid() )
			MSG_RETURN(OMLINK_ERR_MATRIX_INVALID, FALSE)
		
		// Determine last column to send.
		int iFirstCol = atoi(m_MatSendFirstCol.Text);
		int iLastCol = atoi(m_MatSendLastCol.Text);
		
		if( iLastCol == 0 || iLastCol > omatobj.GetNumCols() )
			iLastCol = omatobj.GetNumCols();

		if( iFirstCol > iLastCol )
			MSG_RETURN(OMLINK_ERR_MATRIX_COL_INVALID, FALSE)
		
		long lNumCols = (iLastCol - iFirstCol + 1);
			
		// Determine last row to send.
		int iFirstRow = atoi(m_MatSendFirstRow.Text);
		int iLastRow = atoi(m_MatSendLastRow.Text);
		
		if( iLastRow == 0 || iLastRow > omatobj.GetNumRows() )
			iLastRow = omatobj.GetNumRows();
	
		if( iFirstRow > iLastRow )
			MSG_RETURN(OMLINK_ERR_MATRIX_ROW_INVALID, FALSE)
			
		long lNumRows = (iLastRow - iFirstRow + 1);

		// Allocate memory to hold the matix values.
		double *pdMatrixValues = (double *)malloc(sizeof(double) * lNumCols * lNumRows);
		if( !pdMatrixValues )
			MSG_RETURN(OMLINK_ERR_MEMORY_ALLOCATION_FAILED, FALSE)
	
		// Copy the matrix values into the allocated memory.
		int i = 0;
		matrix omat(omatobj);
		for( long lCol = iFirstCol - 1; lCol < iLastCol; lCol++ )
		{
			for( long lRow = iFirstRow - 1; lRow < iLastRow; lRow++ )
			{
				pdMatrixValues[i++] = omat[lRow][lCol];
			}
		}
	
		BOOL bSuccess = TRUE;
		if( g_MLObj.SendMatrix(m_MatSendMathVar.Text, pdMatrixValues, lNumCols, lNumRows) )
			MSG_SET(OMLINK_ERR_SENDARRAY_FAILED, bSuccess, FALSE)
		
		free(pdMatrixValues);
		
		return bSuccess;
	}
	
	BOOL OnClickRecvMat(Control ctrl)
	{
		if( !g_MLObj.IsLinkOpen() )
			MSG_RETURN(OMLINK_ERR_LINK_NOT_OPEN, FALSE)
		
		/// SY 2006-09-08 v8.0478 QA70-8759 NEW_NOTATION_FOR_TOOLS
		///	MatrixObject omatobj(m_MatRecvOrgMatName.Text, 0);
	#if _OC_VER >= 0x0800
		MatrixObject omatobj;
		string strDataset;
		if( okoc_find_dataset(m_MatRecvOrgMatName.Text, &strDataset, NULL, DATASET_MATRIX) )
			omatobj.Attach(strDataset);
		else
			omatobj.Attach(m_MatRecvOrgMatName.Text);	
	#else
		MatrixObject omatobj(m_MatRecvOrgMatName.Text, 0);
	#endif
		/// end NEW_NOTATION_FOR_TOOLS
		
		if( !omatobj.IsValid() )
			MSG_RETURN(OMLINK_ERR_MATRIX_INVALID, FALSE)
		
		matrix omat(omatobj, TRUE);
		int iFirstCol = atoi(m_MatRecvFirstCol.Text);
		int iFirstRow = atoi(m_MatRecvFirstRow.Text);

		// Get matrix values from Mathematica.
		if( g_MLObj.RecvMatrix(m_MatRecvMathVar.Text, omat, iFirstCol, iFirstRow) )
			MSG_RETURN(OMLINK_ERR_RECVMATRIX_FAILED, FALSE)
	
		// Update Origin object
		/// SY 2007-01-15 v8.0542 QA70-8759 NEW_NOTATION_FOR_TOOLS
		///	Matrix oMat(m_MatRecvOrgMatName.Text);
		Matrix oMat(strDataset);
		/// end NEW_NOTATION_FOR_TOOLS
		oMat.Update(FALSE, REDRAW_REFRESH);
		return TRUE;
	}

private:
	
	void UpdateSendRange(BOOL bEnable)
	{
		m_MatSendFirstCol.Enable = bEnable;
		m_MatSendLastCol.Enable = bEnable;
		m_MatSendFirstRow.Enable = bEnable;
		m_MatSendLastRow.Enable = bEnable;
	}

private:
	Edit m_MatSendMathVar;
	Edit m_MatSendOrgMatName;
	
	Button m_MatSendAll;
	
	Edit m_MatSendFirstCol;
	Edit m_MatSendLastCol;
	Edit m_MatSendFirstRow;
	Edit m_MatSendLastRow;
	
	Edit m_MatRecvMathVar;
	Edit m_MatRecvOrgMatName;
	Edit m_MatRecvFirstCol;
	Edit m_MatRecvFirstRow;
	
	Button m_MatSend;
	Button m_MatRecv;
};

class OMLinkFuncPage : public PropertyPage
{
public:
	// Constructor for OMLinkFuncPage
	OMLinkFuncPage(int nID) : PropertyPage(nID) {}

	// Event handlers for OMLinkFuncPage
	EVENTS_BEGIN
		PAGE_ON_INIT(OnInitPage)
		PAGE_ON_ACTIVE(OnActivatePage)
		ON_BN_CLICKED(IDC_FUNC_USE_NUMPOINTS, OnClickHow)
		ON_BN_CLICKED(IDC_FUNC_USE_INCREMENT, OnClickHow)
		ON_BN_CLICKED(IDC_FUNC_PLOT, OnClickPlot)
	EVENTS_END

	BOOL OnInitPage()
	{
		m_FuncDefine = GetItem(IDC_FUNC_DEFINE);
		m_FuncFrom = GetItem(IDC_FUNC_FROM);
		m_FuncTo = GetItem(IDC_FUNC_TO);
		m_FuncPoints = GetItem(IDC_FUNC_NUMPOINTS);
		m_FuncInc = GetItem(IDC_FUNC_INCREMENT);
		
		m_FuncWks = GetItem(IDC_FUNC_WKSNAME);
		m_FuncGraph = GetItem(IDC_FUNC_GRAPHNAME);
	
		CheckRadioButton(IDC_FUNC_USE_NUMPOINTS, IDC_FUNC_USE_INCREMENT, IDC_FUNC_USE_NUMPOINTS);
		m_FuncInc.Enable = false;
		
		return TRUE;		
	}

	BOOL OnActivatePage()
	{
		return TRUE;		
	}

	BOOL OnClickHow(Control ctrl)
	{
		int nMethod = GetCheckedRadioButton(IDC_FUNC_USE_NUMPOINTS, IDC_FUNC_USE_INCREMENT);
		switch( nMethod )
		{
		case IDC_FUNC_USE_NUMPOINTS:
			m_FuncPoints.Enable = true;
			m_FuncInc.Enable = false;
			break;
			
		case IDC_FUNC_USE_INCREMENT:
			m_FuncPoints.Enable = false;
			m_FuncInc.Enable = true;
			break;

		default:
			return false;
		}
		
		return true;
	}
	
	BOOL OnClickPlot(Control ctrl)
	{
		if( !g_MLObj.IsLinkOpen() )
			MSG_RETURN(OMLINK_ERR_LINK_NOT_OPEN, FALSE)
		
		Worksheet wks(m_FuncWks.Text);
		if( !wks.IsValid() && !wks.Create(NULL , CREATE_HIDDEN) )
			return FALSE;
		
		char szXStep[MAXLINE];
	
		if( GetCheckedRadioButton(IDC_FUNC_USE_NUMPOINTS, IDC_FUNC_USE_INCREMENT) == IDC_FUNC_USE_INCREMENT )
			lstrcpy(szXStep, m_FuncInc.Text);  // Increment
		else
		{
			// Points
			int iNumPoints = atoi(m_FuncPoints.Text);
			if( iNumPoints < 2 )
				iNumPoints = 100;
			sprintf(szXStep, "((%s)-(%s))/%d", m_FuncTo.Text, m_FuncFrom.Text, iNumPoints - 1);
		}
			
		// Allocate memory for storing iutput string.
		HGLOBAL hMem = GlobalAlloc(GMEM_ZEROINIT, OCML_INPUT_BUF);
		LPSTR lpstrMem = (LPSTR)GlobalLock(hMem);
		
		// Build expression string to calculate table of X values.
		sprintf(lpstrMem, "oxtable = Table[x,{x,%s,%s,%s}]//N", m_FuncFrom.Text, m_FuncTo.Text, szXStep);
		g_MLObj.Evaluate(lpstrMem);
	
		// Build expression string to calculate table of Y values.
		sprintf(lpstrMem, "oytable = Table[%s,{x,%s,%s,%s}]//N", m_FuncDefine.Text, m_FuncFrom.Text, m_FuncTo.Text, szXStep);
		g_MLObj.Evaluate(lpstrMem);
		
		// Free allocated memory.
		GlobalFree(hMem);

		Dataset dsXData(wks, 0);
		if( g_MLObj.RecvArray("oxtable", dsXData) )
			MSG_RETURN(OMLINK_ERR_RECVARRAY_FAILED, FALSE)
		dsXData.Update(FALSE, REDRAW_REFRESH);
	
		Dataset dsYData(wks, 1);
		if( g_MLObj.RecvArray("oytable", dsYData) )
			MSG_RETURN(OMLINK_ERR_RECVARRAY_FAILED, FALSE)
		dsYData.Update(FALSE, REDRAW_REFRESH);

		GraphPage gp;
		/// Kenny 08/25/2009 QA81-14203 RESET_PAGE_NAME_IF_CREATED_FROM_OC
		//gp.Create("origin", CREATE_VISIBLE);
		gp.Create("origin", CREATE_VISIBLE|CREATE_ENUM_EXIST_PAGE);
		/// End QA81-14203 RESET_PAGE_NAME_IF_CREATED_FROM_OC
		GraphLayer gl = gp.Layers();
		
		if( gl )
			gl.AddPlot(wks);
		
		return TRUE;
	}
	
private:
	Edit m_FuncDefine;
	Edit m_FuncFrom;
	Edit m_FuncTo;
	Edit m_FuncPoints;
	Edit m_FuncInc;
	
	Edit m_FuncWks;
	Edit m_FuncGraph;
	
	Button m_FuncPlot;
};

class OMLinkEvalPage : public PropertyPage
{
public:
	// Constructor for OMLinkEvalPage
	OMLinkEvalPage(int nID) : PropertyPage(nID) {}

	// Event handlers for OMLinkEvalPage
	EVENTS_BEGIN
		PAGE_ON_INIT(OnInitPage)
		PAGE_ON_ACTIVE(OnActivatePage)
		ON_KEY(IDC_EVAL_INPUT, OnKeyCmdWindow)
		ON_BN_CLICKED(IDC_EVAL_EVALUATE, OnClickEvaluate)
	EVENTS_END

	BOOL OnInitPage()
	{
		m_EvalInput = GetItem(IDC_EVAL_INPUT);
		m_EvalOutput = GetItem(IDC_EVAL_OUTPUT);
	
		return TRUE;		
	}

	BOOL OnActivatePage()
	{
		return TRUE;		
	}
	
	BOOL OnClickEvaluate(Control ctrl)
	{
		return Evaluate();
	}
	
	//return FALSE if not handled, and continue to be processed
	//return TRUE will stop default processing
	BOOL OnKeyCmdWindow(Control ctrl, UINT msg, UINT wParam, UINT lParam)
	{
		if( msg == WM_KEYDOWN && VK_RETURN == wParam && (0x8000 & GetKeyState(VK_SHIFT)) )
			Evaluate();
		
		return FALSE; // return FALSE for not eating message for Enter key in Input window
	}	
	
protected:
	
	BOOL Evaluate()
	{
		if( !g_MLObj.IsLinkOpen() )
			MSG_RETURN(OMLINK_ERR_LINK_NOT_OPEN, FALSE)
		
		char szInput[OCML_INPUT_BUF], szOutput[OCML_OUTPUT_BUF];
		lstrcpyn(szInput, m_EvalInput.Text, OCML_INPUT_BUF);
		
		if( 0 == g_MLObj.Evaluate(szInput, szOutput) )
			MSG_RETURN(OMLINK_ERR_EVALUATE, FALSE);
		
		m_EvalOutput.Text += szOutput;
		return TRUE;
	}
	
private:
	
	Edit m_EvalInput;
	Edit m_EvalOutput;
	
	Button m_Evaluate;
};



class OMLinkPlaceHolder : public PropertySheet
{
public:
	OMLinkPlaceHolder()
	{
		m_OMLinkColumnPage.SetID(IDD_OMLINK_COLUMN);
		AddPage(m_OMLinkColumnPage);
		m_OMLinkMatrixPage.SetID(IDD_OMLINK_MATRIX);
		AddPage(m_OMLinkMatrixPage);
		m_OMLinkFuncPage.SetID(IDD_OMLINK_FUNC);
		AddPage(m_OMLinkFuncPage);
		m_OMLinkEvalPage.SetID(IDD_OMLINK_EVAL);
		AddPage(m_OMLinkEvalPage);
	}

	// Event handlers for OMLinkEvalPage
	EVENTS_BEGIN
		ON_KEY(IDC_EVAL_INPUT, OnKeyCmdWindow)
	EVENTS_END

	void InitMaps()
	{
		InitMsgMap();
		m_OMLinkColumnPage.InitMsgMap();
		m_OMLinkMatrixPage.InitMsgMap();
		m_OMLinkFuncPage.InitMsgMap();
		m_OMLinkEvalPage.InitMsgMap();
	}

	//return FALSE if not handled, and continue to be processed
	//return TRUE will stop default processing
	BOOL OnKeyCmdWindow(Control ctrl, UINT msg, UINT wParam, UINT lParam)
	{
		return m_OMLinkEvalPage.OnKeyCmdWindow(ctrl, msg, wParam, lParam);
	}	
	
	OMLinkColumnPage m_OMLinkColumnPage;
	OMLinkMatrixPage m_OMLinkMatrixPage;
	OMLinkFuncPage m_OMLinkFuncPage;
	OMLinkEvalPage m_OMLinkEvalPage;
};


class OMLinkDialog : public Dialog
{
public:
	OMLinkDialog() : Dialog(IDD_OMLINK, "..\..\OCMmLink")
	{
	}

	int Create(HWND hWndParent)
	{
		InitMsgMap();
		
		DWORD dwDlgOptions = 0;
		
		int nRet = Dialog::Create(hWndParent, dwDlgOptions);
		
		return nRet;
	}

protected:
///----------------- Message Map ----------------
	EVENTS_BEGIN
		PAGE_ON_INIT(OnInitDialog)
		ON_DESTROY(OnDestroy)
	EVENTS_END
///----------------------------------------------
	
	BOOL OnInitDialog()
	{
		m_PlaceHolder.Create(IDC_TAB_PLACEHOLDER, *this);
		m_PlaceHolder.InitMaps();

		g_MLObj.OpenLink();

		return TRUE;
	}
	
	BOOL OnDestroy()
	{
		g_MLObj.CloseLink();
		return TRUE;
	}
	
	OMLinkPlaceHolder m_PlaceHolder;
};


#endif // _OMLINK_PAGE_H