#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
//put additional include files here
//#include <..\Originlab\wksOperation.h> // only for testing //Sim, seems no useful
#include <Nag_utils.h>
#include <stats_utils.h>
#include <..\OriginLab\grobj_utils.h>
#include <..\Originlab\XYZ2Mat.h>

///////////////////////////////////////////////////////////////////////
// Modification Log
//
/// Max 6/1/09 v8.1027 USE_A_BETTER_ERR_MSG
/// Sophy 1/19/2010 QA80-14985 ALWAYS_DUMP_XYZ2MAT_MSG_TO_SCRIPT_WINDOW
///////////////////////////////////////////////////////////////////////
///Sophy 9/6/2010 ORG-849 SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING
//typedef bool (*FUNC_XYZ2MAT)(TreeNode &tr, HWND, PEVENT_GETN pfnGetN);
#define STR_DLG_NAME	_L("XYZ Gridding: Convert Worksheet to Matrix")
typedef bool (*FUNC_XYZ2MAT)(TreeNode &tr, HWND, PEVENT_GETN pfnGetN, LPCSTR lpcszDlgName);
///end SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING

bool XYZ2MatDialog(TreeNode& tr, PEVENT_FUNC pfn, LPCSTR lpcszTitle, LPCSTR lpcszDescription, HWND hWndParent)
{
	string strFile = "Originlab\\XYZ2MATDlg.cpp";
	FUNC_XYZ2MAT pfnOpenDlg = Project.FindFunction("XYZ2MatBox", strFile, true);
	if( pfnOpenDlg )
		///Sophy 9/6/2010 ORG-849 SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING
		//return pfnOpenDlg(tr, hWndParent, NULL);
		return pfnOpenDlg(tr, hWndParent, NULL, STR_DLG_NAME);
		///end SUPPORT_PLOT_XYZ_FROM_WORKSHEET_WITH_GRIDDING
	return error_report("Failed to load XYZ2MatBox");
}


void XYZ2Mat(const XYZRange& iz, const TreeNode& settings, MatrixObject& om)
{
	vector vX, vY, vZ;
	if( !iz.IsValid() || !iz.GetData(vZ, vY, vX) )
	/// Max 6/1/09 v8.1027 USE_A_BETTER_ERR_MSG	
		//XF_THROW(XFERR_FAILED_GET_DATA_FROM_DATARANGE);
		XF_THROW(CER_NOT_ONE_XYZRANGE);
	/// END USE_A_BETTER_ERR_MSG
	
	om.SetInternalData(FSI_DOUBLE);
	//matrix& mat = om.GetDataObject();
	Matrix& Mat = om.GetDataObject();
	
	XYZGriddingSettings xyzSettings;
	xyzSettings.UpdateGUI(settings, false);
	
	// Failed to use extern object in header file!!!
	//int nRet = XYZGRIDDING_MATH(DoGridding(vX, vY, vZ, mat, &xyzSettings));
	int nRet = XYZGRIDDING_MATH(DoGridding(vX, vY, vZ, Mat, &xyzSettings));
	//XYZGriddingMathLib objXYZGriddingMathLib;
	//int nRet = objXYZGriddingMathLib.DoGridding(vX, vY, vZ, mat, &xyzSettings);
	if ( OE_NOERROR != nRet )
		XF_THROW(CER_GRIDDING_INVALID_CONVERTED_MATRIX); // need better error
	
}

//nEventID < 0 on event, like GETNE_ON_INIT, GETNE_ON_OK etc, >0 on change from control
//return 0 to do nothing, return PEVENT_GETN_RET_TO_CLOSE to close dialog
//dwEnables = bOKEnable, bBTN1Enable, bBTN2Enable, bBTN3Enable, , can set to false to disable OK/Apply buttons
//lpcszNodeName = the trGetN TreeNode tag name that generates the event, or is  if GETNE_ON_OK etc
//strAux = optional string for XF Wizard Bar, like DLG_NEED_CHANGE_GRID etc, it will be invalid if from internal node value change event
//strErrMsg = allowing messages to be shown
int XYZ2Mat_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return XYZ2Mat_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	//warning_msg_box("xfTestCustomDialog_event1", true);
	
	return false;

}

int XYZ2Mat_make_tree(TreeNode& tr, LPCSTR lpcszVarName)
{
	//warning_msg_box("xfTestCustomDialog_make_tree", true);
	if ( 0 == lstrcmp(lpcszVarName, "settings") )
	{
		XYZGriddingSettings xyzSettings;
		xyzSettings.UpdateGUI(tr, true);
		tree_set_attribute_to_all_nodes(tr, STR_SHOW_ATTRIB, "1");
		
		return 0;
	}
	
	return -1;
}
//nGetNDialog = 0,1,2, corresponding to the XF GetN dropdown, 0 = dialog is not used
//you can change nRet to be one of XFEVT_PROCEED (defualt), XFEVT_ABORT, XFEVT_PROCEED_NO_DLG or XFEVT_PROCEED_WITH_DLG(when nGetNDialog = 0)
//nGetNDialog = -1 when Ok on GetN dialog to allow handler to preocess <auto> etc variables
//dwCntrl is combination of bits
//LTXF_FROM_GUI_MENU, LTXF_FROM_GUI_PROMPT, LTXF_FROM_AUTO_UPDATE, LTXF_FROM_FUNCTION, LTXF_THEME_USED, LTXF_CHANGE_PARAM
void XYZ2Mat_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	//warning_msg_box("xfTestCustomDialog_before_execute", true);
	//out_tree(trGetN);
	//out_int("nGetNDialog: ", nGetNDialog);
	//out_int("dwCntrl: ", dwCntrl);
	
	if ( nGetNDialog > 0 )
	{
		XYZGRIDDING_MATH(SetDirty());
		
		// show hide GUI
		XYZGriddingSettings xyzSettings;
		xyzSettings.UpdateGUI(trGetN.settings, false);
		xyzSettings.UpdateGUI(trGetN.settings, true);
	}
	
	if ( ( nGetNDialog == 0 ) 
		//&& (( dwCntrl & LTXF_FROM_GUI_PROMPT ) || ( dwCntrl & LTXF_FROM_AUTO_UPDATE )) 
		&& (( dwCntrl & LTXF_FROM_GUI_PROMPT ) || ( dwCntrl & LTXF_FROM_AUTO_UPDATE ) || ( dwCntrl & LTXF_THEME_USED ) ) 		
		)
	{
		XYZGRIDDING_MATH(SetDirty());
		
		int nType = XYZ_CHANGE_INIT;
		if ( dwCntrl & LTXF_FROM_AUTO_UPDATE )
			nType = XYZ_CHANGE_DATA;
		
		// no dialog, need init auto settings manually
		XYZRange dr;
		TreeNode trInputData = trGetN.iz;
		if ( okxf_resolve_tree_construct_range(&trInputData, &dr) )
		{
			XYZGridding xyzGridding;
			if ( xyzGridding.SetInput(dr) )
			{
				XYZGriddingSettings* pSettings = xyzGridding.GetXYZGriddingSettings();
				pSettings->UpdateGUI(trGetN.settings, false);
				ErrorInfo err;
				xyzGridding.OnChange(nType, err);
				if ( !err.bHasNoError )
				{
					//XF_WARN(err.strErrMsg); //==> Can't dump message that similar with event1 format, 1234:param
					///Sophy 1/19/2010 QA80-14985 ALWAYS_DUMP_XYZ2MAT_MSG_TO_SCRIPT_WINDOW
					//xf_warning_msg_box(err.strErrMsg, false);
					xf_warning_msg_box(err.strErrMsg, false, 'E'); //if use 'W' and command window is visible, will output to command window, so should use 'E'
					///end ALWAYS_DUMP_XYZ2MAT_MSG_TO_SCRIPT_WINDOW
					nRet = XFEVT_ABORT; // ==> when recalculate, it continue go to xf body
					return;
				}
				pSettings->UpdateGUI(trGetN.settings, true);
			}
		}
	}	
}
//nEventID < 0 on event, like GETNE_ON_INIT, GETNE_ON_OK etc, >0 on change from control
//return 0 to do nothing, return PEVENT_GETN_RET_TO_CLOSE to close dialog
//dwEnables = bOKEnable, bBTN1Enable, bBTN2Enable, bBTN3Enable, , can set to false to disable OK/Apply buttons
//lpcszNodeName = the trGetN TreeNode tag name that generates the event, or is  if GETNE_ON_OK etc
//strAux = optional string for XF Wizard Bar, like DLG_NEED_CHANGE_GRID etc, it will be invalid if from internal node value change event
//strErrMsg = allowing messages to be shown
int XYZ2Mat_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
