#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	method_fft,
	method_shift,
};
enum{
	algorithm_linear,
	algorithm_circular,
};


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


//enum {
	//ERR_INVALID_MATRIXOBJECT = XF_LOCAL_ERR_BEGIN,
//};

void corr2(const MatrixObject& im1, const MatrixObject& im2, const int& method, const int& algorithm, const int& norm, MatrixObject& om)
{
	waitCursor junk;
	
	if (!im1.IsValid() || !im2.IsValid())
	{
		XF_THROW(XFERR_INVALID_MATOBJ);
	}
	
	matrixbase& mat1 = im1.GetDataObject();
	matrixbase& mat2 = im2.GetDataObject();
	Matrix& mResult = om.GetDataObject();
	int nRows, nCols;
	nRows = im1.GetNumRows();
	nCols = im1.GetNumCols();
	int iRet;
	switch(method)
	{
	case method_fft:
		om.SetNumCols(nCols);
		om.SetNumRows(nRows);
		om.SetXY(1, 1, nCols, nRows);
		iRet = fft_2d_correlation(mat1, mat2, mResult, norm, algorithm);
		break;
	case method_shift:
		om.SetNumCols(nCols*2-1);
		om.SetNumRows(nRows*2-1);
		om.SetXY(1, 1, nCols*2-1, nRows*2-1);
		iRet = correlation_2d_shift_accumulate(mat1, mat2, mResult, norm, algorithm);
		break;
	}
	if (iRet != 0)
	{
		om.Destroy();
		XF_THROW(iRet);
	}
	
	//string strLabel = "Correlation of ";
	//MatrixLayer ml;
	//MatrixPage mp;
	//im1.GetParent(ml);
	//mp = ml.GetPage();
	//strLabel.Insert(strLabel.GetLength(), mp.GetName());
	//strLabel.Insert(strLabel.GetLength(), " & ");
	//im2.GetParent(ml);
	//mp = ml.GetPage();
	//strLabel.Insert(strLabel.GetLength(), mp.GetName());
	//om.GetParent(ml);
	//mp = ml.GetPage();
	//mp.SetLongName(strLabel);
	//mp.TitleShow = WIN_TITLE_SHOW_BOTH;
	
}

//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 corr2_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return corr2_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	//Sandy 2007-7-11 add for check input
	MatrixObject im1;
	if(!okxf_resolve_string_get_origin_object(trGetN.im1.strVal, &im1)||!im1.HasData(false))
	{
		///Sophy 6/24/2010 ORG-322-P1 BETTER_ERR_MSG_INFORM_CVT_IMAGE_TO_DATA
		//strErrMsg = CER_INVALID_MATOBJ;
		if ( !im1.IsValid() )
			strErrMsg = CER_INVALID_MATOBJ;
		else
		{
			strErrMsg = CER_NEED_CVT_TO_DATA;
		}
		///end BETTER_ERR_MSG_INFORM_CVT_IMAGE_TO_DATA
		bOKEnable = false;
		return true;
	}
	
	//Sandy 2007-7-11 add for check input
	MatrixObject im2;
	if(!okxf_resolve_string_get_origin_object(trGetN.im2.strVal, &im2)||!im2.HasData(false))
	{
		///Sophy 6/24/2010 ORG-322-P1 BETTER_ERR_MSG_INFORM_CVT_IMAGE_TO_DATA
		//strErrMsg = CER_INVALID_MATOBJ;
		if ( !im2.IsValid() )
			strErrMsg = CER_INVALID_MATOBJ;
		else
		{
			strErrMsg = CER_NEED_CVT_TO_DATA;
		}
		///end BETTER_ERR_MSG_INFORM_CVT_IMAGE_TO_DATA
		bOKEnable = false;
		return true;
	}
	return false;
	

}

int corr2_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 corr2_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	///Sophy 6/24/2010 ORG-322-P1 BETTER_ERR_MSG_INFORM_CVT_IMAGE_TO_DATA
	MatrixObject im1, im2;
	if( !okxf_resolve_string_get_origin_object(trGetN.im1.strVal, &im1) || !im1.HasData(false) 
		|| 	!okxf_resolve_string_get_origin_object(trGetN.im2.strVal, &im2)|| !im2.HasData(false) )
	{
		nRet = XFEVT_PROCEED_WITH_DLG;
	}
	///end BETTER_ERR_MSG_INFORM_CVT_IMAGE_TO_DATA
}
//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 corr2_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
