#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	method_mean,
	method_median,
	method_min,
	method_max,
	method_sum,
};

//put additional include files here
#include <ReportTree.h>

#include <event_utils.h>


/////////////////////////////////////////////////////////////////////////////
// Modification Log
//
// CPY 12/19/08 USE_SHARED_TEMPLATE_FOR_ALL_PREVIEW_XF
// Kyle 12/22/2008 OPEN_DIALOG_WHEN_THEME_IS_USED_AND_ERROR_HAPPENS
// Kyle 12/22/2008 OUTPUT_COLUMN_COMMENTS
// Jack 12/22/2008 ADD_COUNTS_FOR_DUPXS
// Folger 12/26/08 QA80-12856 v8.0991 IMRPOVE_ocmath_xy_remove_duplicates
// Kyle 06/03/2009 GET_SOURCE_GRAPH_SCALE_TYPE
// Kyle 08/19/2009 QA80-14023 FIX_OUTPUT_SAMPLING_INTERVAL_IS_LOST_WHEN_INPUT_IS_LOOSE_DATASET
// Kyle 09/22/2009 QA80-14023 FIX_SAMPLING_IS_NOT_RESET_IF_SET_INPUT_AS_OUTPUT
// YuI 09/30/09 QA70-14399 UNNECESARY_AUTOUPDATE_IN_CASE_OF_INPUT_NEW
// CPY 9/30/09 QA70-14403 PREVIEW_GRAPH_SHOULD_NEVER_RESCALE_ON_CHANGE
// Jasmine 08/13/2010 ORG-172-S2 CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL
/////////////////////////////////////////////////////////////////////////////





///Kyle 12/02/2008 QA80-12405-S1 UPDATE_XF_TO_SHOW_PREVIEW
static bool s_bInit = false;
static string s_strErrMsg = "";

static void _run_resample_on_current_data(TreeNode& trGetN, PageBase& pgTemp, Worksheet& wksTemp)
{
	XYRange iy, xyResampled;
	///Jack 12/22/2008 ADD_COUNTS_FOR_DUPXS
	XYRange ocTempy;
	///End ADD_COUNTS_FOR_DUPXS
	
	if(!init_preview_graph(trGetN.iy, pgTemp, wksTemp, NULL, &iy, &xyResampled))
		return;
	///Kyle 12/08/2008 CLEAN_DATA_IN_TEMPORARY_WORKSHEET_BEFORE_DO_UPDATE_PREVIEW_GRAPH
	vector vX, vY;
	xyResampled.SetData(&vY, &vX, 0, NULL, 0);	// clean data	
	///End CLEAN_DATA_IN_TEMPORARY_WORKSHEET_BEFORE_DO_UPDATE_PREVIEW_GRAPH
	int method = trGetN.method.nVal;
	double dPrecision = trGetN.tol.dVal;

	try {
		///Jack 12/22/2008 ADD_COUNTS_FOR_DUPXS
		//reducedup(iy, method, dPrecision,xyResampled);
		reducedup(iy, method, dPrecision,xyResampled, ocTempy);
		// End ADD_COUNTS_FOR_DUPXS
	}
	catch(int nErr)
	{
	}
	//--- CPY 9/30/09 QA70-14403 PREVIEW_GRAPH_SHOULD_NEVER_RESCALE_ON_CHANGE
	/*
	// Kyle 09/22/2009 rescale preview
	GraphPage gp = pgTemp;
	GraphLayer gl = gp.Layers(0);
	if(gl)
		gl.Rescale();
	*/
	//--- end PREVIEW_GRAPH_SHOULD_NEVER_RESCALE_ON_CHANGE
}

static int _check_input(TreeNode& trGetN, string& strErrMsg)
{
	int nErr = CER_NO_ERROR;
	int nSize =  get_input_xyrange_data_size(trGetN.iy);
	if(get_input_xyrange_num(trGetN.iy) < 1)
		nErr = XFERR_AT_LEAST_ONE_XYRANGE;
	else if(0 >= nSize)
		nErr = CER_NO_DATA;
	
	if(trGetN.tol.dVal < 0)
		nErr = XFERR_INVALID_ARG;
	
	if(nErr != CER_NO_ERROR)
	{
		strErrMsg = nErr;
		return false;
	}
	
	return true;	
}
///End UPDATE_XF_TO_SHOW_PREVIEW





static bool _trim_missing_values(vector& vX, vector& vData)
{
	if(vX.GetSize()==0 || vData.GetSize()==0)
		return false;
	
	//if missing values, cases are excluded pairwise
	vector<uint> vecIndexX, vecIndexD;
	vX.Find(vecIndexX, NANUM);
	vData.Find(vecIndexD, NANUM);
	
	for (int ii= 0; ii < vecIndexX.GetSize(); ii++)
		vData[vecIndexX[ii]] = NANUM;
	
	for (ii= 0; ii < vecIndexD.GetSize(); ii++)
		vX[vecIndexD[ii]] = NANUM;
		
	vData.Trim();
	vX.Trim();
	if(vX.GetSize()==0 || vData.GetSize()==0)
		return false;
	else
		return true;
}


///Kyle 08/19/2009 QA80-14023 FIX_OUTPUT_SAMPLING_INTERVAL_IS_LOST_WHEN_INPUT_IS_LOOSE_DATASET
//static bool _reducexy_set_data_range(XYRange& oy, const vector *pVMergeX, const vector *pVMergeY)
static bool _reducexy_set_data_range(XYRange& oy, const vector *pVMergeX, const vector *pVMergeY, const XYRange& iy)
///End FIX_OUTPUT_SAMPLING_INTERVAL_IS_LOST_WHEN_INPUT_IS_LOOSE_DATASET
{
	ASSERT(oy.IsValid() && pVMergeX!=NULL || pVMergeY!=NULL);
	if(!oy.IsValid() || pVMergeX==NULL || pVMergeY==NULL)
		return false;
	///Kyle 08/19/2009 QA80-14023 FIX_OUTPUT_SAMPLING_INTERVAL_IS_LOST_WHEN_INPUT_IS_LOOSE_DATASET
	//oy.SetData(pVMergeY,pVMergeX, 0, NULL, DRS_SET_COL_DESIGNATIONS);
	///Kyle 09/22/2009 QA80-14023 FIX_SAMPLING_IS_NOT_RESET_IF_SET_INPUT_AS_OUTPUT
	//set_xyrange_data_ex(oy, pVMergeY,pVMergeX, 0, iy);
	
	/// YuI 09/30/09 QA70-14399 UNNECESARY_AUTOUPDATE_IN_CASE_OF_INPUT_NEW
	//	return oy.SetData(pVMergeY,pVMergeX, 0, NULL, DRS_SET_COL_DESIGNATIONS) && update_output_xyrange_even_sampling(oy, pVMergeX);
	
	// reverting Kyle's change
	// fixed in update_output_xyrange_even_sampling which is called from set_xyrange_data_ex
	///Kyle 10/14/2009 QA80-14023 OPTION_TO_FORCE_SAMPLING_INTERVAL_RECALCULATION
	//return set_xyrange_data_ex(oy, pVMergeY,pVMergeX, 0, iy);
	return set_xyrange_data_ex(oy, pVMergeY,pVMergeX, 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
	return true;
}

///Kyle 12/22/2008 OUTPUT_COLUMN_COMMENTS
static	void	_set_output_range_comments(XYRange &oy, const XYRange& iy, int nMethod)
{
	string strMethod;
	switch(nMethod)
	{
		case method_mean:
			strMethod = "Mean";
			break;
		case method_median:
			strMethod = "Median";
			break;
		case method_min:
			strMethod = "Min";
			break;
		case method_max:
			strMethod = "Max";
			break;
		case method_sum:
			strMethod = "Sum";
			break;
	}
	string strComments;
	strComments.Format(_L("Duplicates replaced with %s of %s"), _L(strMethod), get_input_data_range_string(iy));

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



void reducedup(const XYRange& iy, const int& method, const double& tol, XYRange& oy, XYRange& xcount)
{
	DWORD dwRules = DRR_NO_WEIGHTS | DRR_GET_DEPENDENT | DRR_NO_FACTORS;
	int nNumRanges = iy.GetNumData(dwRules);
	if (nNumRanges < 1)
		XF_THROW(XFERR_AT_LEAST_ONE_XYRANGE);
	
	double dPrecision = tol;
	int nRet;
	    
	
		
	vector vX, vY, vMergedX, vMergedY;
	vector vDupXs, vDupXsCounts;
	int nDupXs;
	
	for( int ii = 0; ii < nNumRanges; ii++ )
	{
		
		iy.GetData(vY, vX, NULL,  ii);  //// note that all the missing value will be trimmed in getting this data
		if(0 == vY.GetSize() || 0 == vX.GetSize())
		{
			XF_THROW(CER_NO_DATA);
		}
		
		vMergedX = vX; 
		vMergedY = vY;
		int nDataSize = vMergedX.GetSize();
		
		///Jack 12/22/2008 ADD_COUNTS_FOR_DUPXS
		vDupXs.SetSize(nDataSize);
		vDupXsCounts.SetSize(nDataSize);
		nDupXs = nDataSize;
		///End ADD_COUNTS_FOR_DUPXS
		
		///------ Folger 12/26/08 QA80-12856 v8.0991 IMRPOVE_ocmath_xy_remove_duplicates
		/*
		switch(method)
		{
			case method_mean:
				nRet = ocmath_xy_remove_duplicates(&nDataSize, vMergedX, vMergedY, Replace_With_Mean, dPrecision, true, vDupXs, vDupXsCounts, &nDupXs);
				if(nRet<0)
					XF_THROW(XF_REDUCE_DUP_FAIL_TO_REDUCE); // todo: fail to remove duplicate XF_REDUCE_DUP_FAIL_TO_REDUCE
				if(nDataSize<=0)
					XF_THROW(XF_REDUCE_DUP_TO_NULL); // todo: remove duplicate to NULL	XF_REDUCE_DUP_TO_NULL			
				vMergedX.SetSize(nDataSize);
				vMergedY.SetSize(nDataSize);
				///Jack 12/22/2008 ADD_COUNTS_FOR_DUPXS
				if(nDupXs>0)
				{
					vDupXs.SetSize(nDupXs);
					vDupXsCounts.SetSize(nDupXs);
				}
				///End ADD_COUNTS_FOR_DUPXS
				
				break;
			///if define nBin   and nBin >0	use second method				
			case method_median:
				nRet = ocmath_xy_remove_duplicates(&nDataSize, vMergedX, vMergedY, Replace_With_Median, dPrecision, true, vDupXs, vDupXsCounts, &nDupXs);
				if(nRet<0)
					XF_THROW(XF_REDUCE_DUP_FAIL_TO_REDUCE); // todo: fail to remove duplicate
				if(nDataSize<=0)
					XF_THROW(XF_REDUCE_DUP_TO_NULL); // todo: remove duplicate to NULL				
				vMergedX.SetSize(nDataSize);
				vMergedY.SetSize(nDataSize);
				
				///Jack 12/22/2008 ADD_COUNTS_FOR_DUPXS
				if(nDupXs>0)
				{
					vDupXs.SetSize(nDupXs);
					vDupXsCounts.SetSize(nDupXs);
				}
				///End ADD_COUNTS_FOR_DUPXS
				
				break;
			case method_min:
				nRet = ocmath_xy_remove_duplicates(&nDataSize, vMergedX, vMergedY, Replace_With_Min, dPrecision, true, vDupXs, vDupXsCounts, &nDupXs);
				if(nRet<0)
					XF_THROW(XF_REDUCE_DUP_FAIL_TO_REDUCE); // todo: fail to remove duplicate
				if(nDataSize<=0)
					XF_THROW(XF_REDUCE_DUP_TO_NULL); // todo: remove duplicate to NULL				
				vMergedX.SetSize(nDataSize);
				vMergedY.SetSize(nDataSize);
				
				///Jack 12/22/2008 ADD_COUNTS_FOR_DUPXS
				if(nDupXs>0)
				{
					vDupXs.SetSize(nDupXs);
					vDupXsCounts.SetSize(nDupXs);
				}
				///End ADD_COUNTS_FOR_DUPXS
				
				break;
				
			case method_max:
				nRet = ocmath_xy_remove_duplicates(&nDataSize, vMergedX, vMergedY, Replace_With_Max, dPrecision, true, vDupXs, vDupXsCounts, &nDupXs);
				if(nRet<0)
					XF_THROW(XF_REDUCE_DUP_FAIL_TO_REDUCE); // todo: fail to remove duplicate
				if(nDataSize<=0)
					XF_THROW(XF_REDUCE_DUP_TO_NULL); // todo: remove duplicate to NULL				
				vMergedX.SetSize(nDataSize);
				vMergedY.SetSize(nDataSize);
				
				///Jack 12/22/2008 ADD_COUNTS_FOR_DUPXS
				if(nDupXs>0)
				{
					vDupXs.SetSize(nDupXs);
					vDupXsCounts.SetSize(nDupXs);
				}
				///End ADD_COUNTS_FOR_DUPXS
				
				break;
			case method_sum:
				nRet = ocmath_xy_remove_duplicates(&nDataSize, vMergedX, vMergedY, Replace_With_Sum, dPrecision, true, vDupXs, vDupXsCounts, &nDupXs);
				if(nRet<0)
					XF_THROW(XF_REDUCE_DUP_FAIL_TO_REDUCE); // todo: fail to remove duplicate
				if(nDataSize<=0)
					XF_THROW(XF_REDUCE_DUP_TO_NULL); // todo: remove duplicate to NULL				
				vMergedX.SetSize(nDataSize);
				vMergedY.SetSize(nDataSize);
				
				///Jack 12/22/2008 ADD_COUNTS_FOR_DUPXS
				if(nDupXs>0)
				{
					vDupXs.SetSize(nDupXs);
					vDupXsCounts.SetSize(nDupXs);
				}
				///End ADD_COUNTS_FOR_DUPXS
				
				break;
		}
		/// End REDUCE_DATA_XF
		*/
		
		if ( (nDataSize = ocmath_xy_remove_duplicates(vMergedX, vMergedY, nDataSize, method, dPrecision, true, vDupXs, vDupXsCounts, &nDupXs)) < OE_NOERROR )
			XF_THROW(XF_REDUCE_DUP_FAIL_TO_REDUCE); // todo: fail to remove duplicate XF_REDUCE_DUP_FAIL_TO_REDUCE
		if(nDataSize<=0)
			XF_THROW(XF_REDUCE_DUP_TO_NULL); // todo: remove duplicate to NULL	XF_REDUCE_DUP_TO_NULL			
		vMergedX.SetSize(nDataSize);
		vMergedY.SetSize(nDataSize);
		///Jack 12/22/2008 ADD_COUNTS_FOR_DUPXS
		if(nDupXs>0)
		{
			vDupXs.SetSize(nDupXs);
			vDupXsCounts.SetSize(nDupXs);
		}
		///End ADD_COUNTS_FOR_DUPXS
		
		///------ End IMRPOVE_ocmath_xy_remove_duplicates
		
		
		if(!oy)  // if not specified an output range, create one for it
		{
			Worksheet wks;
			wks.Create();
			wks.SetSize(-1, 2);
			oy.Create();
			xy_range_from_wks_cols(oy,wks,0,1);
		}
		///Kyle 08/19/2009 QA80-14023 FIX_OUTPUT_SAMPLING_INTERVAL_IS_LOST_WHEN_INPUT_IS_LOOSE_DATASET
		//_reducexy_set_data_range(oy,&vMergedX, &vMergedY);
		_reducexy_set_data_range(oy,&vMergedX, &vMergedY, iy);
		///End FIX_OUTPUT_SAMPLING_INTERVAL_IS_LOST_WHEN_INPUT_IS_LOOSE_DATASET
		
		///Jack 12/22/2008 ADD_COUNTS_FOR_DUPXS
		if(nDupXs>0 && xcount)
			///Kyle 08/19/2009 QA80-14023 FIX_OUTPUT_SAMPLING_INTERVAL_IS_LOST_WHEN_INPUT_IS_LOOSE_DATASET
			//_reducexy_set_data_range(xcount,&vDupXs, &vDupXsCounts);
			_reducexy_set_data_range(xcount,&vDupXs, &vDupXsCounts, iy);
			///End FIX_OUTPUT_SAMPLING_INTERVAL_IS_LOST_WHEN_INPUT_IS_LOOSE_DATASET
		///End ADD_COUNTS_FOR_DUPXS
		
		//_reducexy_update_report_data(rd, vMergedX, vMergedY);
		
		//else
		// supply each yStatsChecked to yStats for each check box to 
		// use vTempMergedX
		// append to vector  and set to range
		
		///Kyle 12/04/2008 ADD_PLOT_TO_GRAPH_IF_FROM_GRAPH
		xf_check_plot_output_rng_in_source_rng_graph(iy, oy);
		///End ADD_PLOT_TO_GRAPH_IF_FROM_GRAPH
	
		///Kyle 12/22/2008 OUTPUT_COLUMN_COMMENTS
		_set_output_range_comments(oy, iy, method);
		///End 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 reducedup_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return reducedup_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	return false;

}

int reducedup_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 reducedup_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	///Kyle 12/22/2008 OPEN_DIALOG_WHEN_THEME_IS_USED_AND_ERROR_HAPPENS
	if(is_xf_startup(nGetNDialog, dwCntrl))
	{
		if ( (dwCntrl&LTXF_THEME_USED) && nGetNDialog <= 0 )
		{
			string strErrMsg;
			if(!_check_input(trGetN, strErrMsg))
				nRet = XFEVT_PROCEED_WITH_DLG;
		}
	}
	///End OPEN_DIALOG_WHEN_THEME_IS_USED_AND_ERROR_HAPPENS
}
//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 reducedup_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

	bOKEnable = _check_input(trGetN, strErrMsg);

	if(bOKEnable)
	{
		Worksheet wks = wksTemp;
		wks.SetSize(-1, 2);
		wks.SetColDesignations("XY");
		wks.Columns(1).SetLongName("ReduceDuplicate");
	}
	s_bInit = false;
	s_strErrMsg = strErrMsg;
	bUpdateGraph = bOKEnable;
	bUpdateGrid = true;
	///End UPDATE_XF_TO_SHOW_PREVIEW
}

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

// 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
	///Kyle 12/02/2008 QA80-12405-S1 UPDATE_XF_TO_SHOW_PREVIEW
	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
	///End UPDATE_XF_TO_SHOW_PREVIEW
}

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

static void GetNGraphPreview_OnUpdateGraph(TreeNode& trGetN, PageBase& pgTemp, Datasheet& wksTemp, PictureControl& pict)
{
	///Kyle 12/02/2008 QA80-12405-S1 UPDATE_XF_TO_SHOW_PREVIEW
	Worksheet wks = wksTemp;
	if(!s_bInit)
	{
		Worksheet wks = wksTemp;
		wks.SetSize(0,-1, true);
		//--- CPY 12/19/08 USE_SHARED_TEMPLATE_FOR_ALL_PREVIEW_XF
		//init_preview_graph(trGetN.iy, pgTemp, wks, "reducedupline");
		///Kyle 06/03/2009 GET_SOURCE_GRAPH_SCALE_TYPE
		//init_preview_graph(trGetN.iy, pgTemp, wks, "CurvePreview");
		init_preview_graph(trGetN.iy, pgTemp, wks, "CurvePreview", NULL, NULL, 0, 0, 1, PREVIEW_LAYER_FORMAT_SCALE_TYPE);
		///End GET_SOURCE_GRAPH_SCALE_TYPE
		//---
		GraphPage gp = pgTemp;
		gp.Refresh(true);
		s_bInit = true;
	}
	_run_resample_on_current_data(trGetN, pgTemp, wks);
	///End UPDATE_XF_TO_SHOW_PREVIEW
}

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

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
	
	bOKEnable = _check_input(trGetN, strErrMsg);
	bUpdateGrid = true;
	
	
	///Kyle 12/02/2008 QA80-12405-S1 UPDATE_XF_TO_SHOW_PREVIEW
	if (trNode && (trNode.tagName =="iy"))
	{
		s_bInit = false;
	}
	
	if(!bOKEnable)
		dwUpdateGraph = UPDATE_GRAPH_INVALID; //nUpdateGraph = UPDATE_GRAPH_ERROR;
	else
		bUpdateGraph = bOKEnable;
	///End UPDATE_XF_TO_SHOW_PREVIEW
}

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

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

