#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	plot_none,
	plot_ap,
	plot_real,
	plot_img,
	plot_amp,
	plot_phase,
};
enum{
	win_rect,
	win_welch,
	win_tri,
	win_bartlett,
	win_hanning,
	win_hamming,
	win_blackman,
};
enum{
	factor_ee,
	factor_science,
};
#include <getnbox.h> // temp solution
//put additional include files here
#include <o8dlg.h>
#include <fft_utils.h>
#include <event_utils.h>
#include <ReportTree.h>
///////////////////////////////////////////////////
// Modification log
///Jasmine 08/14/07 QA80-10207 REPORT_SHEET_CHECK_CONFLICT
/// Max 4/8/08 v8.0839 ONLY_RESET_PLOT_SHEET_NODE_WHEN_IT_IS_NOT_MANUALLY_MODIFIED
/// Max 8/27/08 v8.0931b TEMP_COMMENT_SANDY_CHANGE_WHICH_WILL_POP_UP_DLG_ONCE_ERR_APPEAR
/// Folger 02/12/09 QA80-13076-P2 HIDDEN_GRAPH_CREATED_WHEN_NOT_OUTPUT_REPORT_GRAPH
/// Folger 02/13/09 IFFT_RREVIEW_BROKEN
/// Kyle 03/12/2009 SET_PREVIEW_GRAPH_NO_CLICK
/// Folger 04/14/09 QA80-13436 IMPROVE_MECHANISM_ABOUT_XF_ERR_MSG_SHOWN_IN_BODY
///	Jasmine 08/13/2010 ORG-172-S2 CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL
/// Jacky 08/27/10 ORG-920-P3 ONE_SAMPLE_TTEST_BETTER_HANDLING_OF_OUTPUT_PLOT_AND_REPORT_DATA
///	Kit 10/26/2010 ORG-1227-P3 SUPPORT_OTHER_FFT_TOOL_SHOW_UNITS_ON_REPORT_TABLE
///////////////////////////////////////////////////

///------ Folger 04/14/09 QA80-13436 IMPROVE_MECHANISM_ABOUT_XF_ERR_MSG_SHOWN_IN_BODY
IMPLEMENT_SHOULD_WARNING_MSG_SHOW_IN_XF_BODY
IMPLEMENT_XF_GET_WARNING_MSG_ID
///------ End IMPROVE_MECHANISM_ABOUT_XF_ERR_MSG_SHOWN_IN_BODY

//#define IFFT_WARNING_INTERVAL "Inteval will be replaced by 1.0!"

enum {
	IFFT_REPORT_TABLE = 101,
};
///justin 08/31/2006
//enum {
	//IFFTPLOT_NONE, FFTPLOT_AMP, FFTPLOT_POWER
//};
enum {
	IFFTPLOT_NONE, 
	IFFTPLOT_AMP_AND_PHASE, 
	IFFTPLOT_REAL, 
	IFFTPLOT_IMAG,
	IFFTPLOT_AMP, 
	//FFTPLOT_POWER
	IFFTPLOT_PHASE
};
///end 

#define	_IFFT_RDID_GRAPH_PREVIEW		IFFTPLOT_NONE		///------ Folger 02/13/09 IFFT_RREVIEW_BROKEN

///justin 08/31/2006
//enum _FFT_RDID {
	//_FFT_RDID_TABLE		= 100,
	//
	//_FFT_RDID_FREQ		= IDST_FIT_X, 
	//
	//_FFT_RDID_REAL		= IDST_FIT_Y, 
	//_FFT_RDID_IMAG, 
	//_FFT_RDID_AMP, 
	//_FFT_RDID_PHASE, 
	//_FFT_RDID_POWER, 
//};
enum _IFFT_RDID {
	_IFFT_RDID_TABLE		= 100,
	_IFFT_RDID_GRAPH,
	
	_IFFT_RDID_TIME		= IDST_FIT_X, 
	_IFFT_RDID_COMPLEX, ///justin 11/03/2006 ADD_COMPLEX_RESULT
	_IFFT_RDID_REAL		= IDST_FIT_Y, 
	_IFFT_RDID_IMAG, 
	_IFFT_RDID_AMP, 
	_IFFT_RDID_PHASE, 
};
///end 

//enum {
	//IDST_FFT_FREQ = 0x00010010,
	//IDST_FFT_REAL,
	//IDST_FFT_IMAG,
	//IDST_FFT_AMP,
	//IDST_FFT_PHASE,
	//IDST_FFT_POWER,
//};
//
//enum {
	//ERR_TIME_SEQUENCE_NOT_UNIFORM,
	//ERR_INVALID_DATA,
	//ERR_FAIL_TO_TRANSFORM,
	//ERR_FAIL_TO_GET_FREQUENCE,
	//
//};

//--------- CPY 5/26/06
//static bool _plot_ifft_results(TreeNode& trGetN, GraphPage& gp, Worksheet& wks)
//{
//	int nPlotType = trGetN.plot.nVal;
//	return plot_fft_results(nPlotType, gp, wks);
//}
//-----


//static bool _init_preview_graph(PageBase& pgPreview, Worksheet& wksPreview, LPCSTR lpcszGraphTemplate)
//{
	//GraphPage pg = pgPreview;
	//string strTemplate = lpcszGraphTemplate;
	//if(!strTemplate.IsEmpty())
		//page_load(pg, strTemplate);
//
	//GraphLayer gl = pg.Layers(0);
	////remove all rt dataplot
	//int nPlots = gl.DataPlots.Count();
	//for(int ii = 0; ii < nPlots; ii++)
		//gl.RemovePlot(0);
	//
	//if(wksPreview.Columns(3))
	//{
		//Curve cuvPrev(wksPreview, 0, 3);
		//int nn = gl.AddPlot(cuvPrev, IDM_PLOT_LINE);
		//DataPlot dp = gl.DataPlots(nn);
		//if(dp)
		//{
			//dp.SetColor(0);
			//gl.Rescale();
			//return true;
		//}
		//return false;
	//}
	//else
		//return true;
//}
static bool _check_update_preview(TreeNode& trNode)
{
	if(trNode.IsValid() && ( trNode.tagName == "AutoUpdate" ||trNode.tagName == "rd" || trNode.tagName == "rt"))
	{
		return false;
	}
	return true;
}

static void _prepare_plot_info(int plot, string& strTemplate, int& nY1ID, int& nY2ID, string& strPlotName = NULL)
{
	nY1ID = -1;
	nY2ID = -1;
	strTemplate = "FFTplot1L1";

	switch(plot)
	{
	case IFFTPLOT_AMP_AND_PHASE:
		nY1ID = _IFFT_RDID_AMP;
		nY2ID = _IFFT_RDID_PHASE;
		strTemplate = "FFTPlot2L1";
		break;		
	case IFFTPLOT_REAL: 
		nY1ID = _IFFT_RDID_REAL;
		break;		
	case IFFTPLOT_IMAG:
		nY1ID = _IFFT_RDID_IMAG;
		break;		
	case IFFTPLOT_AMP:
		nY1ID = _IFFT_RDID_AMP;
		break;		
	case IFFTPLOT_PHASE:
		nY1ID = _IFFT_RDID_PHASE;
		break;		
	default:
	}
	if(strPlotName)
	{
		string strCombo = _L("None|Amplitude/Phase|Real|Imaginary|Amplitude|Phase");
		vector<string> vs;
		strCombo.GetTokens(vs, '|');
		if(plot < 0 || plot >= vs.GetSize())
			strPlotName=_L("Invalid Plot");
	
		strPlotName = vs[plot];
	}
}
static void	_run_ifft_on_current_data(TreeNode& trGetN, PageBase& pgTemp, Worksheet& wksTemp)
{
	Tree trTemp;
	trTemp = trGetN;
	///justin 11/21/2006
	//if(auto_compute_sampling_interval_from_InputData(trTemp) == -1)
		//return; 
	//auto_compute_sampling_interval_from_InputData(trTemp.ix, trTemp.interval, false);	///justin 2007-3-23
	///end 	
	
	vector<complex> vx;
	//TreeNode trnInput = trTemp.ix;
	//if(trnInput)
	//{	
		//okxf_resolve_tree_get_data_into_vector(&trnInput, &vx);
		//if(vx.GetSize()<=0)
		//{
			//return;
		//}
	//}
	GraphPage	gp = pgTemp;
	if(check_input_complex_vector(trTemp.ix, 1, false, vx) || trTemp.plot.nVal == plot_none || check_interval(trTemp.interval)) 
	{
		if(pgTemp)
		{
			page_load(gp, "NonePreview");  //page_load(gp, "FFTPlot1L1");  ///justin 
			
			load_text_for_nonepreview_graphpage(gp, TEMPLATE_NONE_PREVIEW_CONTENT, TEMPLATE_NONE_PREVIEW_HINTS);
		}
		return;			
	}
	
	
	Tree trReport;
	ReportData rdTemp(trReport);
	//justin 09/07/2006 CLEAN_TEMP_WORKSHEET
	if(wksTemp)
		wksTemp.SetSize(-1, 0);  
	//end CLEAN_TEMP_WORKSHEET
	rdTemp.SetWorksheet(wksTemp);
	//GraphPage	gp = pgTemp;
	//int			nGraphType = trTemp.plot.nVal;
	XFPushPopGetNTree	pushpopGetN(trGetN); 
	XFExeContext	*pxfexectxt = Project.GetCurrentXFExeCtxt();
	///------ Folger 02/13/09 IFFT_RREVIEW_BROKEN
	//pxfexectxt->SetGraph(gp, _IFFT_RDID_GRAPH);//pxfexectxt->SetGraph(gp, nGraphType); 
	pxfexectxt->SetGraph(gp, _IFFT_RDID_GRAPH_PREVIEW);//pxfexectxt->SetGraph(gp, nGraphType); 
	///------ End IFFT_RREVIEW_BROKEN
	
	try {
		ifft1(vx, trTemp.interval.dVal, trTemp.plot.nVal, trTemp.shift.nVal, trTemp.win.nVal, trTemp.factor.nVal, trTemp.unwrap.nVal, rdTemp, NULL);
	}
	catch(int nErr)
	{
		return;
	}
	// no err, generate results data
	rdTemp.GenerateReport(wksTemp, false, true);	
}
/*
static	BOOL	_fft_graph(XFExeContext	*pxfexectxt, GraphPage &gp, int nGraph, bool bFreqFrom0, ReportData &rd, bool bPlotEvenIfPresent, bool bDontCreateGraphWindIfNonexistent = false)
{
	int				nXID = _FFT_RDID_FREQ;
	int				nYID1stLayer = 0;
	string			strTemplate;
	if ( FFTPLOT_AMP == nGraph )
	{
		strTemplate = "FFTPlot";
		nYID1stLayer = _FFT_RDID_AMP;
	}
	else if ( FFTPLOT_POWER == nGraph )
	{
		strTemplate = "FFTPower";
		nYID1stLayer = _FFT_RDID_POWER;
	}
	else
	{
		strTemplate = "Origin";
	}
	
	if ( !gp )
	{
		if ( bDontCreateGraphWindIfNonexistent )
			return TRUE;
		gp.Create(strTemplate);
		
		string			strInputDesc;
		if ( pxfexectxt->GetArgDescription(strInputDesc, "ix") )
		{
			string		str;
			str.Format(_L("IFFT of %s"), strInputDesc);
			gp.SetLongName(str, false);
			gp.TitleShow = WIN_TITLE_SHOW_BOTH;
		}
	}
	else if ( bPlotEvenIfPresent )
		page_load(gp, strTemplate);
	else
	{
		gp.Refresh(TRUE);		// just refresh
		return TRUE;
	}
	
	if ( IFFTPLOT_NONE == nGraph )
		return TRUE;
	
	// It must have two layers, otherwise invalid:
	GraphLayer		gl = gp.Layers(1);
	if(!gl)
		return error_report("_fft_graph found invalid template, 2nd layer is missing!");
	
	// The second layer should get phase:
	DataRange		drPlot;
	int				nYID = _FFT_RDID_PHASE;
	int				nn = rd.GetDataRange(drPlot, _FFT_RDID_TABLE, nXID, &nYID);
	if (1 != nn)
		return error_report("_fft_graph found invalid worksheet!");
	if ( 0 != gl.AddPlot(drPlot, IDM_PLOT_LINE) )
		return error_report("_fft_graph failed to create plot!");
	gl.Rescale();

	// Thr first layer:
	nYID = nYID1stLayer;
	nn = rd.GetDataRange(drPlot, _FFT_RDID_TABLE, nXID, &nYID);
	if (1 != nn)
		return error_report("_fft_graph found invalid worksheet!");
	
	gl = gp.Layers(0);
	if ( 0 != gl.AddPlot(drPlot, IDM_PLOT_LINE) )
		return error_report("_fft_graph failed to create plot!");
	gl.Rescale();
	if( bFreqFrom0 )
		gl.LT_execute("x1=0");// to show freq only the positive part
	
	return TRUE;
}
*/
///justin 08/31/2006
/*
static	BOOL	_fft_rd_plotting(ReportData &rd, int nGraphType, bool bFreqFrom0)
{
	XFExeContext	*pxfexectxt = Project.GetCurrentXFExeCtxt();
	bool			bPlotEvenIfPresent = pxfexectxt->IsAddPlots();
	GraphPage	gpAmp, gpPower, gpEmpty;
	gpAmp = pxfexectxt->GetGraph(FFTPLOT_AMP);	
	gpPower = pxfexectxt->GetGraph(FFTPLOT_POWER);
	gpEmpty = pxfexectxt->GetGraph(IFFTPLOT_NONE);
	
	if ( FFTPLOT_AMP == nGraphType  && !_fft_graph(pxfexectxt, gpAmp, FFTPLOT_AMP, bFreqFrom0, rd, bPlotEvenIfPresent) )
		return FALSE;
	pxfexectxt->SetGraph(gpAmp, FFTPLOT_AMP);
	
	if ( FFTPLOT_POWER == nGraphType && !_fft_graph(pxfexectxt, gpPower, FFTPLOT_POWER, bFreqFrom0, rd, bPlotEvenIfPresent) )
		return FALSE;
	pxfexectxt->SetGraph(gpPower, FFTPLOT_POWER);
	
	if (!_fft_graph(pxfexectxt, gpEmpty, IFFTPLOT_NONE, bFreqFrom0, rd, bPlotEvenIfPresent, true) )
		return FALSE;
	pxfexectxt->SetGraph(gpEmpty, IFFTPLOT_NONE);
	
	return true;
	
}
*/
static	BOOL	_ifft_rd_plotting(ReportData& rd, GraphPage& gpIFFT, const string& strLabel, const string& strTemplate, int nY1ID, int nY2ID)
{
	XFExeContext	*pxfexectxt = Project.GetCurrentXFExeCtxt();

	//prepare graphpage
	if( -1 == nY1ID)  // none plot
	{
		if(gpIFFT)
			page_load(gpIFFT, strTemplate);  
		return true;
	}
	
	if ( !gpIFFT )
	{
		gpIFFT.Create(strTemplate, CREATE_HIDDEN); 
		string			strInputDesc;
		if(!strLabel.IsEmpty())
		{
			gpIFFT.SetLongName("IFFT of"+" "+strInputDesc, false);
			gpIFFT.TitleShow = WIN_TITLE_SHOW_BOTH;
		}
		
	}
	else if ( pxfexectxt->IsAddPlots() )
	{
		page_load(gpIFFT, strTemplate);
	}
	else
	{
		gpIFFT.Refresh(TRUE);		// just refresh
		return TRUE;
	}
	
	//plot
	DataRange		drPlot;
	GraphLayer		gl;	
	if(-1 != nY2ID)  
	{
		gl = gpIFFT.Layers(1);
		if(!gl)
			return error_report("_ifft_graph found invalid template, 2nd layer is missing!");
		if (1 != rd.GetDataRange(drPlot, _IFFT_RDID_TABLE, _IFFT_RDID_TIME, &nY2ID) )
			return error_report("_ifft_graph found invalid worksheet!");

		if ( 0 != gl.AddPlot(drPlot, IDM_PLOT_LINE) )
			return error_report("_ifft_graph failed to create plot!");
		gl.Rescale();
	}
	
	if(-1 != nY1ID)
	{
		gl = gpIFFT.Layers(0);
		if (1 != rd.GetDataRange(drPlot, _IFFT_RDID_TABLE, _IFFT_RDID_TIME, &nY1ID) )
			return error_report("_ifft_graph found invalid worksheet!");

		if ( 0 != gl.AddPlot(drPlot, IDM_PLOT_LINE) )
			return error_report("_ifft_graph failed to create plot!");
		gl.Rescale();
	}
	
	// pxfexectxt->SetGraph(gpIFFT, _IFFT_RDID_GRAPH); ///justin 11/03/2006 

	return true;
	
}

///justin 08/31/2006 
/*
static void _update_result_data(ReportData& outData, vector& vFreq, vector& vReal, vector& vImag, vector& vAmp, vector& vPhase, vector& vPower)
{
	int nDataTableID = 100;
	int nIDx = IDST_FIT_X;
	int nIDy1 = IDST_FIT_Y;
	int nIndex = 1;
	
	ReportTable rtFFT;
	string strTableName;
	strTableName.Format("IFFT%d", nIndex);
	
	rtFFT = outData.CreateTable(strTableName, "IFFT Results", nDataTableID);
	outData.ID = IDST_RESULT_CURVES;

	rtFFT.AddColumn(vFreq, "Freq", nIDx, "Frequency", OKDATAOBJ_DESIGNATION_X);
	rtFFT.AddColumn(vReal, "Real", nIDy1++, "Real", OKDATAOBJ_DESIGNATION_Y);
	rtFFT.AddColumn(vImag, "Imag", nIDy1++, "Imaginary", OKDATAOBJ_DESIGNATION_Y);
	rtFFT.AddColumn(vAmp, "Amp", nIDy1++, "Amplitude (r)", OKDATAOBJ_DESIGNATION_Y);
	rtFFT.AddColumn(vPhase, "Phase", nIDy1++, "Phase (Phi)", OKDATAOBJ_DESIGNATION_Y);
	rtFFT.AddColumn(vPower, "Power", nIDy1++, "Power", OKDATAOBJ_DESIGNATION_Y);
}
*/
static void _update_result_data(ReportTable& rtIFFT, vector& vTime, vector& vReal, vector& vImag, vector& vAmp, vector& vPhase)
{
	rtIFFT.AddColumn(vTime, "Time", _IFFT_RDID_TIME, _L("Time(s)"), OKDATAOBJ_DESIGNATION_X);
	rtIFFT.AddColumn(vReal, "Real", _IFFT_RDID_REAL, _L("Real"), OKDATAOBJ_DESIGNATION_Y);
	rtIFFT.AddColumn(vImag, "Imag", _IFFT_RDID_IMAG, _L("Imaginary"), OKDATAOBJ_DESIGNATION_Y);
	rtIFFT.AddColumn(vAmp, "Amp", _IFFT_RDID_AMP, _L("Amplitude (r)"), OKDATAOBJ_DESIGNATION_Y);
	rtIFFT.AddColumn(vPhase, "Phase", _IFFT_RDID_PHASE, _L("Phase (Deg)"), OKDATAOBJ_DESIGNATION_Y);
}


///Sandy 2007-10-15 add checking if no plot, no graph sheet output
static bool _check_if_need_plots_in_result_sheet(TreeNode trGetN)
{
	/// Max 4/8/08 v8.0839 ONLY_RESET_PLOT_SHEET_NODE_WHEN_IT_IS_NOT_MANUALLY_MODIFIED
	/*
	if(trGetN.plot.nVal == plot_none)
	{
		trGetN.rt.Enable = false;
		//trGetN.rt.strVal = "<optional>";
		trGetN.rt.strVal = STR_OPTIONAL;
		return false;
	}
	else
	{
		trGetN.rt.Enable = true;
		//trGetN.rt.strVal = "<new  template:=Graph>"; /// Max 12/5/07 should not set value in code
		return true;
	}
	*/
	ASSERT (trGetN.plot);
	if(trGetN.plot.nVal == plot_none)
		return false;
	else
		return true;
	/// END ONLY_RESET_PLOT_SHEET_NODE_WHEN_IT_IS_NOT_MANUALLY_MODIFIED
}

///-----Kit 10/26/2010 ORG-1227-P3 SUPPORT_OTHER_FFT_TOOL_SHOW_UNITS_ON_REPORT_TABLE
class IFFTShowUnitsHelper : public ShowUnitsHelperBase
{
public:
	IFFTShowUnitsHelper(const DataRange &dr);
protected:
	//virtual
	bool	CreateReportUnitStr(int nRDID, string &strUnit);
};

IFFTShowUnitsHelper::IFFTShowUnitsHelper(const DataRange &dr) : ShowUnitsHelperBase(dr)
{

}

bool	IFFTShowUnitsHelper::CreateReportUnitStr(int nRDID, string &strUnit)
{
	bool bRet = true;
	strUnit.Empty();
	string strX = m_strUnitX;
	string strReal = m_strUnitReal;
	
	if( CheckUnitIsCompoiste(strX) )
		AddParenthesis(strX);
	if( CheckUnitIsCompoiste(strReal) )
		AddParenthesis(strReal);
	
	switch( nRDID )
	{
	case _IFFT_RDID_TIME:
		if( compare_string_localization(m_strUnitX, "Hz", true) )
			strUnit = "s";
		else if( compare_string_localization(m_strUnitX, "kHz", true) )
			strUnit = "ms";
		else 
		{
			if( !HandleReciprocalCase(strUnit) )
				strUnit = "1/" + strX;
		}
		break;
	case _IFFT_RDID_REAL:
	case _IFFT_RDID_IMAG:
	case _IFFT_RDID_AMP:
		strUnit = strReal;
		break;
	case _IFFT_RDID_PHASE:
		strUnit = "Deg";
		break;
	default:
		bRet = false;
		break;
	}
	return bRet;
}

///-----End  SUPPORT_OTHER_FFT_TOOL_SHOW_UNITS_ON_REPORT_TABLE


void ifft1(const vector<complex>& ix, const double& interval, const int& plot, const int& shift, const int& win, const int& factor, const int& unwrap, ReportData& rd, ReportTree& rt)
{
	int					ii,jj, nRet;
	vector				vFreq, vImag, vReal, vAmp, vPhase, vPower;	
	vector<complex>		vSignal;
	vSignal = ix;
	
	int nSize = vSignal.GetSize();
	vSignal.GetImaginary(vImag);
	vSignal.GetReal(vReal);
	
	//if (ocmath_count(NANUM, nSize, vReal) || ocmath_count(NANUM, nSize, vImag))
	//{
		//XF_TRACE("Fail in check missing, the signal will be trimed missing before executing FFT");
		//vReal.Trim();
		//vImag.Trim();
	//}
	  		
	nRet = get_frequence_from_interval(nSize, vFreq, interval);
	if (0 != nRet)
	{
		XF_THROW(nRet);
	}
	apply_window_data(vReal, win);
	apply_window_data(vImag, win);
	vSignal.MakeComplex(vReal,vImag);
	
	//justin 08/23/2006 FIX_UNDO_SHIFT
	if (shift)
	{
		undo_fft_shift(vSignal);
	}
	//end FIX_UNDO_SHIFT
	
	nRet = fft_complex(nSize, vSignal, FFT_BACKWARD);
	if(0 != nRet )
	{
		XF_THROW(nRet);
	}
	vSignal /= nSize;
	
	if(factor)
	{
		fft_factor(vSignal);
	}
		
	//justin 08/23/2006 FIX_UNDO_SHIFT
	//if (shift)
	//{
		//ifft_shift(vSignal, vFreq);
	//}
	//end FIX_UNDO_SHIFT
	
	vSignal.GetReal(vReal);
	vSignal.GetImaginary(vImag);	
	vSignal.GetPhase(vPhase);
	vSignal.GetAmplitude(vAmp);
	vPower = vAmp*vAmp/nSize;
	
	vPhase *= 360/2/PI; // in unit of degree
	
	if(unwrap)
	{
		fft_unwrap_phase(vPhase);
	}
	//justin 08/31/2006 MOVE_GRAPH_INTO_WORKSHEET
	//_update_result_data(Result, vFreq, vReal, vImag, vAmp, vPhase, vPower);	
	//_fft_rd_plotting(rd, plot, shift != 0);
	
	string strLabel, strInputDesc;
	XFExeContext	*pxfexectxt = Project.GetCurrentXFExeCtxt();
	pxfexectxt->GetArgDescription(strInputDesc, "ix");
	strLabel = "IFFT of" + " " + strInputDesc;
	
	ReportTable rtIFFT = rd.CreateTable("IFFT", strLabel, _IFFT_RDID_TABLE);
	
	_update_result_data(rtIFFT, vFreq, vReal, vImag, vAmp, vPhase);	
	
	string strTemplate, strPlotName;
	int nY1ID, nY2ID;
	_prepare_plot_info(plot, strTemplate, nY1ID, nY2ID, strPlotName);
	
	///------ Folger 02/13/09 IFFT_RREVIEW_BROKEN
	//GraphPage	gpIFFT = pxfexectxt->GetGraph( _IFFT_RDID_GRAPH );
	
	/////------ Folger 02/12/09 QA80-13076-P2 HIDDEN_GRAPH_CREATED_WHEN_NOT_OUTPUT_REPORT_GRAPH
	////if(_ifft_rd_plotting(rd, gpIFFT, strLabel, strTemplate, nY1ID, nY2ID) && rt)
	//if ( rt && _ifft_rd_plotting(rd, gpIFFT, strLabel, strTemplate, nY1ID, nY2ID) )
	/////------ End HIDDEN_GRAPH_CREATED_WHEN_NOT_OUTPUT_REPORT_GRAPH
	
	GraphPage	gpIFFT = pxfexectxt->GetGraph( _IFFT_RDID_GRAPH_PREVIEW );
	/// gpIFFT is valid only when do Preview
	if ( (gpIFFT || rt) && _ifft_rd_plotting(rd, gpIFFT, strLabel, strTemplate, nY1ID, nY2ID) )
	{
		if ( rt )
		{
			ReportTable rtGraph = rt.CreateTable("Graphs", strLabel, IDST_RESULT_GRAPHS, 0, 1);
			rtGraph.SetCell(0, 0, gpIFFT);
			rtGraph.SetCell(-1, 0, strPlotName);
		}
	}
	///------ End IFFT_RREVIEW_BROKEN
	//end MOVE_GRAPH_INTO_WORKSHEET
	
	///-----Kit 10/26/2010 ORG-1227-P3 SUPPORT_OTHER_FFT_TOOL_SHOW_UNITS_ON_REPORT_TABLE
	if( rt.IsValid() && rd.IsValid() )
	{
		DataRange dr;
		dr = ix.GetSourceDataRange();
		if( dr.IsValid() )
		{
			Worksheet wksIFFT;
			rd.GetWorksheet(wksIFFT);
			if( wksIFFT.IsValid() )
			{
				IFFTShowUnitsHelper unitHelper(dr);
				unitHelper.ShowUnitsRowOnReportTable(wksIFFT, rtIFFT);
			}
		}
		else
		{
			ASSERT(false);
		}
	}
	///-----End SUPPORT_OTHER_FFT_TOOL_SHOW_UNITS_ON_REPORT_TABLE
	
	///------ Folger 04/14/09 QA80-13436 IMPROVE_MECHANISM_ABOUT_XF_ERR_MSG_SHOWN_IN_BODY
	CHECK_SHOW_WARNING_MESSAGE_IN_XF_BODY
	///------ End IMPROVE_MECHANISM_ABOUT_XF_ERR_MSG_SHOWN_IN_BODY
	
}

//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 ifft1_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return ifft1_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	///justin 11/01/2006 CLEAN
	/*
	//if(TRGP_ENUM_LIST != nCntrlType)
	//{
		//return false;
		//
	//}
	//
	//TreeNode& trInputX = trGetN.ix;
	//if( trInputX )
	//{
		//vector<complex> vComplex;
		//vector vTime;
		//if( okxf_resolve_tree_get_data_into_vector(&trInputX, &vComplex, &vTime) )
		//{
			//trGetN.interval.dVal = get_fft_interval_by_x_input(vTime);
		//}
	//}
	//_update_sampling_interval_from_InputData(trGetN);//--------- CPY 5/26/06
	
	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!");
		}	
		bOKEnable = (nRet == -1) ? false : true;	
		
		return true;
	}
	
	if(TRGP_ENUM_LIST == nEventID)
		return true;
	
	*/
	//end CLEAN
	return false;
	

}

int ifft1_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 ifft1_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_ifft1);
	
	//if(0 == nGetNDialog)
	//{
		//string strInterval = trGetN.interval.strVal;
		//if(okutil_cvt_str_to_predefined_type(strInterval) == PDS_UNASSIGNED)
			//_update_sampling_interval_from_InputData(trGetN);
	//}
	///justin 09/28/2006 NO_PLOT_NO_GRAPH
	//if(	nGetNDialog >0 )
	//{
		//trGetN.rt.Show = (IFFTPLOT_NONE != trGetN.plot.nVal); 
	//}
	//end NO_PLOT_NO_GRAPH
	
	/// Max 4/8/08 v8.0839 NEED_TO_CHECK_THEME_CHANGE_CASE
	/////Sandy 2007-10-15 add checking if no plot, no graph sheet output
	//if(nGetNDialog > 0)
		//_check_if_need_plots_in_result_sheet(trGetN);
	ASSERT (trGetN.rt);
	if(nGetNDialog > 0 && !_check_if_need_plots_in_result_sheet(trGetN))
		trGetN.rt.Enable = false;
	/// END  NEED_TO_CHECK_THEME_CHANGE_CASE
	
	if(0 == nGetNDialog || -1 == nGetNDialog)//if(0 == nGetNDialog)///justin 08/31/2006 HANDLE_AUTO_WHEN_CLICK_OK
	{
		//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/21/2006 
		//int nRet = auto_compute_sampling_interval_from_InputData(trGetN);
		//if(nRet != 0 && nRet != -1)
			//XF_TRACE("Warning : Time sequences should be monotonic increase!");
		//
		//double dInterval = trGetN.interval.dVal;
		//if(is_missing_value(dInterval))
			//nRet = XFEVT_ABORT;
			
		///Justin 2007-03-23	
		//nRet = auto_compute_sampling_interval_from_InputData(trGetN.ix, trGetN.interval, false);
		//if(nRet)
		//{
			//XF_WARN_EX(nRet, IFFT_WARNING_INTERVAL);
		//}
		/////end 
		/////justin 09/28/2006 NO_PLOT_NO_GRAPH
		//if(IFFTPLOT_NONE == trGetN.plot.nVal)
		//{
			//trGetN.rt.strVal = "<optional>";
		//}
		
		int nErr = CER_NO_ERROR;
		/// Max 8/27/08 v8.0931b TEMP_COMMENT_SANDY_CHANGE_WHICH_WILL_POP_UP_DLG_ONCE_ERR_APPEAR
		
		///Sandy add 2008-8-12 for check input 
		string strErrMsg;
	if(!get_error_for_input_complex_vector(trGetN.ix, strErrMsg) )
		{
			nErr = XFERR_INVALID_RANGE;
		}
		
		/// END TEMP_COMMENT_SANDY_CHANGE_WHICH_WILL_POP_UP_DLG_ONCE_ERR_APPEAR
		
		//auto_compute_sampling_interval_from_InputData(trGetN.ix, trGetN.interval);
		//int nErr = check_interval(trGetN.interval);
		///------ Folger 04/14/09 QA80-13436 IMPROVE_MECHANISM_ABOUT_XF_ERR_MSG_SHOWN_IN_BODY
		//if(CER_NO_ERROR == nErr)
		//{
			//auto_compute_sampling_interval_from_InputData(trGetN.ix, trGetN.Interval);  ///Justin 2007-03-27 AUTO_FOR_NO_DIALOG
			//nErr = check_interval(trGetN.interval);
			//strErrMsg = nErr;
		//}
		///------ End IMPROVE_MECHANISM_ABOUT_XF_ERR_MSG_SHOWN_IN_BODY
		
		///Jasmine 08/14/07 QA80-10207 REPORT_SHEET_CHECK_CONFLICT
		if(CER_NO_ERROR == nErr && is_same_sheet(trGetN.rd, trGetN.rt))
		{
			nErr = XFERR_REPORT_SHEET_CONFLICT;
			strErrMsg = nErr;
		}
		if(CER_NO_ERROR != nErr)
		{
			///Sandy 2008-8-29 XF called from LT should not pop up dialog as Max's attention
			/*
			//XF_WARN(nErr);
			//warning_msg_box(nErr, false, 'E');
			//nRet = XFEVT_ABORT;
			/// Max 8/27/08 v8.0931b TEMP_COMMENT_SANDY_CHANGE_WHICH_WILL_POP_UP_DLG_ONCE_ERR_APPEAR
			// nRet = XFEVT_PROCEED_WITH_DLG;//Sandy 2008-8-21 Dialog should prompt although there is invalid input.
			warning_msg_box(nErr, false, 'E');
			nRet = XFEVT_ABORT;
			/// END TEMP_COMMENT_SANDY_CHANGE_WHICH_WILL_POP_UP_DLG_ONCE_ERR_APPEAR
			*/
			if( (dwCntrl&LTXF_THEME_USED) && (dwCntrl&LTXF_FROM_GUI_MENU))
			{
				nRet = XFEVT_PROCEED_WITH_DLG;
			}
			else
			{
				//warning_msg_box(nErr, false, 'E');
				xf_warning_msg_box(strErrMsg, false, 'E');
				nRet = XFEVT_ABORT;				
			}
		}
		///End REPORT_SHEET_CHECK_CONFLICT
		///end 
		//end NO_PLOT_NO_GRAPH
	
	}
	
	///------ Folger 04/14/09 QA80-13436 IMPROVE_MECHANISM_ABOUT_XF_ERR_MSG_SHOWN_IN_BODY
	if ( is_xf_startup(nGetNDialog, dwCntrl) )
	{
		SET_WARNING_MSG_SHOW_IN_XF_BODY(IS_ERR_MSG_OK_TO_SHOW_IN_BODY);
		int		nErr = auto_compute_sampling_interval_from_InputData(trGetN.ix, trGetN.Interval);
		if ( CER_NO_ERROR == nErr )
			nErr = check_interval(trGetN.interval);
		XF_SET_WARNING_MSG_ID(nErr);
	}
	///------ End IMPROVE_MECHANISM_ABOUT_XF_ERR_MSG_SHOWN_IN_BODY
	 
}
//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 ifft1_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
	bUpdateGraph = true;
}

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

// 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
	//Worksheet wks = wksTemp;
	/////justin 11/01/2006
	///*
	////_update_sampling_interval_from_InputData(trGetN); //--------- CPY 5/26/06
	/////Justin 08/31/2006 KEEP_AUTO_INTERVAL
	////int nRet = auto_compute_sampling_interval_from_InputData(trGetN);
	//Tree trTemp;
	//trTemp = trGetN;
	//int nRet = auto_compute_sampling_interval_from_InputData(trTemp);
	////end
	//if(nRet != -1 && nRet != 0)
	//{
		//XF_TRACE("Warning : Time sequences should be monotonic increase!");
	//}	
	//bOKEnable = (nRet == -1) ? false : true;	
	//*/
	////end 
	////_run_ifft_on_current_data(trGetN, pgTemp, wks); ///Justin 2007-06-13 SHOULD_AUTO_INTERVAL_BEFORE_PLOT
//
	//// there is some problem that we need to force a dialog page to refresh
	//GraphPage gp = pgTemp;
	//gp.Refresh(true);
	//
	/////justin 11/03/2006 UPDATE_ERROR_MESSAGE
	///////justin 11/01/2006
	////int nRet = get_fft_input_vector(trGetN.ix);
	////if(nRet)
	////{
		////strErrMsg = nRet;
		////bOKEnable = false; 
		////return;
	////}
	//if(! (bOKEnable = get_error_for_input_complex_vector(trGetN.ix, strErrMsg) ) )
		//return;
	/////end UPDATE_ERROR_MESSAGE
	//strErrMsg = auto_compute_sampling_interval_from_InputData(trGetN.ix, trGetN.interval);
	/////end
//
	//_run_ifft_on_current_data(trGetN, pgTemp, wks); ///Justin 2007-06-13 SHOULD_AUTO_INTERVAL_BEFORE_PLOT
//
	/////--justin 2007-03-23
	//int nErr =  check_interval(trGetN.interval);
	//if(nErr)
	//{
		//bOKEnable = false;
		//strErrMsg = nErr;
	//}
	/////end 
	
	///Jasmine 08/13/2010 ORG-172-S2 CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL
	/////Sandy 2007-8-28 Clean initial code to speed up open dlg
	//GraphPage gp = pgTemp;
	//page_load(gp, "NonePreview"); 
//
	//load_text_for_nonepreview_graphpage(gp, TEMPLATE_NONE_PREVIEW_CONTENT, TEMPLATE_NONE_PREVIEW_HINTS);
	//
	/////Kyle 03/12/2009 SET_PREVIEW_GRAPH_NO_CLICK
	//GraphPage gpPreview(pgTemp);
	//if(gpPreview)
		//set_gp_noclick(gpPreview, NOCLICK_DATA_PLOT | NOCLICK_TICKLABEL | NOCLICK_LAYER | NOCLICK_LAYERICON | NOCLICK_AXES | NOCLICK_LABEL);
	/////End SET_PREVIEW_GRAPH_NO_CLICK
	xf_load_nopreview(pgTemp);
	///End CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL

	///Sandy add 2007-12-27 for check input when initialize, should move to initGrid actually
	if(!(bOKEnable = get_error_for_input_complex_vector(trGetN.ix, strErrMsg) ) )
	{
		return;
	}
	
	strErrMsg = auto_compute_sampling_interval_from_InputData(trGetN.ix, trGetN.interval);

	int nErr =  check_interval(trGetN.interval);
	if(nErr)
	{
		strErrMsg = nErr;
		bOKEnable = false;
	}	
	///end
}

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

static void GetNGraphPreview_OnUpdateGraph(TreeNode& trGetN, PageBase& pgTemp, Datasheet& wksTemp, PictureControl& pict)
{

	Worksheet wks = wksTemp;
	_run_ifft_on_current_data(trGetN, pgTemp, wks);
	
	///Kyle 03/12/2009 SET_PREVIEW_GRAPH_NO_CLICK
	GraphPage gpPreview(pgTemp);
	if(gpPreview)
		///Jasmine 08/13/2010 ORG-172-S2 CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL
		//set_gp_noclick(gpPreview, NOCLICK_DATA_PLOT | NOCLICK_TICKLABEL | NOCLICK_LAYER | NOCLICK_LAYERICON | NOCLICK_AXES | NOCLICK_LABEL);
		set_gp_noclick(gpPreview, OC_PREVIEW_NOCLICK_NOZOOMPAN | NOCLICK_LABEL);
		///End CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL
	///End SET_PREVIEW_GRAPH_NO_CLICK

	
	//_plot_ifft_results(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
	///justin 11/01/2006 
	/*
	if(trNode.tagName == "ix")
	{
		//_update_sampling_interval_from_InputData(trGetN);//--------- CPY 5/26/06
		//int nRet = auto_compute_sampling_interval_from_InputData(trGetN);
		Tree trTemp;
		trTemp = trGetN;
		int nRet = auto_compute_sampling_interval_from_InputData(trTemp);
		//end
		if(nRet != -1 && nRet != 0)
		{
			XF_TRACE("Warning : Time sequences should be monotonic increase!");
		}	
		bOKEnable = (nRet == -1) ? false : true;			
	}
	///justin 09/28/2006 NO_PLOT_NO_GRAPH
	if(trNode.tagName == "plot")
	{
		trGetN.rt.Show = (IFFTPLOT_NONE != trGetN.plot.nVal); 
	}
	//end NO_PLOT_NO_GRAPH

	
	bUpdateGraph = true;
	*/
	
	///justin 11/03/2006 
	//bUpdateGrid = true;
	//bUpdateGraph = true;
	//if(trNode.IsValid())
	//{
		//if(trNode.tagName == "AutoUpdate" ||trNode.tagName == "rd" || trNode.tagName == "rt")
		//{
			//bUpdateGraph = false;
		//}
	//}
	bUpdateGraph = _check_update_preview(trNode);
	///end 

	///justin 11/03/2006 UPDATE_ERROR_MESSAGE
	/////justin 11/01/2006
	//int nRet = get_fft_input_vector(trGetN.ix);
	//if(nRet)
	//{
		//strErrMsg = nRet;
		//bOKEnable = false; 
		//return;
	//}
	if((bOKEnable = get_error_for_input_complex_vector(trGetN.ix, strErrMsg) ) )
	{
		strErrMsg = auto_compute_sampling_interval_from_InputData(trGetN.ix, trGetN.interval);
		
		///--justin 2007-03-23
		int nErr =  check_interval(trGetN.interval);
		if(nErr)
		{
			bOKEnable = false;
			strErrMsg = nErr;
		}
		
		bUpdateGrid = true;  //Justin 2007-04-04 FORCE_TO_DISPLAY_INTERVAL_AFTER_CHANGE_THEME 	
	}
	///end UPDATE_ERROR_MESSAGE

	///end 
	///Jasmine 08/14/07 QA80-10207 REPORT_SHEET_CHECK_CONFLICT
	if(bOKEnable && is_same_sheet(trGetN.rd, trGetN.rt))
	{
		int nErr = XFERR_REPORT_SHEET_CONFLICT;
		strErrMsg = nErr;
		bOKEnable = false;
	}
	///End REPORT_SHEET_CHECK_CONFLICT
	
	/// Max 4/8/08 v8.0839 ONLY_RESET_PLOT_SHEET_NODE_WHEN_IT_IS_NOT_MANUALLY_MODIFIED
	// ///Sandy 2007-10-15 add checking if no plot, no graph sheet output
	// _check_if_need_plots_in_result_sheet(trGetN);
	string strRTvalue = STR_DEFAULT_VALUE_FOR_PLOT_SHEET_NODE;
	okutil_convert_localized_PDS(&strRTvalue);
	bool bplot = _check_if_need_plots_in_result_sheet(trGetN);

	// theme change will also invoke GetNGraphPreview_OnChange() and trNode will be invalid when theme changes
	LPCSTR lpcszNode;
	if(trNode)
		lpcszNode = trNode.tagName;
	//--- Jacky 08/27/10 ORG-920-P3 ONE_SAMPLE_TTEST_BETTER_HANDLING_OF_OUTPUT_PLOT_AND_REPORT_DATA
	//tr_set_optional(true, lpcszNode, trGetN.rt, bplot, strRTvalue);
	tr_set_optional_ex(true, lpcszNode, trGetN.rt, xf_event_is_change_param(trGetN), bplot,strRTvalue);
	//--- end ONE_SAMPLE_TTEST_BETTER_HANDLING_OF_OUTPUT_PLOT_AND_REPORT_DATA
	/// END ONLY_RESET_PLOT_SHEET_NODE_WHEN_IT_IS_NOT_MANUALLY_MODIFIED
	
	if(!bOKEnable)
		dwUpdateGraph = UPDATE_GRAPH_INVALID; //nUpdateGraph = UPDATE_GRAPH_ERROR;

	
}

// 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_ifft1(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

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

