#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	type_Haar,
	type_DB2,
	type_DB3,
	type_DB4,
	type_DB5,
	type_DB6,
	type_DB7,
	type_DB8,
	type_DB9,
	type_DB10,
	type_B11,
	type_B13,
	type_B15,
	type_B22,
	type_B24,
	type_B26,
	type_B28,
	type_B31,
	type_B33,
	type_B35,
	type_B37,
};
enum{
	ext_P,
	ext_Z,
};
#include <oErrMsg.h>
#include <event_utils.h>
//put additional include files here
//#include	<nag8\OC_nag_ex.h>
#include <xfutils.h>
#include <..\OriginLab\wavelet_utils.h>
#include <o8dlg.h>

/***************************************************************************************
/// Modification Log :
///	Folger 07/28/08 BETTER_OPREATION_OUTPUT_COLUMN_COMMENTS
/// Max 4/15/09 v8.0981_new NO_POP_UP_DLG_WHEN_ERR_OCCURS_FROM_LT
***************************************************************************************/

//put your own support static functions here

//enum {
	//WAVE_EXT_PERIODIC ,
	//WAVE_EXT_ZERO,
//};

//enum {
	//CREATE_WAVELET_FILTER_ERROR = XF_LOCAL_ERR_BEGIN,
	//EXTEND_MODE_INVALID,
	//NAG_DWT_FAILED,
	//
//};

//------ Folger 07/28/08 BETTER_OPREATION_OUTPUT_COLUMN_COMMENTS
static	void	_set_output_range_comments(vector& ca, vector& cd, const vector& ix, int nType)
{
	string	strRange = get_input_data_range_string(ix.GetSourceDataRange());
	ca.SetOutputComment("Approx Coeff of " + get_wavelet_type_string(nType) + " dwt on " + strRange);
	cd.SetOutputComment("Detail Coeff of " + get_wavelet_type_string(nType) + " dwt on " + strRange);
}
//------ End BETTER_OPREATION_OUTPUT_COLUMN_COMMENTS


void dwt(const vector& ix, const int& type, const int& ext, vector& ca, vector& cd)
{
	waitCursor junk;
	
	Nag_WavFilt filter;
	//Nag_WavType wavname = nWaveletType[type];
	int i, n, nc;
	
	if(!create_wavelet_filter(g_nWaveletType[type], filter))
		XF_THROW(XFERR_WT_FAILED_TO_CREATE_FILTER);
	
	
	/* Read end extension mode */
	//vector<string> vWaveMode = {"Periodic", "Zero-padded"};
	//vector<int> vWaveModes(2) = {Nag_PerWavExt, Nag_ZeroWavExt};
	if(ext <0 || ext > 1 )
	{
		nag_free_wavfilter(&filter);
		XF_THROW(XFERR_WT_EXTEND_MODE_INVALID);
	}
	
	Nag_WavModeType mode = g_nWaveModes[ext];
	n = ix.GetSize();
	nc = get_coeffs_size(mode, n, filter);
	//ix.SetSize(nc*2);
	
	
	///Sandy add 
	vector vca(nc), vcd(nc);
	
	//printf("wavmode = %s, n = %ld, nc = %ld\n", vWaveMode[ext], n, nc);
	
	/* 1D Discrete Wavelet Transform (DWT) (one level) */
	NagError fail;
	fail.code = NE_NOERROR;
	nag_dwt(mode, ix.GetSize(), ix, &filter, nc, vca, vcd, &fail);
	if (fail.code != NE_NOERROR)
	{
		nag_free_wavfilter(&filter);
		if(fail.code == 90)
			XF_THROW(XFERR_WT_N_SHOULD_BE_EVEN_PRD_MODE);
		XF_THROW_EX(XFERR_WT_FUNCTION_UNKNOWN_ERR, fail.code);
		//printf("Error from nag_dwt.\n%s\n", fail.message);
		//goto END;
	}
	
	//END:
	
	nag_free_wavfilter(&filter);
	
	if(ca)
	{
		ca.SetSize(nc);
		ca = vca;
	}
	
	if(cd)
	{
		cd.SetSize(nc);
		cd = vcd;
	}
	
	//------ Folger 07/28/08 BETTER_OPREATION_OUTPUT_COLUMN_COMMENTS
	_set_output_range_comments(ca, cd, ix, type);
	//------
}

//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 dwt_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return dwt_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	///Kyle 09/24/08 SET_NO_NEED_TO_LOCALIZE
	if( GETNE_ON_INIT == nEventID )
	{
		trGetN.type.SetAttribute( STR_OCNTRL_OPTNS, OCNTRLPARAM1_NOT_LOCALIZED);
	}
	///End SET_NO_NEED_TO_LOCALIZE
	
	if(!get_error_for_input_double_vector(trGetN.ix, strErrMsg))
	{
		bOKEnable = false;
	}
	
	TreeNode trX = trGetN.ix;
	vector vx;
	if(okxf_resolve_tree_get_data_into_vector(&trX, &vx))
	{
		int nSize = vx.GetSize();
		if(nSize%2 != 0 && trGetN.ext.nVal == 0 )
		{
			strErrMsg = XFERR_WT_N_SHOULD_BE_EVEN_PRD_MODE;
			bOKEnable = false;			
		}
	}
	return true;

}

int dwt_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 dwt_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_dwt);
	
	/// Max 4/15/09 v8.0981_new NO_POP_UP_DLG_WHEN_ERR_OCCURS_FROM_LT
	if(0 == nGetNDialog && (dwCntrl&LTXF_THEME_USED) && (dwCntrl&LTXF_FROM_GUI_MENU) )
	//if(nGetNDialog == 0)
	/// ---
	{
		string strErrMsg;
		
		if(!get_error_for_input_double_vector(trGetN.ix, strErrMsg))
		{
			nRet = XFEVT_PROCEED_WITH_DLG;
		}
		
		TreeNode trX = trGetN.ix;
		vector vx;
		if(okxf_resolve_tree_get_data_into_vector(&trX, &vx))
		{
			int nSize = vx.GetSize();
			if(nSize%2 != 0 && trGetN.ext.nVal == 0 )
			{
				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 dwt_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
