#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	type_line,
	type_circular,
};
#include <GetNBox.h>
#include <o8dlg.h>
#include <fft_utils.h>
#include <event_utils.h>

/*-------------------------------------------------------------------------
	Folger 12/19/07 SHOULD_CHECK_INPUT_ONLY_WHEN_INITIAL_AND_INPUT_CHANGE
	Folger 07/23/08 BETTER_OPREATION_OUTPUT_COLUMN_COMMENTS
	YuI 10/14/09 QA70-13728-P3 WRONG_AUTOSAMPLING_INTERVAL_IF_OUTPUT_PRODUCES_X_COLUMN
-------------------------------------------------------------------------*/

//enum {
	 //ERR_SET_DATA = XF_LOCAL_ERR_BEGIN,
//};
static bool _check_input(TreeNode& trGetN, string& strErrMsg)
{
	
	if(!get_error_for_2_input_double_vector(trGetN.ix1, trGetN.ix2, strErrMsg) )
		return false;
	/// YuI 10/14/09 QA70-13728-P3 WRONG_AUTOSAMPLING_INTERVAL_IF_OUTPUT_PRODUCES_X_COLUMN
	//	strErrMsg = auto_compute_sampling_interval_from_InputData(trGetN.ix1, trGetN.interval);
	strErrMsg = auto_compute_sampling_interval_from_InputData(trGetN.ix1, trGetN.interval, trGetN.oy);
	/// end WRONG_AUTOSAMPLING_INTERVAL_IF_OUTPUT_PRODUCES_X_COLUMN
	int nErr =  check_interval(trGetN.interval);
	if(nErr)
	{
		strErrMsg = nErr;
		return false;
	}
	
	return true;
}

//------ Folger 07/23/08 BETTER_OPREATION_OUTPUT_COLUMN_COMMENTS
static	void	_set_output_range_comments(XYRange &oy, const vector& ix1, const vector& ix2)
{
	string strComments;
	strComments.Format("correlation of %s, %s", get_input_data_range_string(ix1.GetSourceDataRange()), get_input_data_range_string(ix2.GetSourceDataRange()));
	oy.SetOutputComment(strComments);
}
//------ End BETTER_OPREATION_OUTPUT_COLUMN_COMMENTS


void corr1(const vector& ix1, const vector& ix2, const double& interval, const int& type, const int& norm, XYRange& oy)
{
	
	waitCursor junk;
	ix1.Trim();
	ix2.Trim();
	
	int iSize  = ix1.GetSize();
	int iSize1 = ix2.GetSize();
	if (iSize < 1 || iSize1 < 1) 
	{
		XF_THROW(XFERR_INVALID_ARG);
	}
	
	iSize = max(iSize, iSize1);
	vector vOutX;
	get_lag_from_interval(iSize, vOutX, interval, type);
	
	if (!type) //linear
	{
		iSize = 2 * iSize - 1;
	
	}
	
	vector vSignal1, vSignal2;
	vSignal1 = ix1;
	vSignal2 = ix2;
	vSignal1.SetSize(iSize);
	vSignal2.SetSize(iSize);
	
	if(norm) 	//normalize
	{
		fft_normalize_response(vSignal1);
		fft_normalize_response(vSignal2);
	}
	
	int iRet = fft_fft_correlation(iSize, vSignal1, vSignal2);
	if (iRet != 0)
	{
		//fft_error_handle(iRet);
		//XF_THROW(ERR_CORRELATION);
		XF_THROW(iRet);
	}
	
	vector vOutY;
	vOutY = vSignal1;
	if(!type)
	{
		vOutY.Wrap((iSize + 1) / 2);
	}
	else
	{
		vector<uint> vUpDown;
		vUpDown.Data(vSignal1.GetSize() - 1, 0, -1);
		vOutY.Reorder(vUpDown);
	}
	
	if (!oy.SetData(&vOutY, &vOutX))
	{
		XF_THROW(XFERR_FAIL_IN_SET_XYRANGE_DATA);
	}
	
	//Column col;
	//bool bRet = oy.GetXColumn(col);
	//bRet = col.SetLongName("Corr");
	//bRet = oy.GetYColumn(col);
	//bRet = col.SetLongName("Corr");
	
	//------ Folger 07/23/08 BETTER_OPREATION_OUTPUT_COLUMN_COMMENTS
	_set_output_range_comments(oy, ix1, ix2);
	//------
	
}

//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 corr1_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return corr1_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	//if(TRGP_ENUM_LIST != nCntrlType)
	//{
		//return false;
	//}
	//
	//_update_sampling_interval_from_InputData(trGetN);
	//
	//return true;
	
	///justin 11/03/2006 UPDATE_ERROR_MESSAGE
	//if(GETNE_ON_INIT == nEventID || is_data_selection_control_id(nEventID))
	//{
		//int nRet = auto_compute_sampling_interval_from_InputData(trGetN);
		//if(nRet != -1 && nRet != 0)
		//{
			////XF_TRACE("Warning : Time sequences should be monotonic increase!");
			 //warning_msg_box(XFWAR_TIME_SEQ_INVALID, false);
	//
		//}	
		//bOKEnable = (nRet == -1) ? false : true;	
		//
		//return true;
	//}
	
	//if(! (bOKEnable = get_error_for_2_input_double_vector(trGetN.ix1, trGetN.ix2, strErrMsg) ) )
		//return false;
	//strErrMsg = auto_compute_sampling_interval_from_InputData(trGetN.ix1, trGetN.interval);
	/////end UPDATE_ERROR_MESSAGE
	/////Justin 2007-03-23 CHECK_INTERVAL_IS_VALID
	//int nErr =  check_interval(trGetN.interval);
	//if(nErr)
	//{
		//bOKEnable = false;
		//strErrMsg = nErr;
	//}
	////------ Folger 12/19/07 SHOULD_CHECK_INPUT_ONLY_WHEN_INITIAL_AND_INPUT_CHANGE
	////bOKEnable =  _check_input(trGetN, strErrMsg);	
	//if ( GETNE_ON_INIT == nEventID ||
		//lstrcmpi(lpcszNodeName, "ix1") == 0 || lstrcmpi(lpcszNodeName, "ix2") == 0 )
		//bOKEnable = _check_input(trGetN, strErrMsg);
	////------
	bOKEnable = _check_input(trGetN, strErrMsg);
	 	///END CHECK_INTERVAL_IS_VALID
	if(TRGP_ENUM_LIST == nEventID)
		return true;
	
	return true; //return false; //Justin 2007-04-04 FORCE_TO_DISPLAY_INTERVAL_AFTER_CHANGE_THEME //temp solution
	

}

int corr1_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 corr1_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	
	
	//------ fisher 11/16/07 ADD_MAP_ID_TO_CHM
	if(is_use_origin_chm())
		trGetN.SetAttribute(STR_HELPID_ATTRIB, IDD_XF_corr1);
	
	if(0 == nGetNDialog || -1 == nGetNDialog)
	{
		//string strInterval = trGetN.interval.strVal;
		//double dInterval = trGetN.interval.dVal;
		//if(dInterval == NANUM || okutil_cvt_str_to_predefined_type(strInterval) == PDS_UNASSIGNED)
			//_update_sampling_interval_from_InputData(trGetN);
			
		///justin 11/03/2006 CLEAN
		//int nRet = auto_compute_sampling_interval_from_InputData(trGetN);
		//if(nRet != 0 && nRet != -1)
			////XF_TRACE("Warning : Time sequences should be monotonic increase!");
			 //warning_msg_box(XFWAR_TIME_SEQ_INVALID, false);
		//
		//double dInterval = trGetN.interval.dVal;
		//if(is_missing_value(dInterval))
			//nRet = XFEVT_ABORT;
		///Justin 2007-03-23 CHECK_INTERVAL_IS_VALID
		//auto_compute_sampling_interval_from_InputData(trGetN.ix1, trGetN.interval, false);  //auto_compute_sampling_interval_from_InputData(trGetN.ix1, trGetN.interval, true);  //if no suitable value, interval will be set 1. ///justin 11/21/2006
		auto_compute_sampling_interval_from_InputData(trGetN.ix1, trGetN.interval);
		int nErr = check_interval(trGetN.interval);
		if(nErr)
		{
			XF_WARN(nErr);
			nRet = XFEVT_ABORT;
		}
		///END CHECK_INTERVAL_IS_VALID
		///end CLEAN
	}
	
	if ( (dwCntrl&LTXF_THEME_USED) && nGetNDialog <= 0 )
	{
		string strErrMsg;
		if ( true != _check_input(trGetN, strErrMsg) )
			nRet = XFEVT_PROCEED_WITH_DLG;
	}
}
//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 corr1_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
