/*------------------------------------------------------------------------------*
 * File Name: XYZ2MatDlg.cpp 													*
 * Creation: Sim 02-27-2009														*
 * Purpose: OriginC Source C file												*
 * Copyright (c) ABCD Corp.	2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010		*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	Sim 09-25-2009 QA80-13783 CHANGE_PROTOTYPE_AND_ALGORITHM_FOR_EXAMINATION	*
 *	Sim 09-16-2009 IMPROVE_GRIDDING_ERROR_REPORT								*
 *------------------------------------------------------------------------------*/
 
////////////////////////////////////////////////////////////////////////////////////
// Including the system header file Origin.h should be sufficient for most Origin
// applications and is recommended. Origin.h includes many of the most common system
// header files and is automatically pre-compiled when Origin runs the first time.
// Programs including Origin.h subsequently compile much more quickly as long as
// the size and number of other included header files is minimized. All NAG header
// files are now included in Origin.h and no longer need be separately included.
//
// Right-click on the line below and select 'Open "Origin.h"' to open the Origin.h
// system header file.
#include <Origin.h>
#include <Array.h>
#include <..\Originlab\DialogEx.h>

#define BASE_WINDOW		MultiPaneDlg
#include <..\Originlab\DynaDlg.h>

#include <analysis_utils.h>

#include "XYZ2Mat.h"
#include "XYZ2MatControl.h"
#include "XYZ2MatDlg.h"

////////////////////////////////////////////////////////////////////////////////////
// Start your functions here.
#define PROFILE_HRGLASS			waitCursor junk;
#define _SHOW_TIME				Profiler junk2;
///Sophy 9/6/2010 ORG-849 SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING move to xyz2mat.oxf
//#define STR_DLG_NAME	_L("XYZ Gridding: Convert Worksheet to Matrix")
///end SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING
#define STR_TAB_XY_RANGE		_L("XY Range")
#define STR_TAB_X_HISTOGRAM		_L("X Steps")	///Leo 2005-9-19
#define STR_TAB_Y_HISTOGRAM		_L("Y Steps")
#define STR_TAB_XYZ_WIREFRAME	_L("Preview Result")

//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////  XYZ2MatDlg  ////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////

static HWND s_hdlg;

void PostMsgToXYZ2MatDlg(string str)
{
	Window win(s_hdlg);
	if(win)
	{
		//if(0 == str.CompareNoCase("rect"))
		//{
			//win.PostMessage(WM_USER_ON_MOVE_RECT);
			//return;
		//}

		if (	0 == str.CompareNoCase("Left")
			||	0 == str.CompareNoCase("Right")
			||	0 == str.CompareNoCase("Top")
			||	0 == str.CompareNoCase("Bottom")
			)
		{
			win.PostMessage(WM_USER_XYZ2MAT_DLG_MOVE_RESTRICTION_LINE);
		}
	}
}
///Sophy 9/6/2010 ORG-849 SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING
//XYZ2MatDlg::XYZ2MatDlg()
XYZ2MatDlg::XYZ2MatDlg(LPCSTR lpcszDlgName)
///end SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING
:DynaDlg(IDD_XYZ_GRIDDING_DLG, NULL, "Odlg8", true)
{
	m_strDlgName = lpcszDlgName;	///Sophy 9/6/2010 ORG-849 SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING

	// no hope to go m_DynaCntrl.SetEventCallback();
	//SetEventCallback(NULL, pfnEvent);
	m_pEventNew = getEventFunction();
}

static ErrorInfo s_errEvent1;
static int _xyz2mat_event1(TreeNode& tr, int nRow, int nEvent, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& getNCountainer, string& strAux, string& strErrMsg)
{
	DECLARE_BUTTON_ENABLES   //support more buttons enable/disable
	
	bOKEnable = s_errEvent1.bHasNoError;
	strErrMsg = s_errEvent1.strErrMsg;
	
	return true;
}

PEVENT_GETN XYZ2MatDlg::getEventFunction()
{
	return _xyz2mat_event1;
}

int XYZ2MatDlg::DoModalEx(TreeNode& trGetN, HWND hParent) // = NULL
{
	TreeNode tr = InitTree();
	tr.Replace(trGetN.Clone());
	
	InitMsgMap();// will be called from internal later
	return DynaDlg::DoModal(hParent);
}

void XYZ2MatDlg::UpdateEditTreeNode(TreeNode& trGetN)
{
	trGetN.Replace(GetTree().Clone());
}

BOOL XYZ2MatDlg::OnInitDialog()
{
	PROFILE_HRGLASS		

	vector<string>  vstrTipsUpDown(2);
	vstrTipsUpDown[0] = _L("Show Preview (slower)");//maybe time-consuming)");	///Jasmine 05/04/07 by Mike's request
	vstrTipsUpDown[1] = _L("Hide Preview (faster)");//this's time-saving)");
	///Sophy 9/6/2010 ORG-849 SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING
	//DynaDlg::OnInitDialog(IDC_XYZ_SETTINGS_DYNA_GRID, IDC_XYZ_SHOW_GRAPH, IDC_XYZ_GRAPH_TAB, vstrTipsUpDown, STR_DLG_NAME);
	DynaDlg::OnInitDialog(IDC_XYZ_SETTINGS_DYNA_GRID, IDC_XYZ_SHOW_GRAPH, IDC_XYZ_GRAPH_TAB, vstrTipsUpDown, m_strDlgName);
	///end SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING

	InitDynaControl(IDC_XYZ_SETTINGS_DYNA_GRID);
	
	//Sim, need to move from OnReady(), for fix very narrow panel, don't know why.
	UpdateDlgSize();
	UpdateDlgShow();
	///Sophy 9/6/2010 ORG-849 SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING
	//SetDialogTitle(STR_DLG_NAME);
	SetDialogTitle(m_strDlgName);
	///end SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING

	BitmapRadioButton btnSaveAs = GetItem(IDC_SAVE_AS_BTN);
	vector<string> vsTips;
	btnSaveAs.Init(1, IDB_DROP_DOWN_UP, 16, vsTips);

	InitThemeControls(this, GetTree(), IDC_THEME_COMB, IDC_STATIC_THEME, IDC_SAVE_BTN, IDC_SAVE_AS_BTN);	
	
	m_txtStatus = GetItem(IDC_XYZ_STATUS_TEXT);
	m_txtStatus.Visible = false;		//------ Folger 08/07/08 SHOULD_USE_STANDARD_DYNA_ERROR_HANDLING_INSTEAD_OF_TEXT_STATUS_BAR

	s_hdlg = GetSafeHwnd();
	
	return true;
}

void XYZ2MatDlg::InitPreviewGraphs()
{
	// init graph controls
	Array<Control&> arrCtrls;
	arrCtrls.SetAsOwner(true);
	for(int nGraph = 0; nGraph < XYZ_GRAPH_TOTAL_GRAPHS; nGraph++) 
	{
		uint nID = getTabGraphContrlID(nGraph);
		ASSERT(nID > 0);
		Control *pCtrl = new Control(GetItem(nID));
		arrCtrls.Add(*pCtrl);
	}
	m_GPCManager.InitGraphControls(arrCtrls);
	
	// init tab control and Preview checkbox
	TabControl tabCtrl = GetItem(IDC_XYZ_GRAPH_TAB);
	tabCtrl.InsertItem(XYZ_TAB_INDEX_XY_RANGE, STR_TAB_XY_RANGE);
	tabCtrl.InsertItem(XYZ_TAB_INDEX_X_HISTOGRAM, STR_TAB_X_HISTOGRAM);
	tabCtrl.InsertItem(XYZ_TAB_INDEX_Y_HISTOGRAM, STR_TAB_Y_HISTOGRAM);
	tabCtrl.InsertItem(XYZ_TAB_INDEX_PREVIEW_RESULT, STR_TAB_XYZ_WIREFRAME);
	
	Button chkPreview = GetItem(IDC_XYZ_QUICK_PREVIEW_CHK);
	m_GPCManager.InitControls(tabCtrl, chkPreview, IsBottomPaneShown());	
}


BOOL XYZ2MatDlg::OnReady()
{	
	/*
	m_XYZGridding.GetXYZGriddingSettings()->UpdateGUI(GetTree().settings, false);
	SetInput();
	ErrorInfo err;
	m_XYZGridding.OnChange(XYZ_CHANGE_INIT, err);
	m_XYZGridding.GetXYZGriddingSettings()->UpdateGUI(GetTree().settings, true);
	
	InitPreviewGraphs();
	m_GPCManager.PreChangeTab(XYZ_CHANGE_INIT, m_XYZGridding.GetXYZGriddingSettings(), m_XYZGridding.GetXYZGrdiddingDataInfo());
	UpdatePreviewDatas();
	UpdatePreviewGraphs();
	
	s_errEvent1 = err;
	*/
	InitPreviewGraphs();
	SetInput();
	
	//Sim, need to move to OnInitDialog(), for fix very narrow panel, don't know why.
	//UpdateDlgSize();
	//UpdateDlgShow();
	
	UpdateDynaControl(true, GETNEVENT_ON_INIT);
	
	//----- CPY 10/2/08 QA70-12323 LSI_REPORTED_XYZ_GRIDDING_OPENS_TOO_NARROW_FOR_SOME_DATA
	// should do this at the end as onDataChange might lead to unwanted resize call before we have received init size in OnRestoreSize
	SetInitReady();
	//-----	
	return true;
}

BOOL XYZ2MatDlg::OnDestroy()
{
	s_hdlg = NULL;
	return DynaDlg::OnDestroy();
}


BOOL XYZ2MatDlg::OnDlgResize(int nType, int cx, int cy)
{
	if(!IsInitReady())
		return TRUE;
	
	MoveControlsHelper	_temp(this);		///Jasmine 03/27/06 DLG_RESIZE_PAINT_MESS
	uint nButtonIDs[] = {IDCANCEL, IDOK, IDC_XYZ_QUICK_PREVIEW_CHK, 0};
	DynaDlg::OnDlgResize(nButtonIDs, cx, cy, false);

	resizeTopPaneControl();

	
	RECT rTab;
	getTabRect(rTab);
	m_GPCManager.OnAfterDlgResize(rTab);


	return TRUE;
}

void XYZ2MatDlg::SetDialogTitle(LPCSTR lpcszTitle)
{
	Window wDlg=GetWindow();
	wDlg.Text = lpcszTitle;
}

void XYZ2MatDlg::resizeTopPaneControl()
{	
	Control ctrlGrid = GetItem(IDC_XYZ_SETTINGS_DYNA_GRID);
	RECT rr;
	GetClientRect(ctrlGrid, rr);

	int nEdge = GetControlGap(), nx = nEdge, ny = nEdge, cx = rr.right, cy = rr.bottom;
	vector<uint> vnThemeSaveGroup = {IDC_THEME_TEXT, IDC_THEME_COMB, IDC_SAVE_BTN, IDC_SAVE_AS_BTN, 0};
	ArrangeControlsLeftRight(vnThemeSaveGroup, nx, ny, cx, IDC_THEME_COMB);

	int		nErrMessageHeight = GetDlgStatusMsgBoxHeight(cx - 2*nEdge );

	RECT rBtn;
	rBtn.left = rr.left;
	rBtn.right = rr.right;
	if(nErrMessageHeight )
	{
		rBtn.bottom = rr.bottom;
		rBtn.top = rBtn.bottom - nErrMessageHeight;
		rr.bottom = rBtn.top - nEdge;
		MoveControl(m_btnErrMessage, rBtn);
		m_btnErrMessage.Visible = true;
		MoveControl(ctrlGrid, rr);
	}
	else
		m_btnErrMessage.Visible = false;

	MoveControl(IDC_XYZ_STATUS_TEXT, nx, cy+nEdge);
}


BOOL XYZ2MatDlg::OnRestoreSize(DWORD dwSizeInfo)
{
	void * p = (void*)dwSizeInfo;
	DLGSIZEINFO *pSz = (DLGSIZEINFO*)p;
	///Sophy 9/6/2010 ORG-849 SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING
	//lstrcpyn(pSz->szDialogName, STR_DLG_NAME, MAXLINE);
	lstrcpyn(pSz->szDialogName, m_strDlgName, MAXLINE);
	///end SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING
	pSz->top = -1;
	pSz->left = -1;
	pSz->width = 800; //hard code, just for only one function
	pSz->height = 400;

	///Sophy 9/6/2010 ORG-849 SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING
	//if(0 == HasPreviousSize(STR_DLG_NAME))
	if(0 == HasPreviousSize(m_strDlgName))
	///end SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING
	{
		SetBottomPaneHeight(300);
	}
	return TRUE;
}
BOOL XYZ2MatDlg::OnInitSize(int &left, int &top, int &right, int  &bottom)
{
	return FALSE;
}
int	XYZ2MatDlg::GetTotalHeight(bool bMin)
{
	return 350;
}
int	XYZ2MatDlg::GetTotalWidth(bool bMin)
{
	return 460;
}

void XYZ2MatDlg::getTabRect(RECT& rTab)
{
	TabControl tab = GetItem(IDC_XYZ_GRAPH_TAB);
	GetClientRect(tab, rTab);
}

BOOL XYZ2MatDlg::OnShowBottomPane(Control ctrl)
{
	PROFILE_HRGLASS

	DynaDlg::OnShowBottomPane(ctrl);

	RECT rTab;
	getTabRect(rTab);
	m_GPCManager.OnShowBottomPane(ctrl, IsBottomPaneShown(), rTab);
	return true;
}

BOOL XYZ2MatDlg::OnChangePreviewMode(Control ctrl)
{
	PROFILE_HRGLASS
	
	m_GPCManager.OnChangePreviewMode(ctrl);
	UpdatePreviewDatas();
	UpdatePreviewGraphs();
	
	return TRUE;
}

BOOL XYZ2MatDlg::OnTabChange(Control ctrl)
{
	PROFILE_HRGLASS

	m_GPCManager.OnTabChange(ctrl);
	UpdatePreviewDatas();
	UpdatePreviewGraphs();
	
	return TRUE;
}

//virtual
void XYZ2MatDlg::InvokeGlobalEventOnInitDialog()
{
	OnChange(XYZ_CHANGE_INIT);	
	invokeBasicGlobalEvent(GETNE_ON_INIT);
}

//virtual
void XYZ2MatDlg::InvokeGlobalEventOnThemeChange()
{
	OnChange(XYZ_CHANGE_INIT); // theme change is equal to initialization
	invokeBasicGlobalEvent(GETNE_ON_THEME);
}

void XYZ2MatDlg::OnAfterValueChange(int nRow, int nCol)
{
	PROFILE_HRGLASS	//will be slow if big data is used
	
	TreeNode trGUI = m_DynaCntrl.GetTreeNode(-1);
	TreeNode trNode = m_DynaCntrl.GetTreeNode(nRow);
	if(!trGUI || !trNode)
	{
		error_report("Get Edit TreeNode fail");
		return;
	}

	//m_XYZGridding.GetXYZGriddingSettings()->UpdateGUI(trGUI.settings, false);

	int nType;
	if ( 0 == lstrcmp("iz", trNode.tagName) ) // hard code name by XYZ2Mat.oxf
	{
		SetInput();
		nType = XYZ_CHANGE_DATA;
	}
	else
	{
		switch(trNode.DataID)
		{
		//case IDST_INPUT_DATA_OPTIONS:
		//case IDV_DATA_X:
		//case IDV_DATA_Y:
		//case IDV_DATA_Z:
			//SetInput();
			//nType = XYZ_CHANGE_DATA;
			//break;
			
		///---Sim 09-25-2009 QA80-13783 CHANGE_PROTOTYPE_AND_ALGORITHM_FOR_EXAMINATION
		//case IDE_XYZ2MAT_PRECISION:
		//case IDE_XYZ2MAT_REMOVE_DUPL_BY:
		//case IDE_XYZ2MAT_XSTEPTOLERANCE:
		//case IDE_XYZ2MAT_YSTEPTOLERANCE:
		case IDE_XYZ2MAT_X_PRECISION:
		case IDE_XYZ2MAT_Y_PRECISION:
		case IDE_XYZ2MAT_REMOVE_DUPL_BY:
		///---END QA80-13783 CHANGE_PROTOTYPE_AND_ALGORITHM_FOR_EXAMINATION
			nType = XYZ_CHANGE_EXAM;
			break;
			
		case IDE_XYZ2MAT_PARA_ROWS:
		case IDE_XYZ2MAT_PARA_COLUMNS:
			nType = XYZ_CHANGE_COLUMN_AND_ROW;
			break;
			
		case IDE_XYZ2MAT_SELECT_RANGE:
			nType = XYZ_CHANGE_SEL_RANGE_USE;
			break;
			
		case IDE_XYZ2MAT_RANGE_XMIN:
		case IDE_XYZ2MAT_RANGE_XMAX:
		case IDE_XYZ2MAT_RANGE_YMIN:
		case IDE_XYZ2MAT_RANGE_YMAX:
			nType = XYZ_CHANGE_SEL_RANGE;
			break;
			
		case IDE_XYZ2MAT_CONVERT_TO_MAT:
			nType = XYZ_CHANGE_METHOD;
			break;
			
		case IDE_XYZ2MAT_PARA_QILF:
		case IDE_XYZ2MAT_PARA_WFLF:
		case IDE_XYZ2MAT_PARA_SEARCH_RADIUS:
		case IDE_XYZ2MAT_PARAMETERS:
		case IDE_XYZ2MAT_PARA_MINI_POINTS:
		case IDE_XYZ2MAT_PARA_MAXI_POINTS: ///---Sim 09-16-2009 QA81-11497-P7 ADD_MAXIMUM_FOR_RANDOM_KRIGING_METHOD
		case IDE_XYZ2MAT_PARA_BS_SMOOTHING:
		case IDE_XYZ2MAT_PARA_CORRE_SMOOTHING:
		case IDE_XYZ2MAT_PARA_TPS_SMOOTHING:
		case IDE_XYZ2MAT_PARA_OUTSIDE_VAL:
		case IDE_XYZ2MAT_PARA_TOLERANCE:
			nType = XYZ_CHANGE_METHOD_PARAMS;
			break;
			
		case IDE_XYZ2MAT_PREVIEW_PLOT_TYPE:
			nType = XYZ_CHANGE_PREVIEW_PLOT_TYPE;
			break;
			
		default:
			nType = XYZ_CHANGE_OTHER;
			break;
		}
	}
	
	/*
	ErrorInfo err;
	m_XYZGridding.OnChange(nType, err);
	m_GPCManager.OnChange(nType);
	m_GPCManager.PreChangeTab(nType, m_XYZGridding.GetXYZGriddingSettings(), m_XYZGridding.GetXYZGrdiddingDataInfo());
	UpdatePreviewDatas();
	UpdatePreviewGraphs();
		
	// update gui on value change
	m_XYZGridding.GetXYZGriddingSettings()->UpdateGUI(trGUI.settings, true);
	
	s_errEvent1 = err;
	*/
	OnChange(nType);
	
	invokeBasicGlobalEvent(GETNE_ON_VALUE_CHANGE, trGUI);
	
	//Sim, need to improve
	// input range update, not invoke OnReconstructGrid()
	// So, we have to force call UpdateDynaControl()
	if ( XYZ_CHANGE_DATA )
		UpdateDynaControl(true, GETNEVENT_ON_CHANGE_UPDATE_GUI);
}



void XYZ2MatDlg::OnChange(int nType)// = XYZ_CHANGE_INIT
{
	ErrorInfo err;
	
	m_XYZGridding.GetXYZGriddingSettings()->UpdateGUI(GetTree().settings, false);
	
	m_XYZGridding.OnChange(nType, err);
	m_GPCManager.OnChange(nType);
	m_GPCManager.PreChangeTab(nType, m_XYZGridding.GetXYZGriddingSettings(), m_XYZGridding.GetXYZGrdiddingDataInfo());
	UpdatePreviewDatas();
	UpdatePreviewGraphs();
		
	m_XYZGridding.GetXYZGriddingSettings()->UpdateGUI(GetTree().settings, true);
	
	s_errEvent1 = err;
}

void XYZ2MatDlg::OnMoveLine(int nRow, int nCol)
{
	if ( !m_GPCManager.GetDataSel(&(m_XYZGridding.GetXYZGriddingSettings()->settingRangeRestriction)) )
		return;
	
	m_XYZGridding.GetXYZGriddingSettings()->UpdateGUI(GetTree().settings, true);
	
	OnChange(XYZ_CHANGE_SEL_RANGE);
	
	invokeBasicGlobalEvent(GETNE_ON_VALUE_CHANGE, GetTree());
	UpdateDynaControl(true, GETNEVENT_ON_CHANGE_UPDATE_GUI);
}

void XYZ2MatDlg::OnEnableButtons(DWORD dwEnable, int nEventID)//OK and Apply buttons
{
	uint nBtnIds[] = {
		//IDC_APPLY,
		IDOK,
		0};

	BOOL bEnable = dwEnable & GETNGEVT_OK_ENABLE;
	EnableControls(nBtnIds, bEnable);
	EnableCustomButtons(dwEnable);
}

bool XYZ2MatDlg::getInputRange(XYZRange& dr)
{
	TreeNode trInputData= GetTree().iz.Range1;
	if(!okxf_resolve_tree_construct_range(&trInputData, &dr))
	{
		return false;
	}	
	return true;
}

bool XYZ2MatDlg::SetInput()
{
	XYZRange dr;
	// need to get error message from internal of m_XYZGridding
	//if( !getInputRange(dr) )
		//return error_report("Fail to get input range");
	getInputRange(dr);
	
	if ( !m_XYZGridding.SetInput(dr) )
		//return error_report("Fail to set input range");
		return false;
	return true;
}

bool XYZ2MatDlg::UpdatePreviewDatas()
{
	DWORD dwUpdateBits = 0;
	if ( m_GPCManager.IsDirty(&dwUpdateBits) )
	{
		if ( UPDATE_PREVIEW_DATA_CHANGED & dwUpdateBits )
		{
			vector vX, vY, vZ;
			if ( !m_XYZGridding.GetData(vX, vY, vZ, true) )
				return error_report("Fail to get input data");
			
			if ( !m_GPCManager.UpdateData(vX, vY, vZ, true) )
				return error_report("Fail to update preview data");
		}
		
		if ( UPDATE_PREVIEW_SEL_DATA_CHANGED & dwUpdateBits )
		{
			vector vX, vY, vZ;
			if ( !m_XYZGridding.GetData(vX, vY, vZ, false) )
				return error_report("Fail to get preprocess input data");
			
			if ( !m_GPCManager.UpdateData(vX, vY, vZ, false) )
				return error_report("Fail to update preprocess preview data");
		}	
		
		if ( UPDATE_PREVIEW_SEL_RANGE_USE & dwUpdateBits || UPDATE_PREVIEW_SEL_RANGE_CHANGED & dwUpdateBits )
		{
			if ( !m_GPCManager.UpdateDataSel(&(m_XYZGridding.GetXYZGriddingSettings()->settingRangeRestriction), m_XYZGridding.GetXYZGrdiddingDataInfo()) )
				return error_report("Fail to update preview data selection");
		}
		
		if ( UPDATE_PREVIEW_GRID_CHANGED & dwUpdateBits )
		{
			if ( !m_GPCManager.UpdateGrid(m_XYZGridding.GetXYZGrdiddingDataInfo()) )
				return error_report("Fail to update preview data grid line");
		}
		
		///---Sim 09-16-2009 IMPROVE_GRIDDING_ERROR_REPORT
		//if ( UPDATE_PREVIEW_RESULT_CHANGED & dwUpdateBits )
		//{
			//if ( OE_NOERROR != m_XYZGridding.DoGridding() )
				//return error_report("Fail to do gridding");
			//
			//matrix mat;
			//if ( !m_XYZGridding.GetOutput(mat) )
				//return error_report("Fail to get output data");
			//
			//if ( !m_GPCManager.UpdateResult(mat, m_XYZGridding.GetXYZGrdiddingDataInfo()) )
				//return error_report("Fail to update preview result");
		//}
		///---END IMPROVE_GRIDDING_ERROR_REPORT
		
		if ( UPDATE_PREVIEW_PLOT_TYPE_CHANGED & dwUpdateBits )
		{
			if ( !m_GPCManager.UpdatePlotType(&(m_XYZGridding.GetXYZGriddingSettings()->settingPreview)) )
				return error_report("Fail to update preview plot type");
		}
		
		///---Sim 09-16-2009 IMPROVE_GRIDDING_ERROR_REPORT
		// Griding result maybe invalid, that will cause graph control is switched. So must put these code at the end
		if ( UPDATE_PREVIEW_RESULT_CHANGED & dwUpdateBits )
		{
			matrix mat;
			XYZGrdiddingDataInfo *pXYZGrdiddingDataInfo = NULL;
			
			int nErrorCode = m_XYZGridding.DoGridding();
			
			if ( OE_NOERROR == nErrorCode )
			{
				if ( !m_XYZGridding.GetOutput(mat) )
					return error_report("Fail to get output data");
				pXYZGrdiddingDataInfo = m_XYZGridding.GetXYZGrdiddingDataInfo();
			}

			if ( !m_GPCManager.UpdateResult(mat, pXYZGrdiddingDataInfo, nErrorCode) )
				return error_report("Fail to update preview result");
		}
		///---END IMPROVE_GRIDDING_ERROR_REPORT
	}
	
	return true;
}

bool  XYZ2MatDlg::UpdatePreviewGraphs()
{
	return m_GPCManager.UpdatePreview();
}


uint XYZ2MatDlg::getTabGraphContrlID(int nGraph)
{
	vector<int> vnGraphIndeces	= {XYZ_GRAPH_INDEX_XY_RANGE,	XYZ_GRAPH_INDEX_X_HISTOGRAM,	XYZ_GRAPH_INDEX_Y_HISTOGRAM,	XYZ_GRAPH_INDEX_XYZ_WIREFRAME,	XYZ_GRAPH_INDEX_XYZ_CONTOUR,	XYZ_GRAPH_INDEX_XYZ_NONE_PREVIEW};
	vector<uint> vnGraphIDs		= {IDC_XYZ_XY_RANGE_GRAPH,		IDC_XYZ_X_HIST_GRAPH,			IDC_XYZ_Y_HIST_GRAPH,			IDC_XYZ_XYZ_3D_GRAPH,			IDC_XYZ_XYZ_3D_COLORFILL_GRAPH,	IDC_XYZ_NONE_PREVIEW};
	ASSERT( vnGraphIndeces.GetSize() == vnGraphIDs.GetSize() );
	
	if(0 > nGraph || vnGraphIndeces.GetSize()-1 < nGraph)
		return 0;

	for ( int ii = 0; ii < vnGraphIndeces.GetSize(); ii++ )
		if ( vnGraphIndeces[ii] == nGraph )
			return vnGraphIDs[ii];
	
	return 0;
}

////////////////////////////////////////////////////////////
///Sophy 9/6/2010 ORG-849 SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING
//bool XYZ2MatBox(TreeNode& trGetN, HWND hWndParent, PEVENT_GETN pfnGetN)
bool XYZ2MatBox(TreeNode& trGetN, HWND hWndParent, PEVENT_GETN pfnGetN, LPCSTR lpcszDlgName = "")
///end SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING
{
	///Sophy 9/6/2010 ORG-849 SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING
	//XYZ2MatDlg myDlg();
	XYZ2MatDlg myDlg(lpcszDlgName);
	///end SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING

	int nRet = myDlg.DoModalEx(trGetN, hWndParent);
	if(IDOK == nRet)
	{
		myDlg.UpdateEditTreeNode(trGetN);
		return true;
	}
	return false;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// for testing
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
static bool init_from_selection(TreeNode &trGUI)
{
	TreeNode trInputData = trGUI.iz;
	int nErrorCode;
	bool bRet;
	if( !init_input_data_branch_from_selection(trInputData, DRR_GET_Z_DEPENDENT|DRR_ONE_DATA, &nErrorCode) )
	{
		trInputData.SetAttribute(STR_ERROR_CODE_ATTRIB, nErrorCode);
		bRet = false;
	}
	else
	{
		trInputData.RemoveAttribute(STR_ERROR_CODE_ATTRIB);
		bRet = true;
	}
	trInputData.ID = 0x10000000;
	trInputData.Range1.DataID = 0x0020000a;
	trInputData.Range1.X.DataID = 0x00000033;
	trInputData.Range1.Y.DataID = 0x00000034;
	trInputData.Range1.Z.DataID = 0x00000036;
	return bRet;
}

void test_xyz2mat_dlg()
{
	Tree trGUI;
	
	trGUI.AddNode("iz");
	init_from_selection(trGUI);
	
	trGUI.AddNode("settings");
	XYZGriddingSettings settings;
	settings.UpdateGUI(trGUI.settings, true);	
	
	XYZ2MatDlg dlg;
	dlg.DoModalEx(trGUI);
}
