#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>


//put additional include files here
#include <wks2mat.h>
//put your own support static functions here


void xyz_sparse(const XYZRange& iz, const int& rows, const int& cols, MatrixObject& om)
{
	if (!iz.IsValid())
	{
		/// Cloud 7/12/07 UPDATE_XF_ERR_THROW
		//XF_THROW(ERR_INVALID_XYZ_RANGE);
		warning_msg_box(XFERR_INVALID_XYZ_RANGE, false, 'E');
		/// End UPDATE_XF_ERR_THROW
	}
	
	vector vX, vY, vZ;
	if (!iz.GetData(vZ, vY, vX))
	{
		/// Cloud 7/12/07 UPDATE_XF_ERR_THROW
		//XF_THROW(ERR_RETRIEVE_DATA);
		warning_msg_box(XFERR_INVALID_XYZ_RANGE, false, 'E');
		/// End UPDATE_XF_ERR_THROW
	}
		
	int nSize = vX.GetSize();	
	///Arvin 08/15/06 DEBUG
	//int nPrecision = 8;
	double dPrecision = 1.0e-10;
	///end 
	// Step 1: Remove duplicates
	///---Sim 09-25-2009 QA80-13783 PROTOTYPE_WITH_TWO_PRECISION_FOR_XYZ_REMOVE_DUPLICATE
	//nSize = ocmath_xyz_remove_duplicates(nSize, vX, vY, vZ, Remove_With_Mean, dPrecision);
	nSize = xyz_remove_duplicates(nSize, vX, vY, vZ, Remove_With_Mean, dPrecision);
	///---END QA80-13783 PROTOTYPE_WITH_TWO_PRECISION_FOR_XYZ_REMOVE_DUPLICATE
	///Arvin 02/04/08 QA70-10984 REGULAR_IS_ALSO_SUITABLE_FOR_SPARSE
	//Remove invalid values
	vX.SetSize(nSize);
	vY.SetSize(nSize);
	vZ.SetSize(nSize);
	///end REGULAR_IS_ALSO_SUITABLE_FOR_SPARSE
	double dXMin, dXStep, dXMax, dYMin, dYStep, dYMax;
	
	// Step 2, 3: examine data and do the conversion if data are regular.
	///---Sim 09-25-2009 QA80-13783 CHANGE_PROTOTYPE_AND_ALGORITHM_FOR_EXAMINATION
	//int iRet = ocmath_xyz_examine_data(nSize, vX, vY, vZ, dPrecision, NULL, &dXMin, &dXStep, &dXMax, &dYMin, &dYStep, &dYMax);
	int iRet = xyz_examine_data(nSize, vX, vY, vZ, dPrecision, NULL, &dXMin, &dXStep, &dXMax, &dYMin, &dYStep, &dYMax);
	///---END QA80-13783 CHANGE_PROTOTYPE_AND_ALGORITHM_FOR_EXAMINATION
	///Arvin 02/04/08 QA70-10984 REGULAR_IS_ALSO_SUITABLE_FOR_SPARSE	
	//if (iRet != Examine_XYZ_Sparse)
	if (iRet != Examine_XYZ_Sparse && iRet != Examine_XYZ_Regular)
	///end 	REGULAR_IS_ALSO_SUITABLE_FOR_SPARSE
	{
		/// Cloud 7/12/07 UPDATE_XF_ERR_THROW
		//XF_THROW(ERR_NOT_SPARSE);
		warning_msg_box(CER_NOT_MATCHED_TRY_RANDOM_CONVERSION, false, 'E');
		/// End UPDATE_XF_ERR_THROW
	}
	///Arvin 08/15/06 INPUT_ROW_AND_COLUMN_NUMBER
	//int nRows, nCols;	
	//nCols = dXStep > 0 ? (int)((dXMax - dXMin) / dXStep + 0.5) + 1 : 1; 
	//nRows = dYStep > 0 ? (int)((dYMax - dYMin) / dYStep + 0.5) + 1 : 1; 
	dXStep = (dXMax - dXMin)/(cols - 1);
	dYStep = (dYMax - dYMin)/(rows - 1);
	dXStep = round(dXStep, 4);
	dYStep = round(dYStep, 4);
	///END INPUT_ROW_AND_COLUMN_NUMBER
	Matrix& mat = om.GetDataObject();
	mat.SetSize(rows, cols); 
	om.SetXY(dXMin, dYMin, dXMax, dYMax);
	
	// return the number of scatters discarded by the conversion. 
	iRet = ocmath_convert_sparse_xyz_to_matrix(nSize, vX, vY, vZ,
				mat, dXMin, dXStep, cols, dYMin, dYStep, rows);
				
	if (iRet < 0) {
		/// Cloud 7/12/07 UPDATE_XF_ERR_THROW
		//XF_THROW_EX("Xfunction failed, Code = %d", iRet);
		warning_msg_box(XFERR_COVERT_TO_MATRIX, false, 'E');
		/// End UPDATE_XF_ERR_THROW
	}
	
}

//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 xyz_sparse_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return xyz_sparse_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	return false;

}

int xyz_sparse_make_tree(TreeNode& tr, LPCSTR lpcszVarName)
{
	return false;
}
//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 xyz_sparse_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{

}
//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 xyz_sparse_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
