#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	filter_none,
	filter_ave,
	filter_fir,
};
#include <fft_utils.h>
#include <ocmsp.h>
#include <event_utils.h>

/**
/// Iris 10/13/09 QA70-14403 PREVIEW_GRAPH_SHOULD_NEVER_RESCALE_ON_CHANGE
/// Kyle 10/13/2009 CHECK_RESAMPLE_FACTOR
/// Iris 10/20/2009 ADD_FFT_PREVIEW_FOR_DECIMATE_XF
/// Kyle 10/21/2009 QA80-13487-P1 OUTPUT_COLUMN_COMMENTS
/// Kyle 10/21/2009 QA80-13487-P2 CENTRALIZE_CHECKING_CODE_AND_NOT_DO_AUTO_CORRECT
///	Jasmine 08/13/2010 ORG-172-S2 CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL
*/

//put your own support static functions here

static bool s_bInit = false;
static string s_strErrMsg = "";


static void _run_decimate_on_current_data(TreeNode& trGetN, PageBase& pgTemp, Worksheet& wksTemp)
{
	wksTemp.SetSize(0, -1);
	XYRange iy, oy;
	if(!init_preview_graph(trGetN.iy, pgTemp, wksTemp, NULL, &iy, &oy))
		return;
	
	int d = trGetN.d.nVal;
	int newsize = trGetN.newsize.nVal;
	int filter = trGetN.filter.nVal;
	
	int order = trGetN.order.nVal;
	int plot = trGetN.plot.nVal;
	
	
	try{
		decimate(iy, d, newsize, filter, order, plot, oy);
	}
	catch(int nErr)
	{
		
	}
	/// Iris 10/20/2009 ADD_FFT_PREVIEW_FOR_DECIMATE_XF
	/*	
	GraphPage gp = pgTemp;
	GraphLayer gl = gp.Layers(1);
	
	if(plot)
	{
		// prepare layer
		if(!gl)
		{
			int nIndex = gp.AddLayer("Amp");
			gl = gp.Layers(nIndex);
			page_arrange_layers(gp, 2, 1);
		}

		// data
		XYRange rngPlot;
		int nX = 2, nY = 3;
		xy_range_from_wks_cols(rngPlot, wksTemp, nX, nY);
		_update_decimate_fft_amp(oy, rngPlot);
	
		// plot
		Curve cuvPrev(wksTemp, nX, nY);
		int nPlots = gl.DataPlots.Count();
		for(int ii = 0; ii < nPlots; ii++)
			gl.RemovePlot(0);
		int nn = gl.AddPlot(cuvPrev, IDM_PLOT_LINE);
		DataPlot dp = gl.DataPlots(nn);
		if(dp)
		{
			dp.SetColor(1);
			legend_update(gl);
		}
		gl.Rescale();
	}
	else
	{
		if(gl)
			gl.Destroy();
		page_arrange_layers(gp, 1, 1);
	}
	*/
	bool bRet = show_FFT_preview(trGetN, pgTemp, wksTemp, oy, trGetN.d.nVal);
	ASSERT(bRet);
	///end ADD_FFT_PREVIEW_FOR_DECIMATE_XF
	
	/// Iris 10/13/09 QA70-14403 PREVIEW_GRAPH_SHOULD_NEVER_RESCALE_ON_CHANGE
	/*
	// Kyle 09/22/2009 rescale preview
	gl = gp.Layers(0);
	if(gl)
		gl.Rescale();
	*/
	///end PREVIEW_GRAPH_SHOULD_NEVER_RESCALE_ON_CHANGE
}

/// Iris 10/20/2009 ADD_FFT_PREVIEW_FOR_DECIMATE_XF
/*
static void _update_decimate_fft_amp(const XYRange& iy, XYRange& oy)
{
	vector vx, vy;
	if(!iy || !iy.GetData(vy, vx,NULL, 0, 0))
		return;

	vector vfreq, vAmp;
	
	fft_amp(vx, vy, vfreq, vAmp, vy.GetSize());
	
	if(oy.IsValid())
		oy.SetData(&vAmp, &vfreq);

}
*/
///end ADD_FFT_PREVIEW_FOR_DECIMATE_XF

static void update_d_slider(TreeNode& trGetN)
{
	int nSize = get_input_xyrange_data_size(trGetN.iy);
	
	int nSliderBegin = 1;
	int nSliderEnd = nSize / 10;
	///Kyle 08/18/2009 RESET_THE_SLIDER_AS_DEFAULT_IF_NO_DATA
	if(nSize <= 0)
	{
		nSliderBegin = 5;
		nSliderEnd = 205;
	}
	else if(nSliderEnd <= nSliderBegin)
		nSliderEnd = nSliderBegin + 1;
	///End RESET_THE_SLIDER_AS_DEFAULT_IF_NO_DATA
	string strComboAttrib;
	strComboAttrib.Format("%d|%d|%d", nSliderBegin, nSliderEnd, nSliderEnd - nSliderBegin);

	trGetN.d.SetAttribute(STR_COMBO_ATTRIB, strComboAttrib);
	///Kyle 10/21/2009 QA80-13487-P2 CENTRALIZE_CHECKING_CODE_AND_NOT_DO_AUTO_CORRECT, no need to do auto correct here
	/*
	if(trGetN.d.nVal < nSliderBegin)
		trGetN.d.nVal = nSliderBegin;
	else if(trGetN.d.nVal > nSliderEnd)
		trGetN.d.nVal = nSliderEnd;
	*/
	///End CENTRALIZE_CHECKING_CODE_AND_NOT_DO_AUTO_CORRECT
}


static void _update_gui_tree_show(TreeNode& trGetN)
{
	trGetN.order.Show = trGetN.filter.nVal == filter_fir;
}

static bool _check_input(TreeNode& trGetN, string& strErrMsg)
{
	int nSize = get_input_xyrange_data_size(trGetN.iy);
	///Kyle 10/10/2009 ADD_ERROR_CHECKING
	int nErr = CER_NO_ERROR;
	if(get_input_xyrange_num(trGetN.iy) < 1)
		nErr = XFERR_AT_LEAST_ONE_XYRANGE;
	else if(0 >= nSize)
		nErr = CER_NO_DATA;
	
	vector vx, vy;
	XYRange xyTemp;
	if(xy_range_from_GetN_data_node(trGetN.iy, xyTemp) && xyTemp.GetData(vy, vx,NULL, 0, 0))
	{
		int mo = ocmath_is_monotonic(vx, nSize);
		if( MONO_DECREASE != mo && MONO_INCREASE != mo)
			nErr = CER_NONMONOTONIC_X
	}
	
	if(nErr != CER_NO_ERROR)
	{
		strErrMsg = nErr;
		return false;
	}
	///End ADD_ERROR_CHECKING
	
	///Kyle 10/13/2009 CHECK_RESAMPLE_FACTOR
	if(trGetN.d.nVal < 1 || trGetN.d.nVal > max(nSize/10, 2) )
	{
		strErrMsg = XF_DECIMATE_RESAMPLE_FACTOR;
		return false;
	}
	///End CHECK_RESAMPLE_FACTOR

	trGetN.newsize.nVal = ceil( (double)(nSize)/trGetN.d.nVal );
	
	if(trGetN.filter.nVal == filter_fir)
	{
		///Kyle 10/14/2009 CHECK_ORDER
		//if(trGetN.order.nVal < 8)
		//	trGetN.order.nVal = 8;
		//else if(trGetN.order.nVal > 60)
		//	trGetN.order.nVal = 60;
		if(trGetN.order.nVal < 8 || trGetN.order.nVal > 60)
		{
			strErrMsg = XF_DECIMATE_FIR_ORDER;
			return false;
		}
		///End CHECK_ORDER
	}
	
	return true;
}
///Kyle 10/21/2009 QA80-13487-P2 CENTRALIZE_CHECKING_CODE_AND_NOT_DO_AUTO_CORRECT
/*
/// Iris 10/20/2009 QA80-13487-P2 NEED_CHECK_NEW_SIZE_NOT_TOO_SMALL
static bool _check_data_size(TreeNode& trGetN, int& nErr, string& strAux)
{
	string strFactorRange;
	bool bRet = trGetN.d.GetAttribute(STR_COMBO_ATTRIB, strFactorRange);
	ASSERT(bRet);
	
	vector vRanges;
	strFactorRange.GetTokens(vRanges, '|');
	if( vRanges.GetSize() != 3 )
		return false;
	
	if( trGetN.d.dVal < vRanges[0] || trGetN.d.dVal > vRanges[1] )
	{		
		trGetN.d.GetAttribute(STR_LABEL_ATTRIB, strAux);
		nErr = NEW_DATA_SIZE_TOO_SMALL;			
		return false;
	}
	return true;
}

static void _gui_check_data_size(TreeNode& trGetN, bool& bOKEnable, string& strErrMsg)
{
	if( bOKEnable && strErrMsg.IsEmpty() )
	{
		int nErr;
		string strAux;
		if( !_check_data_size(trGetN, nErr, strAux) )
		{
			strErrMsg = nErr;
			strErrMsg += ":" + strAux;
			bOKEnable = false;
		}		
	}
}
///end NEED_CHECK_NEW_SIZE_NOT_TOO_SMALL
*/
///End CENTRALIZE_CHECKING_CODE_AND_NOT_DO_AUTO_CORRECT

///Kyle 10/21/2009 QA80-13487-P1 OUTPUT_COLUMN_COMMENTS
static	void	_set_output_range_comments(XYRange &oy, const XYRange& iy, int nFilter)
{
	string strFilter;
	switch(nFilter)
	{
	case filter_none:
		strFilter = _L("decimation of %s");
		break;
	case filter_ave:
		strFilter = _L("MA decimation of %s");
		break;
	case filter_fir:
		strFilter = _L("FIR decimation of %s");
		break;
	default:
		ASSERT(FALSE);
		return;
	}

	string strComments;
	strComments.Format(strFilter, get_input_data_range_string(iy));

	if(oy != NULL && oy.IsValid())
		oy.SetOutputComment(strComments);
}
///End OUTPUT_COLUMN_COMMENTS


void decimate(const XYRange& iy, const int& d, const int& newsize, const int& filter, const int& order, const int& plot, XYRange& oy)
{
	vector vx, vy;
	if(!iy.GetData(vy, vx,NULL, 0, 0))
		XF_THROW(1);
	
	int nSize = vy.GetSize(), nType;
	vector vxD(nSize), vyD(nSize), vfreq, vAmp;
	
	switch(filter)
	{
	case filter_none:
		nType = DEC_FILTER_NONE;
		break;
	case filter_ave:
		nType = DEC_FILTER_MOVING_AVE;		
		break;
	case filter_fir:
		nType = DEC_FILTER_FIR;		
		break;
	default:
		ASSERT(FALSE);
		XF_THROW(1);
		break;
	}
	
	int nSizeNew = ocmsp_decimate(vx, vy, nSize, d, vxD, vyD, nType, order);
	if( nSizeNew <= 0 )
		XF_THROW(XFERR_FAIL_EVAL);
	
	vxD.SetSize(nSizeNew);
	vyD.SetSize(nSizeNew);
	
	if(oy.IsValid())
	{
		///Kyle 08/19/2009 QA80-14023 FIX_OUTPUT_SAMPLING_INTERVAL_IS_LOST_WHEN_INPUT_IS_LOOSE_DATASET
		//oy.SetData(&vyD, &vxD);
		///Kyle 09/22/2009 QA80-14023 FIX_SAMPLING_IS_NOT_RESET_IF_SET_INPUT_AS_OUTPUT
		//set_xyrange_data_ex(oy, &vyD, &vxD, 0, iy);
		/// YuI 09/30/09 QA70-14399 UNNECESARY_AUTOUPDATE_IN_CASE_OF_INPUT_NEW
		//	if( oy.SetData(&vyD, &vxD,  0, NULL, DRS_SET_COL_DESIGNATIONS) )
		//		update_output_xyrange_even_sampling(oy, &vxD);
		// reverting Kyle's change
		// fixed in update_output_xyrange_even_sampling which is called from set_xyrange_data_ex
		///Kyle 10/14/09 QA70-14023 OPTION_TO_FORCE_SAMPLING_INTERVAL_RECALCULATION
		//set_xyrange_data_ex(oy, &vyD, &vxD, 0, iy);
		set_xyrange_data_ex(oy, &vyD, &vxD, 0, iy, NULL, SXYDC_RECALCULATE_SAMPLING_INTERVAL);
		///End OPTION_TO_FORCE_SAMPLING_INTERVAL_RECALCULATION
		/// end UNNECESARY_AUTOUPDATE_IN_CASE_OF_INPUT_NEW
		///End FIX_SAMPLING_IS_NOT_RESET_IF_SET_INPUT_AS_OUTPUT
		///End FIX_OUTPUT_SAMPLING_INTERVAL_IS_LOST_WHEN_INPUT_IS_LOOSE_DATASET
	
		_set_output_range_comments(oy, iy, filter);			///Kyle 10/21/2009 QA80-13487-P1 OUTPUT_COLUMN_COMMENTS
	}
	
}

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

}

int decimate_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 decimate_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	///Kyle 10/10/2009 ADD_ERROR_CHECKING
	if(is_xf_startup(nGetNDialog, dwCntrl))
	{
		_update_gui_tree_show(trGetN);
		update_d_slider(trGetN);
		///Kyle 10/21/2009 QA80-13487-P2 CENTRALIZE_CHECKING_CODE_AND_NOT_DO_AUTO_CORRECT
		/*
		if ( (dwCntrl&LTXF_THEME_USED) && nGetNDialog <= 0 )
		{
			string strErrMsg;
			if(!_check_input(trGetN, strErrMsg))
				nRet = XFEVT_PROCEED_WITH_DLG;
		}
		
		/// Iris 10/20/2009 QA80-13487-P2 NEED_CHECK_NEW_SIZE_NOT_TOO_SMALL
		if( nGetNDialog <= 0 )
		{
			int nErr;
			string strAux;
			if( !_check_data_size(trGetN, nErr, strAux) )
			{				
				warning_msg_box(nErr, strAux, false);	
				nRet = XFEVT_ABORT;
			}
		}	
		///end NEED_CHECK_NEW_SIZE_NOT_TOO_SMALL
		*/
		if ( (dwCntrl&LTXF_THEME_USED) || nGetNDialog <= 0 )
		{
			string strErrMsg;
			if(!_check_input(trGetN, strErrMsg))
			{
				if( (dwCntrl&LTXF_THEME_USED) && nGetNDialog <= 0 )
					nRet = XFEVT_PROCEED_WITH_DLG;
				else if( nGetNDialog <= 0 )
				{
					warning_msg_box(atoi(strErrMsg), false);
					nRet = XFEVT_ABORT;
				}
			}
		}
		///End CENTRALIZE_CHECKING_CODE_AND_NOT_DO_AUTO_CORRECT
	}
	
	///End ADD_ERROR_CHECKING
}
//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 decimate_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}


// put your grid initialization here
// you may also initialize wksTemp here
static void GetNGraphPreview_OnInitGrid(TreeNode& trGetN, PageBase& pgTemp, Datasheet& wksTemp,
PictureControl& pict, // optional tab for showing an image or EMF, as requested in OnDialogSetup 
DWORD& dwUpdateGraph,  // default to 0, UPDATE_GRAPH_CHANGED to cause graphs to be updated, UPDATE_GRAPH_INVALID to disable preview button
DWORD& dwUpdateGrid, // default to 0, set to UPDATE_GRID_SIMPLE to update the DynaControl grid, UPDATE_GRID_RESET to reset DynaControl grid
DWORD& dwEnables,// bOKEnable, bBTN1Enable, bBTN2Enable and bBTN3Enable :default to true, can set to false to disable buttons
string& strErrMsg) // optional err msg to be shown on dialog
{
	DECLARE_BUTTON_ENABLES
	DECLARE_UPDATE_GRAPH
	DECLARE_UPDATE_GRID

	trGetN.newsize.Enable = ENABLE_READ_ONLY;

	_update_gui_tree_show(trGetN);
	update_d_slider(trGetN);
	bOKEnable = _check_input(trGetN, strErrMsg);
	///Kyle 10/21/2009 QA80-13487-P2 CENTRALIZE_CHECKING_CODE_AND_NOT_DO_AUTO_CORRECT
	//_gui_check_data_size(trGetN, bOKEnable, strErrMsg); /// Iris 10/20/2009 QA80-13487-P2 NEED_CHECK_NEW_SIZE_NOT_TOO_SMALL
	///End CENTRALIZE_CHECKING_CODE_AND_NOT_DO_AUTO_CORRECT
	//if(bOKEnable)			///Kyle 10/22/2009 SHOULD_ALWAYS_INIT_THE_TEMP_WKS
	{
		Worksheet wks = wksTemp;
		/// Iris 10/20/2009 ADD_FFT_PREVIEW_FOR_DECIMATE_XF
		/*
		wks.SetSize(-1, 4);
		wks.SetColDesignations("XYXY");
		wks.Columns(1).SetLongName("Decimate");  
		wks.Columns(3).SetLongName("spectrum");
		*/
		wks.SetSize(-1, 6);
		wks.SetColDesignations("XYXYXY");
		wks.Columns(1).SetLongName(_L("Decimated"));
		wks.Columns(3).SetComments(_L("Input")); // display for plot legend
		wks.Columns(5).SetComments(_L("Output"));// display for plot legend
		wks.Columns(2).SetLongName(_L("Frequency")); // display for X Axis title
		wks.Columns(3).SetLongName(_L("FFT Amplitude")); // display for Y Axis title
		///end ADD_FFT_PREVIEW_FOR_DECIMATE_XF
	}
	
	bUpdateGraph = bOKEnable;

	s_bInit = false;
	s_strErrMsg = strErrMsg;

}

///////////////////////////////////////////////////////

// pgTemp is the graph for preview or control
// wksTemp is the the temp wks created to hold data to plot into pgTemp
static void GetNGraphPreview_OnInitGraph(TreeNode& trGetN, PageBase& pgTemp, Datasheet& wksTemp,
PictureControl& pict, // optional tab for showing an image or EMF, as requested in OnDialogSetup  
DWORD& dwUpdateGrid, // default to 0, set to UPDATE_GRID_SIMPLE to update the DynaControl grid, UPDATE_GRID_RESET to reset DynaControl grid
DWORD& dwEnables,// bOKEnable, bBTN1Enable, bBTN2Enable and bBTN3Enable :default to true, can set to false to disable buttons
string& strErrMsg) // optional err msg to be shown on dialog
{
	DECLARE_BUTTON_ENABLES
	DECLARE_UPDATE_GRID

	strErrMsg = s_strErrMsg;
	///Jasmine 08/13/2010 ORG-172-S2 CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL
	//GraphPage gp = pgTemp;
	//page_load(gp, "NonePreview");
	//load_text_for_nonepreview_graphpage(gp, TEMPLATE_NONE_PREVIEW_CONTENT, TEMPLATE_NONE_PREVIEW_HINTS);
	xf_load_nopreview(pgTemp);
	///End CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL
	
	//bUpdateGraph = bOKEnable;

}

///////////////////////////////////////////////////////

static void GetNGraphPreview_OnUpdateGraph(TreeNode& trGetN, PageBase& pgTemp, Datasheet& wksTemp, PictureControl& pict)
{
	Worksheet wks = wksTemp;
	if(!s_bInit)
	{
		Worksheet wks = wksTemp;
		
		wks.SetSize(0,-1, true);
		init_preview_graph(trGetN.iy, pgTemp, wks, "CurvePreview", NULL, NULL, 0, 0, 1, PREVIEW_LAYER_FORMAT_SCALE_TYPE);

		GraphPage gp = pgTemp;
		/// Iris 10/20/2009 ADD_FFT_PREVIEW_FOR_DECIMATE_XF
		// no need take care of layer arrangement here since show_FFT_preview will do this.
		/*
		int nRow = 2,
			nCol = 1;

		int nLayerCount = gp.Layers.Count();
		if(nLayerCount > 2)
		{
			while((nLayerCount--) > 2)
			{
				GraphLayer gl = gp.Layers(nLayerCount);
				gl.Destroy();
			}
		}
		else if(nLayerCount < 2)
		{
			//gp.AddLayer("Decimate");
			gp.AddLayer("Spectrum");
		}
		page_arrange_layers(gp, nRow, nCol);
		*/
		///end ADD_FFT_PREVIEW_FOR_DECIMATE_XF
		gp.Refresh(true);
		s_bInit = true;
	}

	_run_decimate_on_current_data(trGetN, pgTemp, wks);

}

///////////////////////////////////////////////////////

static void GetNGraphPreview_OnChange(TreeNode& trGetN, TreeNode& trNode, PageBase& pgTemp, Datasheet& wksTemp,
PictureControl& pict, // optional tab for showing an image or EMF that might be present, as requested in OnDialogSetup  
bool bChangedByGraph, // called when graph has been modified by user, like dragging a vertical line
DWORD& dwUpdateGraph,  // default to 0, UPDATE_GRAPH_CHANGED to cause graphs to be updated, UPDATE_GRAPH_INVALID to disable preview button
DWORD& dwUpdateGrid,  // default to 0, set to UPDATE_GRID_SIMPLE to update the DynaControl grid, UPDATE_GRID_RESET to reset DynaControl grid
DWORD& dwEnables,	// bOKEnable, bBTN1Enable, bBTN2Enable and bBTN3Enable :default to true, can set to false to disable buttons
string& strErrMsg) // optional err msg to be shown on dialog
{
	DECLARE_BUTTON_ENABLES
	DECLARE_UPDATE_GRAPH
	DECLARE_UPDATE_GRID

	trGetN.newsize.Enable = ENABLE_READ_ONLY;
	
	if(trNode && trNode.tagName=="iy")
	{
		update_d_slider(trGetN);
		bUpdateGrid = true;			///Kyle 08/18/2009 RESET_THE_SLIDER_AS_DEFAULT_IF_NO_DATA, should force to update the gui if the slider is updated
	}
	_update_gui_tree_show(trGetN);
	bOKEnable = _check_input(trGetN, strErrMsg);
	///Kyle 10/21/2009 QA80-13487-P2 CENTRALIZE_CHECKING_CODE_AND_NOT_DO_AUTO_CORRECT
	//_gui_check_data_size(trGetN, bOKEnable, strErrMsg); /// Iris 10/20/2009 QA80-13487-P2 NEED_CHECK_NEW_SIZE_NOT_TOO_SMALL
	///End CENTRALIZE_CHECKING_CODE_AND_NOT_DO_AUTO_CORRECT
	if(!bOKEnable)
		dwUpdateGraph = UPDATE_GRAPH_INVALID; //nUpdateGraph = UPDATE_GRAPH_ERROR;
	else
		bUpdateGraph = bOKEnable;

}

// called from OnInitDialog to allow options on setting up of dialog
// dwOptions = 0 (default) will create a line graph with data in a temp worksheet
// dwOptions = XFGSETUP_IMAGEGRAPH_CNTRL to create an image graph with data in a temp matrix book
// dwOptions = XFGSETUP_MATRIX_CNTRL to have a MatrixControl with data in a temp matrix book
// dwOptions = XFGSETUP_2_TABS | XFGSETUP_EMF_1ST to have a PictureControl on 1st tab and a GraphControl on 2nd tab
// vsTabTitles is empty on entering the event, but you can put tab title strings in this array.
static void GetNGraphPreview_OnDialogSetup(TreeNode& trGetN, WndContainer& theDlg, DWORD& dwOptions, vector<string>& vsTabTitles)
{

}

// called when dialog is being destroyed, either as OK button or as Cancel button being pressed
static void GetNGraphPreview_OnDestroy(TreeNode& trGetN, PageBase& pgTemp, Datasheet& wksTemp, PictureControl& pict)
{

}
//------------
//
static void GetNGraphPreview_OnCustomButton(TreeNode& trGetN, int nButton, PageBase& pgTemp, Datasheet& wksTemp,
PictureControl& pict, // optional tab for showing an image or EMF that might be present, as requested in OnDialogSetup  
bool bChangedByGraph, // called when graph has been modified by user, like dragging a vertical line
DWORD& dwUpdateGraph,  // default to 0, UPDATE_GRAPH_CHANGED to cause graphs to be updated, UPDATE_GRAPH_INVALID to disable preview button
DWORD& dwUpdateGrid,  // default to 0, set to UPDATE_GRID_SIMPLE to update the DynaControl grid, UPDATE_GRID_RESET to reset DynaControl grid
DWORD& dwEnables,	// bOKEnable, bBTN1Enable, bBTN2Enable and bBTN3Enable :default to true, can set to false to disable buttons
string& strErrMsg) // optional err msg to be shown on dialog
{
	DECLARE_BUTTON_ENABLES
	DECLARE_UPDATE_GRAPH
	DECLARE_UPDATE_GRID

}
//


///////////////////////////////////////////////////////
	
int GetNGraphBox_decimate(TreeNode& trGetN, int nRow, int nCol, TreeNode& trNode, DWORD dwCntrl, int nType, WndContainer& theDlg, PageBase& pgTemp, Datasheet& wksTemp, PictureControl& pict)
{
	return xf_GetNPreviewDlg_event_handler(trGetN, nRow, nCol, trNode, dwCntrl, nType, theDlg, pgTemp, wksTemp, pict,
	GetNGraphPreview_OnInitGrid, GetNGraphPreview_OnInitGraph,
	GetNGraphPreview_OnChange, GetNGraphPreview_OnUpdateGraph, GetNGraphPreview_OnDialogSetup, GetNGraphPreview_OnDestroy,
	GetNGraphPreview_OnCustomButton);	
}


//This file is the template for GetNEvent4

///////////////////////////////////////////////////////

