#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
#include <o8dlg.h>
#include <..\OriginLab\PAWizCore.h>

#include <..\OriginLab\XFWizard_utils.h>
#include <..\OriginLab\graph_utils.h>
#include <..\OriginLab\curve_utils.h>
#include <..\OriginLab\nlsf_utils.h>
#include <event_utils.h>
#include <..\OriginLab\NLFitSession.h>
#include <ReportTree.h>


/*------------------------------------------------------------------------------*
 * Modification Log:  															*
 *	Sophy 11/10/2008 CLEAN_CODE_ADD_BASELINE_INFO_TO_REPORT_TABLE				*
 *  Iris 12/02/2008 v8.0981b QA80-12701 FIX_BACK_TO_BASECREATE_NOT_KEEP_BASELINE_FUNC_IF_CHANGE_FUNC_IN_FITPEAK*
 *	Folger 12/03/08 v8.0982 CHECK_CREATE_BASELINE_SHOULD_BE_MEMBER_OF_PAWIZCORE	*
 *	Folger 12/03/08 QA80-12701 v8.0982 THEME_SETTING_CONTROL_FOR_BASELINE_FUNCTION_APPLIED_IN_PA_FIT
 *	Kyle 12/24/2008 ADD_COMMENTS_FOR_OUTPUT_DATA								*
 *	Sim 01-07-2008 QA80-12833 FIX_APPLY_XF_WIZ_XF_TWICE							*
 *  Iris 8/21/2009 QA80-14165 SHOW_PRO_CONTROL_WITH_DISABLE_AND_PRO_TAG			*
 *	Jasmine 09/02/09 SHOW_PRO_ONLY_REMINDER_MSG									*
 *	Folger 09/05/09 REDUNDANT_LEGEND_APPEARS_WHEN_CREATE_BASELINE_ON_SCRIPT_MODE*
 *  Iris 2/02/2010 QA81-14165 ALSO_SHOW_PRO_IN_PRO_VERSION						*
 *	Jasmine 04/13/10 QA81-15304 UPDATE_LIST_FREQUENTLY_SINCE_USE_MAY_ADD_BASELINE_FUNC_BY_FO
 *	Jasmine 04/14/10 QA81-15304 ANNOUNCE_FITTING_FUNC_CHANGE					*
 *------------------------------------------------------------------------------*/
 
enum{
	connect_none = -1,
	connect_interpolate = 0,
	connect_fitting = 1,
	
	connect_items_count = 2
};


#define _STR_BUTTON_LIST_IN_MODIFY ("Add|Modify/Del")
//#define _STR_BUTTON_SUBTRACT ("Subtract")
//#define _STR_BUTTON_NO_SUBTRACT ("No Subtract")


#define _BASELINE_RDID_TABLE   200
#define _BASELINE_X_RDID_TABLE 201
#define _BASELINE_Y_RDID_TABLE 202

bool _update_baseline_param_names_in_tree(TreeNode& trFit, const vector& vParams = NULL)
{
	string strFuncName;
	string strFileName;
	vector<string> vstrParamNames;
	int nFuncIndex = trFit.func.nVal;
	if( !nlsf_get_func(nFuncIndex, strFuncName, strFileName, STR_PA_NLSF_CAT_BASELINE) )
		return false;
		
	nlsf_get_param_names(strFuncName, STR_PA_NLSF_CAT_BASELINE, vstrParamNames);


	int iNum = vstrParamNames.GetSize();
	if (vParams!=NULL)
		if (vParams.GetSize()!=iNum)
			return false;

	int ii = 0;
	Collection<TreeNode> pars;
	pars = trFit.Parameters.Children;
	foreach (TreeNode tr in pars)
	{
		if (ii<iNum && ii<pars.Count())
		{
			tr.SetAttribute(STR_LABEL_ATTRIB, vstrParamNames[ii]);
			if (vParams==NULL)
				tr.dVal = 0;
			else
				tr.dVal = vParams[ii];
			tr.Show = true;
		}
		else
		{
			tr.SetAttribute(STR_LABEL_ATTRIB, _L(""));
			tr.Show = false;
			tr.dVal = 0;
		}
		ii ++;
	}
	return true;
}
///Kyle 10/09/08 USE_NEW_NLFSESSION
//static bool _create_baseline_by_fitting(string strFuncName, const vector& vx, const vector&vy, vector& vX, vector& vY, vector& vParams)
static bool _create_baseline_by_fitting(string strFuncName, XYRange xyRange, vector& vX, vector& vY, vector& vParams)
///End USE_NEW_NLFSESSION
{
	///Kyle 10/09/08 USE_NEW_NLFSESSION
	//NLFitSessionBase fit(false);

	//if (!fit.SetData(vy, vx))
	//{
		//return false;
	//}
	NLFitSession fit();
	if(!xyRange.IsValid())
		return false;
	Tree trRange;
	xyRange.GetTree( trRange, false);
	if ( ! prepare_input_data_for_operation(trRange, true) )
		return false;
	///End USE_NEW_NLFSESSION
	
	if (!fit.SetFunction(strFuncName, STR_PA_NLSF_CAT_BASELINE))
	{
		return false;
	}
	
	///Kyle 10/09/08 USE_NEW_NLFSESSION
	if (!fit.SetData(trRange))
	{
		return false;
	}
	///End USE_NEW_NLFSESSION
	
	if (!fit.ParamsInitValues())
	{
		return false;
	}

	vector vErrors;
	int nFitOutcome;

	if(!fit.IsReadyIterations())///Sandy 2009-1-7 add error checking
		return false;
	
	fit.Fit(&nFitOutcome);
	vector vTmp;
	if (!fit.GetFitResultsParams(vParams, vErrors))
	{
		return false;
	}
	
	if(!nlsf_evaluate(strFuncName, STR_PA_NLSF_CAT_BASELINE, vX, vY, vParams))
		return false;

	return true;
}

///Kyle 10/09/08 USE_NEW_NLFSESSION
//static bool _update_baseline_fit_tree(PAWizCore* paCore, vector&vbxFitted, vector& vbyFitted, const vector& vbx, const vector& vby, int nFuncIndex,  TreeNode& trParams, string& strErrMsg)
static bool _update_baseline_fit_tree(PAWizCore* paCore, vector&vbxFitted, vector& vbyFitted, const XYRange xyRange, int nFuncIndex,  TreeNode& trParams, string& strErrMsg)
///End USE_NEW_NLFSESSION
{
	DataPlot dpbl;
	Page pg = Project.Pages();
	
	vector vxNewb, vyNewb, vParams;
	
	string strFuncName, strFileName;
	if( !nlsf_get_func(nFuncIndex, strFuncName, strFileName, STR_PA_NLSF_CAT_BASELINE) )
	{
		strErrMsg = XFERR_FAIL_SET_FUNCTION;	
		return false;				
	}	
	
	///Kyle 10/09/08 USE_NEW_NLFSESSION
	//if (!_create_baseline_by_fitting(strFuncName,   vbx, vby, vbxFitted, vbyFitted, vParams))
	if (!_create_baseline_by_fitting(strFuncName, xyRange, vbxFitted, vbyFitted, vParams))
	///End USE_NEW_NLFSESSION
	{
		strErrMsg = NLFIT_OUTCOME_FAILED_FROM_FUNC;	
		return false;				
	}
	
	pa_vParams2tr(vParams, trParams);
	///Sophy 11/10/2008 CLEAN_CODE_ADD_BASELINE_INFO_TO_REPORT_TABLE
	//Tree treeParams;
	//
	//if(!pa_make_baseline_param_tree(treeParams,strFuncName, vParams) )
		//XF_THROW(XFERR_FAIL_CONVERT_BASELINE_PARAM_TREE);
	//
	//paCore->UpdateInfoTree(treeParams, PA_TREE_BASELINE_FIT_INFO, true); 
	Tree		treeParams;
	TreeNode	trBLParams = tree_check_get_node( treeParams, STR_BASELINE_PARAM_TREE );
	if(!pa_make_baseline_param_tree( trBLParams,strFuncName, vParams ) )
		XF_THROW(XFERR_FAIL_CONVERT_BASELINE_PARAM_TREE);

	//------ Folger 12/03/08 QA80-12701 v8.0982 THEME_SETTING_CONTROL_FOR_BASELINE_FUNCTION_APPLIED_IN_PA_FIT
	//trBLParams.SetAttribute(STR_BASEFUNC_FROM_BASECREATE_XF_ATTRIB, 1);  /// Iris 12/02/2008 v8.0981b QA80-12701 FIX_BACK_TO_BASECREATE_NOT_KEEP_BASELINE_FUNC_IF_CHANGE_FUNC_IN_FITPEAK
	//------
	paCore->UpdateInfoTree( trBLParams, PA_TREE_BASELINE_FIT_INFO, true ); 
	///end CLEAN_CODE_ADD_BASELINE_INFO_TO_REPORT_TABLE
	return true
}



static void _create_x_data_for_fitting(const vector& vx, vector& vxFit, int nSize)
{	
	double dxMin, dxMax;	
	vx.GetMinMax(dxMin, dxMax);
	vxFit.SetSize(nSize);
	if(nSize == vx.GetSize())
		vxFit = vx;
	else
		vxFit.Data(dxMin, dxMax, (dxMax-dxMin)/(nSize-1));
}


static bool _set_npts_with_data(TreeNode trGetN)
{

	TreeNode trN = trGetN.npts;
	if(!trN.IsValid())
		return false;
	
	if(1==octree_get_auto_support(&trN))
	{
		
		PAWizCore* paCore = (PAWizCore*)get_xf_core_handler(trGetN);
		ASSERT(paCore);
		
		XYRange xyOrigin;
		if(!paCore->GetOriginalRange(xyOrigin))
		{
			error_report("fail in get xyrange in PACore!");
			return false;
		}		
		
		vector vx, vy;
		if(!xyOrigin.GetData(vy, vx))
			return false;

		trN.nVal = vy.GetSize();
	}
	
	return true;
}

///Sandy 2008-12-30 move to pawizcore
/*
///Kyle 12/24/2008 ADD_COMMENTS_FOR_OUTPUT_DATA
static	void	_set_output_range_comments(const XYRange& iy, XYRange& oy)
{
	string	strComments;
	strComments.Format("Baseline of %s", get_input_data_range_string(iy));
	oy.SetOutputComment(strComments);
}
///End ADD_COMMENTS_FOR_OUTPUT_DATA
*/


void pa_basecreate(const XYRange& iy, const int& connect, const int& snap, const TreeNode& btns_modify, const int& npts, const TreeNode& connect_Interp, const TreeNode& connect_fit, XYRange& oyb, const TreeNode& trAnchorXY, const int& nXFCorePointer, const TreeNode& btn_subtract, const int& subtract)
{
	///---Sim 01-07-2008 QA80-12833 FIX_APPLY_XF_WIZ_XF_TWICE
	//PAWizCore* paCore = (PAWizCore*)get_xf_core_handler(getnhandler);
	PAWizCore* paCore = (PAWizCore*)get_xf_core_handler(NODE_NAME_XF_WIZ_CORE_POINTER);
	///---END QA80-12833 FIX_APPLY_XF_WIZ_XF_TWICE
	if(!paCore)
		XF_THROW(XF_ERR_INVALID_PA_INSTANCE);	
	///---Sim 01-07-2008 QA80-12833 FIX_APPLY_XF_WIZ_XF_TWICE
	TreeNode getnhandler;
	bool bRet = paCore->GetGetN(getnhandler);
	ASSERT(bRet);
	///---END QA80-12833 FIX_APPLY_XF_WIZ_XF_TWICE
	
	XYRange xyOrigin;
	vector vx, vy;
	if(!paCore->GetOriginalRange(xyOrigin) || !xyOrigin.GetData(vy, vx))
	{
		XF_THROW(XF_ERR_INVALID_PA_INSTANCE);
	}
	
	
	vector vxAnchors, vyAnchors;
	XYRange xyAnchors;
	if(!paCore->GetBaseAnchorsRange(xyAnchors) || !xyAnchors.GetData(vyAnchors, vxAnchors)|| vxAnchors.GetSize() < 2)
	{
	XF_THROW(XF_ERR_INVALID_PA_INSTANCE);
	}
	
	if(!anchors_to_tree(vxAnchors, vyAnchors, trAnchorXY, true))
	{
		error_report("Fail to get anchors from trGetN!");
	}
	
	vector vbx, vby;
	if(connect == connect_fitting)
	{
		_create_x_data_for_fitting(vx, vbx, npts);
		vby.SetSize(npts);
	
		string strErrMsg;
		///Kyle 10/09/08 USE_NEW_NLFSESSION
		//if(!_update_baseline_fit_tree(paCore, vbx, vby, vxAnchors, vyAnchors, connect_fit.func.nVal, connect_fit.Parameters, strErrMsg))
		if(!_update_baseline_fit_tree(paCore, vbx, vby, xyAnchors, connect_fit.func.nVal, connect_fit.Parameters, strErrMsg))
		///End USE_NEW_NLFSESSION
		{		
			XF_THROW(atoi(strErrMsg));
		}
		
		//------ Folger 12/03/08 QA80-12701 v8.0982 THEME_SETTING_CONTROL_FOR_BASELINE_FUNCTION_APPLIED_IN_PA_FIT
		Tree	trBLParams;
		paCore->UpdateInfoTree( trBLParams, PA_TREE_BASELINE_FIT_INFO, false ); 
		if ( connect_fit.FitFuncUsing.nVal != connect_fit.func.nVal )
		{
			trBLParams.SetAttribute(STR_BASEFUNC_FROM_BASECREATE_XF_ATTRIB, 1);  /// Iris 12/02/2008 v8.0981b QA80-12701 FIX_BACK_TO_BASECREATE_NOT_KEEP_BASELINE_FUNC_IF_CHANGE_FUNC_IN_FITPEAK
			paCore->UpdateInfoTree( trBLParams, PA_TREE_BASELINE_FIT_INFO, true ); 
			getnhandler.connect_fit.FitFuncUsing.nVal = connect_fit.func.nVal;
		}
		//------ End THEME_SETTING_CONTROL_FOR_BASELINE_FUNCTION_APPLIED_IN_PA_FIT		
		
	}
	else if(connect == connect_interpolate)
	{
		vbx = vxAnchors;
		vby = vyAnchors;
		int nRet = interpolate_baseline_base_on_data(vbx, vby, vx, vy, npts, connect_Interp.type.nVal);
		if(OE_NOERROR != nRet)
		{
			XF_THROW(XF_ENVELOPE_FAILED_TO_INTERPOLATE);
		}		
		
		Tree treeParams;
		paCore->UpdateInfoTree(treeParams, PA_TREE_BASELINE_FIT_INFO, true); //for reset the baseline info tree
		paCore->SetBaseIntepType(connect_Interp.type.nVal);
	}
	
	//if(!anchors_to_tree(vxAnchors, vyAnchors, trAnchorXY))
	//{
		//error_report("fail in set anchors to tree!");
	//}	
	
	XYRange xyBaseline;
	if(paCore->GetBaselineRange(xyBaseline) && xyBaseline.IsValid())
		xyBaseline.SetData(&vby, &vbx, 0, NULL, DRS_SET_COL_DESIGNATIONS);		
	
	
	
	int goal = paCore->GetCurrGoal();
	if(goal == PA_GOAL_CREATE_BASELINE )//if goal is create baseline, baseline should output to user assigned dataset
	{
		//Worksheet wks;
		//rd_oyb.GetWorksheet(wks);
		//wks.SetSize(-1,0);
	
		//int nID = 100; 
		//int nTableFormat = GETNBRANCH_OPEN | GETNBRANCH_HIDE_COL_HEADINGS| GETNBRANCH_HIDE_ROW_HEADINGS | GETNBRANCH_FIT_COL_WIDTH | GETNBRANCH_FIT_ROW_HEIGHT;
		
		//rd_oyb.ID = nID++; 
		//rd_oyb.SetAttribute(STR_LABEL_ATTRIB, "Baseline"); //Table title
		//rd_oyb.SetAttribute(TREE_Table, nTableFormat);
		
		//Sandy 2008-11-11 change to XYRange output, keep same format with subtracted data
		//ReportTable rt;
		//rt = rd_oyb.CreateTable("baseline", _L("Baseline"), _BASELINE_RDID_TABLE);
		//rt.AddColumn(vbx, "X", _BASELINE_X_RDID_TABLE, "X", OKDATAOBJ_DESIGNATION_X);
		//rt.AddColumn(vby, "Y", _BASELINE_Y_RDID_TABLE, "Y", OKDATAOBJ_DESIGNATION_Y);	
		
		///Sandy 2008-12-30 centralize code to pawizcore		
		//if(oyb)
		//{
			//oyb.SetData(&vby, &vbx, 0, NULL, DRS_SET_COL_DESIGNATIONS);
			//_set_output_range_comments(iy, oyb);		///Kyle 12/24/2008 ADD_COMMENTS_FOR_OUTPUT_DATA
		//}
		output_baseline_if_create_baseline(iy, oyb, paCore, vbx, vby);	
	}
	
	//---end centralize code to pawizcore	
	
	
	
	
}

//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 pa_basecreate_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return pa_basecreate_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	
	if (nEventID == GETNE_ON_INIT)
	{	
		xf_turnon_user_event_receiver(trGetN);
	}
	
	PAWizCore* paCore = (PAWizCore*)get_xf_core_handler(trGetN);
	ASSERT(paCore);	
	
	///Sandy 2008-12-30 centralize code to pawizcore
	if(process_create_baseline_handler(trGetN, nEventID, lpcszNodeName, paCore))
		return true;
	//int goal = paCore->GetCurrGoal();
	//if( goal == PA_GOAL_CREATE_BASELINE && 0 == lstrcmp(lpcszNodeName, "btn_subtract") || nEventID == GETNE_ON_UNDO)
	//{
		//bool bUndoSubtract = ((nEventID == GETNE_ON_UNDO)? true : (bool)(trGetN.subtract.nVal));
		//if(!create_subtracted_plot(paCore, bUndoSubtract))
			//error_report("fail to create subtracted plot");
			//
		//if(bUndoSubtract)
		//{
			//trGetN.subtract.nVal = false;
			//trGetN.btn_subtract.SetAttribute(STR_COMBO_ATTRIB, _STR_BUTTON_SUBTRACT);
		//}
		//else
		//{
			//trGetN.subtract.nVal = true;
			//trGetN.btn_subtract.SetAttribute(STR_COMBO_ATTRIB, _STR_BUTTON_NO_SUBTRACT);
		//}
		//return true;
	//}	
	
	/// Iris 8/21/2009 QA80-14165 SHOW_PRO_CONTROL_WITH_DISABLE_AND_PRO_TAG
	string strConnectErrMsg;	///Jasmine 09/02/09 SHOW_PRO_ONLY_REMINDER_MSG
	/// Iris 2/02/2010 QA81-14165 ALSO_SHOW_PRO_IN_PRO_VERSION
	//if( !is_pro_version() ) 
	//{
	///End ALSO_SHOW_PRO_IN_PRO_VERSION
		string strCombo;
		if( nEventID == GETNE_ON_INIT && trGetN.connect.GetAttribute(STR_COMBO_ATTRIB, strCombo) )
		{
			vector<string> vs;
			strCombo.GetTokens(vs, '|');
			if( connect_items_count == vs.GetSize() && vs[connect_fitting].Find('(') < 0 )
			{
				vs[connect_fitting] += " " + STR_PRO_POSTFIX;
				strCombo.SetTokens(vs, '|');
				trGetN.connect.SetAttribute(STR_COMBO_ATTRIB, strCombo);
			}
			//else ///Jasmine 04/13/10 when go to another step and come back to this step, vs[connect_fitting] has STR_PRO_POSTFIX. it's correct so no assert.
			//{
				//ASSERT(0);
			//}
		}
		
	/// Iris 2/02/2010 QA81-14165 ALSO_SHOW_PRO_IN_PRO_VERSION
	if( !is_pro_version() ) 
	{
	///End ALSO_SHOW_PRO_IN_PRO_VERSION
		if( (0 == lstrcmp(lpcszNodeName, "connect") || nEventID == GETNE_ON_INIT || nEventID == GETNE_ON_THEME) && trGetN.connect.nVal == connect_fitting )
		{
			string strProOption = get_selected_string_from_combolist(trGetN.connect);
			strErrMsg = XFERR_PRO_OPTION_WARNNING_MSG;
			strErrMsg += ":" + strProOption;
			strConnectErrMsg = strErrMsg; // warnning message	///Jasmine 09/02/09 SHOW_PRO_ONLY_REMINDER_MSG
			
			trGetN.connect.nVal = connect_interpolate;
		}				
	}
	///end SHOW_PRO_CONTROL_WITH_DISABLE_AND_PRO_TAG
	
	if(0 == lstrcmp(lpcszNodeName, "connect") || nEventID ==GETNE_ON_INIT)
	{
		trGetN.connect_Interp.Show = (trGetN.connect.nVal == connect_interpolate ? true:false);
		trGetN.connect_fit.Show = (trGetN.connect.nVal == connect_fitting ? true:false);
		trGetN.npts.Show = (trGetN.connect.nVal == connect_none ? false:true);
		trGetN.btns_modify.Show = (trGetN.connect.nVal == connect_none ? false:true);
		trGetN.snap.Show = (trGetN.connect.nVal == connect_none ? false:true);		
	}
	
	if( 0 == lstrcmp(lpcszNodeName, "npts") || nEventID ==GETNE_ON_INIT )
	{
		_set_npts_with_data(trGetN);
	}
	
	
	///Jasmine 04/14/10 QA81-15304 ANNOUNCE_FITTING_FUNC_CHANGE
	bool bUpdateFitFuncList = false;
	if(GETNE_ON_EXTERNAL_MSG == nEventID)
	{
		int nMsg, nUserEventInfo;
		if( xf_check_is_user_event( trGetN, nMsg, &nUserEventInfo ) )
		{
			if(EXTERNAL_MSG_FO_CHANGE_FUNC == nMsg)
			{
				bUpdateFitFuncList = true;
			}
		}
	}
	else if(nEventID == GETNE_ON_INIT)
		bUpdateFitFuncList = true;
	///Jasmine 04/13/10 QA81-15304 UPDATE_LIST_FREQUENTLY_SINCE_USE_MAY_ADD_BASELINE_FUNC_BY_FO
	TreeNode trFunc = trGetN.connect_fit.func;
	if(bUpdateFitFuncList && trFunc)
	{
		vector<string> vsFunc;
		vector<string> vsFile;
		nslf_get_func_list(vsFunc, vsFile, STR_PA_NLSF_CAT_BASELINE);
		set_combo_string(trFunc, vsFunc);
		GETN_CHANGE_GRID
	}
	///End UPDATE_LIST_FREQUENTLY_SINCE_USE_MAY_ADD_BASELINE_FUNC_BY_FO
	///End ANNOUNCE_FITTING_FUNC_CHANGE
	
	int	nUserEvent = -1;	
	bool bPointsModified = (xf_check_is_user_event(trGetN, nUserEvent));
	if(nEventID == GETNE_ON_INIT || bPointsModified || 0 == lstrcmp(lpcszNodeName, "btns_modify")
		|| 0 == lstrcmp(lpcszNodeName, "snap") ||  0 == lstrcmp(lpcszNodeName, "connect") || 0 == lstrcmp(lpcszNodeName, "func")
		|| 0 == lstrcmp(lpcszNodeName, "npts") || 0 == lstrcmp(lpcszNodeName, "type")
		|| bUpdateFitFuncList)	///Jasmine 04/14/10 QA81-15304 ANNOUNCE_FITTING_FUNC_CHANGE
	{
		
		if(0 == lstrcmp(lpcszNodeName, "btns_modify") )
		{
			modify_baseline_points_buttons(paCore, trGetN.btns_modify.nVal);
		}		
		
	
		///Sandy 2008-10-21 For indicate all anchors are deleted.
		//if((bPointsModified && nUserEvent == WPARAM_DONE_DLG_COSE))
		if ( bPointsModified && (nUserEvent == WPARAM_DONE_DLG_COSE || nUserEvent == WPARAM_NONE_ANCHOR))
		{
			resume_anchor_plot_after_modify_done(paCore, nUserEvent == WPARAM_DONE_DLG_COSE);
			GETN_CHANGE_GRID
		}
	
		if(!create_anchor_plot(paCore,trGetN.trAnchorXY, false))
		{
			error_report("fail in get dataplot from anchor range!");
			return false;
		}
		
	
		XYRange xyOrigin, xyAnchors, xyBaseline;
		if(!paCore->GetOriginalRange(xyOrigin) || !paCore->GetBaseAnchorsRange(xyAnchors) || !paCore->GetBaselineRange(xyBaseline))
		{
			error_report("fail in get xyrange in PACore!");
			return false;
		}
		
		vector vx, vy, vxAnchors, vyAnchors, vxBaseline, vyBaseline;
		if(!xyOrigin.GetData(vy, vx) || !xyAnchors.GetData(vyAnchors, vxAnchors))
		{
			error_report("fail in get data in PACore!");
			return false;		
		}
		if(trGetN.snap.nVal)
		{
			snap_points_to_source_data(vx, vy, vxAnchors, vyAnchors);
			xyAnchors.SetData(&vyAnchors, &vxAnchors, 0, NULL, DRS_SET_COL_DESIGNATIONS);
		}	
		
		if(trGetN.connect.nVal == connect_fitting)
		{			
			if(0 == lstrcmp(lpcszNodeName, "connect")	|| 0 == lstrcmp(lpcszNodeName,"func") || nEventID ==GETNE_ON_INIT
				|| bUpdateFitFuncList)	///Jasmine 04/14/10 QA81-15304 ANNOUNCE_FITTING_FUNC_CHANGE
			{
				if( !_update_baseline_param_names_in_tree(trGetN.connect_fit) )
				{
					strErrMsg = XFERR_FAIL_GET_PARAMETERS; 
					return false;
				}
			}
		
			if(bPointsModified  || nEventID == GETNE_ON_INIT  || 0 == lstrcmp(lpcszNodeName, "btns_modify") 
				|| 0 == lstrcmp(lpcszNodeName, "connect") || 0 == lstrcmp(lpcszNodeName, "func")
				|| 0 == lstrcmp(lpcszNodeName, "npts")  || 0 == lstrcmp(lpcszNodeName, "snap")
				|| bUpdateFitFuncList)	///Jasmine 04/14/10 QA81-15304 ANNOUNCE_FITTING_FUNC_CHANGE
			{
				strErrMsg = ""; 
				int nSize = trGetN.npts.nVal;		
				_create_x_data_for_fitting(vx, vxBaseline, nSize);		
				vyBaseline.SetSize(nSize);
				///Kyle 10/09/08 USE_NEW_NLFSESSION
				//if(!(bOKEnable = _update_baseline_fit_tree(paCore, vxBaseline, vyBaseline,vxAnchors, vyAnchors, trGetN.connect_fit.func.nVal, trGetN.connect_fit.Parameters, strErrMsg)))
				if(!(bOKEnable = _update_baseline_fit_tree(paCore, vxBaseline, vyBaseline, xyAnchors, trGetN.connect_fit.func.nVal, trGetN.connect_fit.Parameters, strErrMsg)))
				///End USE_NEW_NLFSESSION
				{
					return false;
				}
				strErrMsg = strConnectErrMsg;	///Jasmine 09/02/09 SHOW_PRO_ONLY_REMINDER_MSG, low priority 
			}
		}
		
		if(trGetN.connect.nVal == connect_interpolate)
		{
			if(bPointsModified || nEventID == GETNE_ON_INIT || 0 == lstrcmp(lpcszNodeName, "btns_modify") 
				|| 0 == lstrcmp(lpcszNodeName, "connect")	|| 0 == lstrcmp(lpcszNodeName, "type") 
				|| 0 == lstrcmp(lpcszNodeName, "npts")		|| 0 == lstrcmp(lpcszNodeName, "snap"))
			{
	
				vector vxTemp, vyTemp;
				vxTemp = vxAnchors;
				vyTemp = vyAnchors;
				strErrMsg = ""; 
				int nRet = interpolate_baseline_base_on_data(vxTemp, vyTemp,  vx,  vy, trGetN.npts.nVal, trGetN.connect_Interp.type.nVal);
				if(OE_NOERROR != nRet)
				{
					strErrMsg = XF_ENVELOPE_FAILED_TO_INTERPOLATE;
					bOKEnable = false;
					return true;
				}
				vxBaseline = vxTemp;
				vyBaseline = vyTemp;
				strErrMsg = strConnectErrMsg;	///Jasmine 09/02/09 SHOW_PRO_ONLY_REMINDER_MSG
			}
		}
		
		if(!anchors_to_tree(vxAnchors, vyAnchors, trGetN.trAnchorXY))
		{
			error_report("fail to set anchors' XY to trGetN");
		}
		
	 	if(!xyBaseline.SetData(&vyBaseline, &vxBaseline, 0, NULL, DRS_SET_COL_DESIGNATIONS))
	 	{
	 		error_report("fail in set data in PACore!");
	 		return false;
	 	}
	
	 	//------ Folger 12/03/08 v8.0982 CHECK_CREATE_BASELINE_SHOULD_BE_MEMBER_OF_PAWIZCORE
	 	//create_baseline_plot( paCore, false);// keep data 
	 	paCore->CheckCreateBaselinePlot(false);
	 	//------
	 	return true;
	}
	
		

}

int pa_basecreate_make_tree(TreeNode& tr, LPCSTR lpcszVarName)
{
	if(tr.IsValid())
	{
		
		string strVarName = lpcszVarName;
		int nBranchID;
	
		if (strVarName == "connect_Interp")
		{
			nBranchID = GET_USER_DATAID(0);
			GETN_USE(tr)  GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
			///Sophy 10/20/2008 CLEAN_CODE_ADD_BASELINE_INFO_TO_REPORT_TABLE
			//GETN_RADIO_INDEX(type, 0, _L("Line|Spline|BSpline")) GETN_ID(nBranchID + 1)		
			GETN_RADIO_INDEX(type, 0, _L(STR_INTERP_FUNCTION_LIST)) GETN_ID(nBranchID + 1)		
			///end CLEAN_CODE_ADD_BASELINE_INFO_TO_REPORT_TABLE
		}
		if (strVarName == "connect_fit" && is_pro_version())
		{
			///Jasmine 04/13/10 QA81-15304 UPDATE_LIST_FREQUENTLY_SINCE_USE_MAY_ADD_BASELINE_FUNC_BY_FO
			//vector<string> vsFunc;
			//vector<string> vsFile;
			//nslf_get_func_list(vsFunc, vsFile, "Baseline");
			///End UPDATE_LIST_FREQUENTLY_SINCE_USE_MAY_ADD_BASELINE_FUNC_BY_FO
			
			nBranchID = GET_USER_DATAID(10);
			GETN_USE(tr)  GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
			GETN_LIST(func, _L("Function"), 0, "")  GETN_ID(nBranchID  + 1)
			//set_combo_string(tr.func, vsFunc);///Jasmine 04/13/10 QA81-15304 UPDATE_LIST_FREQUENTLY_SINCE_USE_MAY_ADD_BASELINE_FUNC_BY_FO
			
			//------ Folger 12/03/08 QA80-12701 v8.0982 THEME_SETTING_CONTROL_FOR_BASELINE_FUNCTION_APPLIED_IN_PA_FIT
			TreeNode trFitFuncUsing = tree_check_get_node_by_dataid(tr, "FitFuncUsing", PA_BASE_CREATE_DATAID_FUNCTION_USING);
			trFitFuncUsing.nVal = -1;
			trFitFuncUsing.Show = false;
			//------
	
			{
				TreeNode trParams = tr.AddNode("Parameters");
				GETN_USE(trParams) GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
					GETN_NUM(p0, "", 0.0) GETN_ID(GET_USER_DATAID(0)) GETN_READ_ONLY_COLOR GETN_OPTION_COLOR_READONLY(RGB(20,150,10))
					GETN_NUM(p1, "", 0.0) GETN_ID(GET_USER_DATAID(1)) GETN_READ_ONLY_COLOR GETN_OPTION_COLOR_READONLY(RGB(20,150,10))
					GETN_NUM(p2, "", 0.0) GETN_ID(GET_USER_DATAID(2)) GETN_READ_ONLY_COLOR GETN_OPTION_COLOR_READONLY(RGB(20,150,10))
					GETN_NUM(p3, "", 0.0) GETN_ID(GET_USER_DATAID(3)) GETN_READ_ONLY_COLOR GETN_OPTION_COLOR_READONLY(RGB(20,150,10))
					GETN_NUM(p4, "", 0.0) GETN_ID(GET_USER_DATAID(4)) GETN_READ_ONLY_COLOR GETN_OPTION_COLOR_READONLY(RGB(20,150,10))
					GETN_NUM(p5, "", 0.0) GETN_ID(GET_USER_DATAID(5)) GETN_READ_ONLY_COLOR GETN_OPTION_COLOR_READONLY(RGB(20,150,10))
					GETN_NUM(p6, "", 0.0) GETN_ID(GET_USER_DATAID(6)) GETN_READ_ONLY_COLOR GETN_OPTION_COLOR_READONLY(RGB(20,150,10))
					GETN_NUM(p7, "", 0.0) GETN_ID(GET_USER_DATAID(7)) GETN_READ_ONLY_COLOR GETN_OPTION_COLOR_READONLY(RGB(20,150,10))
					GETN_NUM(p8, "", 0.0) GETN_ID(GET_USER_DATAID(8)) GETN_READ_ONLY_COLOR GETN_OPTION_COLOR_READONLY(RGB(20,150,10))
					GETN_NUM(p9, "", 0.0) GETN_ID(GET_USER_DATAID(9)) GETN_READ_ONLY_COLOR GETN_OPTION_COLOR_READONLY(RGB(20,150,10))
			}
		}
		
		if(strVarName == "trAnchorXY")
		{
			//string strXs = "Xs";
			TreeNode trXs = tree_check_get_node_by_dataid(tr, STR_GETN_VAR_SHARED_BASE_ANCHORS_XS, PA_BASE_ANCHOR_X_DATAID_IN_GETN_TREE);
			//string strYs = "Ys";
			TreeNode trYs = tree_check_get_node_by_dataid(tr, STR_GETN_VAR_SHARED_BASE_ANCHORS_YS, PA_BASE_ANCHOR_Y_DATAID_IN_GETN_TREE);
		}
		return 0;
		
	}
}
//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 pa_basecreate_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	trGetN.SetAttribute(STR_HELPID_ATTRIB, IDD_PA_RE_CB);
	
	if(nGetNDialog>=0)
	{
		PAWizCore* paCore = (PAWizCore*)get_xf_core_handler(trGetN);
		ASSERT(paCore);	
		
		///Sandy 2008-10-23 add for output "[<input>]<new>" ReportData to source wks page
		paCore->SetOriginalRangeToGetN(trGetN.iy);
	
		//if not pro version, only interpolate support
		/// Iris 8/21/2009 QA80-14165 SHOW_PRO_CONTROL_WITH_DISABLE_AND_PRO_TAG
		/*
		if(!is_pro_version())
		{
			trGetN.connect.nVal = connect_interpolate;
			trGetN.connect.Show = false;
		}
		*/
		if( !is_pro_version() && connect_fitting == trGetN.connect.nVal )
		{
			trGetN.connect.nVal = connect_interpolate;
		}
		///end SHOW_PRO_CONTROL_WITH_DISABLE_AND_PRO_TAG
		
		///---------Sandy 2008-12-30 centralize code to pawizcore
		process_create_baseline_before_execute(trGetN, dwCntrl, paCore);
		/*
		///if goal is create baseline, the xf will the end of wizard, baseline output should come out
		int goal = paCore->GetCurrGoal();
		//string strRTvalue = STR_DEFAULT_TEXT_FOR_REPORT_DATA_NODE;
		//okutil_convert_localized_PDS(&strRTvalue);
		if(goal == PA_GOAL_CREATE_BASELINE)
		{
			//trGetN.rd_oyb.Show = true;//Sandy 2008-11-11 change to XYRange output, keep same format with subtracted data
			trGetN.oyb.Show = true;
			
			//if(!(dwCntrl & LTXF_CHANGE_PARAM) || !(dwCntrl & LTXF_EXEC_RECALCULATE))
			if(!(dwCntrl & LTXF_CHANGE_PARAM) && !(dwCntrl & LTXF_EXEC_RECALCULATE) )
			//	trGetN.rd_oyb.strVal = strRTvalue;//Sandy 2008-11-11 change to XYRange output, keep same format with subtracted data
			{
				trGetN.oyb.SetAttribute(STR_DATA_ATTRIB, STR_NEW);//trGetN.oyb.strVal = strRTvalue;
				int	nn = okutil_getn_update_ranges(&trGetN);
			}
			
			trGetN.btn_subtract.Show = true;//2008-8-14 Sandy add for easwar's suggestion
			
			///subtract preview button format
			TreeNode tr = trGetN.btn_subtract;
			if(tr)
			{
				tr.SetAttribute(STR_ID_ATTRIB, ONODETYPE_PUSHBUTTON_GROUP);
				tr.SetAttribute(STR_COMBO_ATTRIB, PA_BASELINE_STR_BUTTON_SUBTRACT);			
				DWORD dwDisplyBits = DISPLAY_EDITOR_HORZ;
				tr.SetAttribute(STR_ATTRIB_DISPFMT, (string)dwDisplyBits);
				trGetN.btn_subtract.nVal = 0;
			}
		}
		else
		{
			//trGetN.rd_oyb.strVal = STR_OPTIONAL;//Sandy 2008-11-11 change to XYRange output, keep same format with subtracted data
			trGetN.oyb.SetAttribute(STR_DATA_ATTRIB, STR_OPTIONAL);//trGetN.oyb.strVal = STR_OPTIONAL;
			//trGetN.rd_oyb.Show = false;//Sandy 2008-11-11 change to XYRange output, keep same format with subtracted data
			trGetN.oyb.Show = false;
			trGetN.btn_subtract.Show = false;
		}
		*/
		///------ Folger 09/05/09 REDUNDANT_LEGEND_APPEARS_WHEN_CREATE_BASELINE_ON_SCRIPT_MODE
		//if(!create_anchor_plot(paCore,trGetN.trAnchorXY, false))
		//{
			//error_report("fail in get dataplot from anchor range!");
		//}
		///------ End REDUNDANT_LEGEND_APPEARS_WHEN_CREATE_BASELINE_ON_SCRIPT_MODE
		
		if(nGetNDialog>0)
		{
			///------ Folger 09/05/09 REDUNDANT_LEGEND_APPEARS_WHEN_CREATE_BASELINE_ON_SCRIPT_MODE
			if(!create_anchor_plot(paCore,trGetN.trAnchorXY, false))
			{
				error_report("fail in get dataplot from anchor range!");
			}
			///------ End REDUNDANT_LEGEND_APPEARS_WHEN_CREATE_BASELINE_ON_SCRIPT_MODE
			///modify button format
			TreeNode tr = trGetN.btns_modify;
			if(tr)
			{
				tr.SetAttribute(STR_ID_ATTRIB, ONODETYPE_PUSHBUTTON_GROUP);
				tr.SetAttribute(STR_COMBO_ATTRIB, _STR_BUTTON_LIST_IN_MODIFY);			
				DWORD dwDisplyBits = DISPLAY_EDITOR_HORZ;
				tr.SetAttribute(STR_ATTRIB_DISPFMT, (string)dwDisplyBits);
			}
		}
	}
}
//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 pa_basecreate_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
