/*------------------------------------------------------------------------------*
 * File Name: PFM_utils.h	 													*
 * Creation: Leo 2005-11-14														*
 * Purpose: OriginC Source H file												*
 * Copyright (c) OriginLab Corp.	2004, 2005, 2006, 2007, 2008, 2009, 2010	*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	Leo 2005-12-16 MOVED_PEAK_AND_BASLINE_FUNCS_TO_PFM_UTILS					*
 *  Sandy 2005-12-26 MOVE_CURVE_RELATIVE_FUNCTION_TO_CURVE_UTTILS				*
 *	Raine 2006-04-30 GET_GAUSSIAN_FILTER										*
 *	Jasmine 08/30/07 PARAMETERS_IS_USED_CHANGE_UNIQUE_NAME						*
 *	Cloud 11/01/07 FIND_BASELINE_AMONG_DATAPLOTS								*
 *	Arvin 12/05/07 XOP_NEED_SUPPORT_PFW											*
 *	Hong 02/18/08 v8.0806 CHANGE_BTN_BEHAVIOR_BY_EDIT_TEMP_WORKSHEET			*
 *	Sim 02-25-2008 NO_FIT_AGAIN_CHECK_BOX										*
 *	Jasmine 03/31/08 ALLOW_CHANGE_FUNCTION_IN_PARAM_DLG							*
 *	Folger 04/02/08 QA80-11364 IMRPOVE_PA_FIT_BY_STORE_FIT_FUNCTION_TREE_FOR_LOOP
 *	Folger 04/08/08 QA80-11364 IMPROVE_PA_CREATE_GAUSSIAN_PEAK_MECHANISM		*
 *	Folger 04/10/08 QA80-11364 REDUCE_FDF_LOADING_AND_SETTING_TREE_IN_PEAK_CALCULATION
 *	Jasmine 04/17/08 NEED_PASS_SETTING_INFO_AND_FIT_STATUS_IN_ONE_VARIABLE		*
 *	Jasmine 05/16/08 MOMENTS_COMPUTE_METHOD										*
 *	Jasmine 05/20/08 REPORT_GRAPH_SHOULD_BE_BE_ABLE_TO_TURN_OFF					*
 *  Sandy  2008-9-9 REMOVE_OLD_CODE_OF_PAGE_STORAGE_IN_SR3						*
 *	Kyle 10/10/08 CLEAN_PFW_TREE_MOVE_CODE_FROM_PFM_UTILS						*
 *	Folger 10/17/08 NEED_TO_UPDATE_PARAMS_TREE_INTO_PA_FIT_GETNTREE_WHEN_PEAK_FIT_DIALOG_CLOSE
 *	Kyle 11/24/2008 CALCULATE_PEAKS_CHARACTERIZATION_HAS_BEEN_MOVED_TO_FITPEAK	*
 *	Hong 01/13/09 v8.0995d IMPROVE_CODE_OF_MEMORY_CONSUMER_IN_PA				*
 *	Folger 03/06/09 SHOULD_NOT_NEW_SHEET_IF_NO_PEAK_PROPERTIES_OUTPUT			*
 *------------------------------------------------------------------------------*/

//#include "PFM_const.h" /// Hong 04/25/07 v8.0608 MOVE_TO_PFM_UTILS
//#include "pfmwiz.h"

//#include "blpwiz.h"
///move from pfmwiz.h 2007-10-31

//#define SCRIPT_PKFIND_GROBJECT_EVENT "events_from_peaks_finding_control_line_go(0);"


//#define STR_CATEGORY		"PFM"



//#define PEAK_ANCHOR_CONTROL_LINE_NAME "pkaControlLine"
//#define PEAK_CENTER_RED_LINE_NAME "pkLine"

#ifndef	__PFM_UTILS_H__
#define __PFM_UTILS_H__

#define TREE_SET_DVAL(_trNode, _strSubNode, _dVal) {TreeNode& _tempNode = tree_check_get_node(_trNode, _strSubNode); _tempNode.dVal=_dVal;}
#define TREE_SET_NVAL(_trNode, _strSubNode, _nVal) {TreeNode& _tempNode = tree_check_get_node(_trNode, _strSubNode); _tempNode.nVal=_nVal;}
#define TREE_SET_STRVAL(_trNode, _strSubNode, _strVal) {TreeNode& _tempNode = tree_check_get_node(_trNode, _strSubNode); _tempNode.strVal=_strVal;}

#define TREE_GET_DVAL(_trNode, _strSubNode, _dVal) {TreeNode& _tempNode = tree_check_get_node(_trNode, _strSubNode); _dVal = _tempNode.dVal;}
#define TREE_GET_NVAL(_trNode, _strSubNode, _nVal) {TreeNode& _tempNode = tree_check_get_node(_trNode, _strSubNode); _nVal = _tempNode.nVal;}
#define TREE_GET_STRVAL(_trNode, _strSubNode, _strVal) {TreeNode& _tempNode = tree_check_get_node(_trNode, _strSubNode); _strVal = _tempNode.strVal;}




//#define PKEDIT_TEMP_WKS_NAME "PeaksEditData";
//#define PKINIT_TEMP_WKS_NAME "PeaksInitData";
///end of move from pfmwiz.h 2007-10-31



///Jasmine 07/05/07 CENTRALIZE_FIT_PEAK_STORAGE_FUNCTION
#define STR_FP_STORAGE					"FitPeak"
#define STR_PFM_NODE 					"PFM"
#define STR_ADVANCED_NODE 				"AdvancedSetting"
#define STR_PARA_NODE 					"PFMParameters"	///Jasmine 08/30/07 PARAMETERS_IS_USED_CHANGE_UNIQUE_NAME
#define STR_STATE_NODE 					"FitState"
//#define STR_FIT_POINTER		 			"FitPointer" /// Iris 11/11/2008 v8.0968 MOVE_PA_ENUM_TO_NEW_HEADER_PA_UTILS
//#define STR_FIT_HELPER		 			"FitHelper"	//Jasmine 11/18/08 GET_FITHELPER_FROM_CORE_NOT_FROM_PAPG_STORAGE_ANY_MORE
#define PFM_PEAKS_TREE_TAG_NAME 		"Peaks"
#define PFM_PEAK_TREE_TAG_NAME 			"Peak"
#define PFM_BASELINE_PEAK_TAG_NAME 		"Peak0"
#define PFW_TREE_TAG_NAME 				"PFWTree" 

#define BRANCH_PARAMS_IN_PFM_TREE "Parameters"
//#define BRANCH_SETTINGS_IN_PFM_TREE "Settings"
//#define TAG_SHARE_IN_PFM_TREE "Sharing"
//#define TAG_FIX_IN_PFM_TREE "Fixed"

#define BRANCH_FUNCTION_IN_PFM_TREE "Function"
#define TAG_FULLPATH_IN_PFM_TREE "FullPath"
#define TAG_FILE_IN_PFM_TREE "File"
#define TAG_FUNCNAME_IN_PFM_TREE "FuncName"

#ifndef _PA_FUNC_CATE_INFO
#define _PA_FUNC_CATE_INFO
#define STR_PA_NLSF_CAT_BASELINE	"Baseline"
#define STR_PA_NLSF_CAT_PEAK		"PFW"
#define STR_GAUSSIAN_FUNC			"Gaussian"
#define STR_PA_DEFAULT_FUNC			STR_GAUSSIAN_FUNC
#define STR_PA_DEFAULT_FDF			STR_GAUSSIAN_FUNC
#define IS_DEFAULT_PA_FUNC(_STR)	(lstrcmpi(_STR, STR_PA_DEFAULT_FUNC)==0)
#endif //_PA_FUNC_CATE_INFO

#define STR_NLSF_CAT_BASELINE		STR_PA_NLSF_CAT_BASELINE
#define STR_NLSF_CAT_PFM			STR_PA_NLSF_CAT_PEAK


//#define XF_DESC_IN_PFW_GOAL_FIT	    	_L("Goal: Fit Peaks")
//#define XF_DESC_IN_PFW_GOAL_FIT_BP	    	_L("Goal: Fit Peaks with Baseline")
//#define XF_DESC_IN_PFW_GOAL_INT 		_L("Goal: Integrate Peaks")
//#define XF_DESC_IN_PFW_GOAL_BASE 		_L("Goal: Baseline")
//
////#define XF_DESC_IN_PFW_B_BSPLINE    	_L("Compute Baseline: Interpolate with Cubic B-Spline")
//#define XF_DESC_IN_PFW_B_INTERP			_L("Compute Baseline: Interpolate Baseline")
//#define XF_DESC_IN_PFW_B_CHEBYSHEV 		_L("Compute Baseline: Chebyshev")
//#define XF_DESC_IN_PFW_B_SHIRLEY		_L("Compute Baseline: Shirley")
//#define XF_DESC_IN_PFW_B_TOUGAARD		_L("Compute Baseline: Tougaard")
//#define XF_DESC_IN_PFW_B_PTS_FROM_GRAPH	_L("Compute Baseline: Select Points from Graph")
//
//
//
//#define XF_DESC_IN_PFW_B_FIT			_L("Fit Baseline")
//
//#define XF_DESC_IN_PFW_B_FIT_W_DATA		_L("Baseline: Fit with Data")
//
//#define XF_DESC_IN_PFW_P_FIND			_L("Find Peaks: Use Derivatives")
//#define XF_DESC_IN_PFW_P_MAX			_L("Find Peaks: Local Maximum")
//#define XF_DESC_IN_PFW_P_RECT			_L("Find Peaks: Window Search")
//
//#define XF_DESC_IN_PFW_P_EDIT			_L("Peak Edit")
//#define XF_DESC_IN_PFW_P_INIT			_L("Peak Init")
//
//#define XF_DESC_IN_PFW_P_FIT			_L("Fit Peaks")


/// Iris 11/11/2008 v8.0968 MOVE_PA_ENUM_TO_NEW_HEADER_PA_UTILS
/*
///Jasmine 05/20/08 REPORT_GRAPH_SHOULD_BE_BE_ABLE_TO_TURN_OFF
//enum{	PLOT_TO_SOURCE_GRAPH,	PLOT_TO_NEW_GRAPH};///Jasmine 02/01/08 PLOT_TO_SOURCE_GRAPH 
enum{	
	PLOT_TO_NONE 		= 0,		
	PLOT_TO_NEW_GRAPH,
	PLOT_TO_SOURCE_GRAPH,
};

#define	REPORT_GRAPH_DESTINATION_LIST 		_L("<None>|<New Graph>|<Source Graph>")
///End REPORT_GRAPH_SHOULD_BE_BE_ABLE_TO_TURN_OFF

enum{
	PLOT_PEAK_CURVE, 
	PLOT_CUM_CURVE, 
	PLOT_ALL_CURVE
};

//use in pkfitDlg
enum{
	EXTERNAL_MSG_PARA_CHANGE, 
	EXTERNAL_MSG_ADV_CHANGE,
	EXTERNAL_MSG_AFT_ITR, ///---Sim 02-25-2008 NO_FIT_AGAIN_CHECK_BOX
	EXTERNAL_MSG_FUNC_CHANGE,	///Jasmine 03/31/08 ALLOW_CHANGE_FUNCTION_IN_PARAM_DLG
	EXTERNAL_MSG_CHECK_AUTOINIT,
	EXTERNAL_MSG_DIALOG_CLOSE,	//------ Folger 10/17/08 NEED_TO_UPDATE_PARAMS_TREE_INTO_PA_FIT_GETNTREE_WHEN_PEAK_FIT_DIALOG_CLOSE
};
*/
///end MOVE_PA_ENUM_TO_NEW_HEADER_PA_UTILS

///Jasmine 04/17/08 NEED_PASS_SETTING_INFO_AND_FIT_STATUS_IN_ONE_VARIABLE
int 	pfm_combine_exmsg_parachange_setting(bool bEnbale = true, int nSetting = -1);
bool 	pfm_parse_exmsg_parachange_setting(int& nSetting);
///End NEED_PASS_SETTING_INFO_AND_FIT_STATUS_IN_ONE_VARIABLE

/**$
*/
//TreeNode 	get_fit_peak_binary_storage_tree(Page& gp, LPCSTR lpcszNodeName);
///**$
//*/
//bool 		update_fit_peak_binary_storage_tree(Page& gp, TreeNode& trNode, LPCSTR lpcszNodeName);
///**$
//*/
//bool 		clean_fit_peak_binary_storage_tree(Page& gp);
///End CENTRALIZE_FIT_PEAK_STORAGE_FUNCTION

///End CENTRALIZE_FIT_PEAK_STORAGE_FUNCTION

///Leo 2005-12-16 MOVED_PEAK_AND_BASLINE_FUNCS_TO_PFM_UTILS
///Forest 7/29/04 QA70-6067 BASELINE_SECOND_DERIVATIVE_METHOD 
//Commetnts last updated by Frank on 1/06/05
/**	>Analysis>Spectral Analysis
		Algorithm for finding baseline points in a dataset

		Examine second derivative of the data and accept values that are close to zero as baseline points.
		
		The following is a step by step process of the algorithm described above:
		1. Perform adjacent averaging smooth on the input data, or perform no smoothing
		2. Take the second derivative of the data
		3. For all points in the second derivative with absolute value above a user-specified Percentile value, 
		    change the corresponding points in original dataset to missing value
		4. For all points that still remain in the original dataset, remove those that do not have an immediate neighbor on either side
		5. Record all points that remain in the dataset, that are not missing values. These are now the baseline points for the dataset
	Parameters:
		vxData =[input] the input x data to find baseline points
		vyData =[input] the input y data to find baseline points
		vxBaseline =[output] the x data value of the baseline points
		vyBaseline =[output] the y data value of the baseline points
		dPercentile =[input] input value that will a percentile from 0 to 100 of the absolute value of the second derivative of the data.
		nSmoothPts =[input] number of points to perform the averaging smooth, 0 = no smoothing
	Example1:
		//For this sample to run, Origin workspace should have worksheet and have 4 columns A, B, C, D.  The dataset to operate on
		//should be in columns A and B.  The values for the baseline points will be loaded into
		//column C and D  
		//For example, import "Positive & Negative Peaks.DAT" from the /Samples/Data folder
		//and copy the data in worksheet and make it active.  Add column C and D for the baseline points values.
		void find_baseline_2nd_derivative_ex1(double dPercentile)
		{
			// call lloc to find baseline points
			Worksheet	wks = Project.ActiveLayer();
			Dataset dsDataX(wks,0);
			Dataset dsDataY(wks,1);
			Dataset dsBslnX(wks,2);
			Dataset dsBslnY(wks,3);
			
			int iRet = find_baseline_2nd_derivative(dsDataX, dsDataY, dsBslnX, dsBslnY, dPercentile);
			printf("%d baseline points were found.\n", iRet);
		}
	Return:
		the number of baseline points found if success, otherwise returns error code
		-1  Problem adjacent averaging smooth
		-2  Problem taking derivative of data
*/
//int find_baseline_2nd_derivative(vector& vxData, vector& vyData, vector& vxBaseline, vector& vyBaseline, double dPercentile, int nSmoothPts = 3);
/////End BASELINE_SECOND_DERIVATIVE_METHOD 

/**
	Remarks:
		NOTE: IT IS ASSUMED THAT THE DATA IN VXDATA IS SORTED.
		IF NOT, HLOC SHOULD SORT BEFORE CALLING THIS LLOC.
		
		Smooth the data curve using nSmoothPts-pt adjacent averaging
		nSmoothPts = 0 for no smoothing
		
		Look for all points of the 1st deriv and look for zero crossings.  If for a zero
		crossing in the deriv, the absolute value of the original data is above theshold,
		then that corresponds to a peak. Also save the peak points.
	Keywords:
	Example1:
		// See the example for find_peaks_1st_derivative.
	Parameters:
		vxData = [input]
		vyData = [input]
		vxPeaks = [output]
		vyPeaks = [output]
		vnIndices = [output]
		nDir = [input]
		numPeaks = [input]
		nPtsSmooth = [input]
	Return:
	SeeAlso: find_peaks_1st_derivative
 */ 
 //end 2005-12-26 MOVE_CURVE_RELATIVE_FUNCTION_TO_CURVE_UTTILS
bool find_peaks_2nd_derivative(vector& vxData, vector& vyData, vector& vxPeaks, vector& vyPeaks, vector<int>& vnIndices, int nDir, int nPtsSmooth = 11);

///**
	//Remarks:
	//Keywords:
	//Example1:
		//void find_peaks_partition_ex1
		//{
		//
		//}
	//Parameters:
		//vxData = [input]
		//vyData = [input]
		//vxPeaks = [output]
		//vyPeaks = [output]
		//numPeaks = [input]
		//nPtsSmooth = [input]
	//Return:
	//SeeAlso:
 //*/ 
////bool find_peaks_partition(vector& vxData, vector& vyData, vector& vxSub, vector& vySub, double dxPeak, int nDir = POSITIVE_DIRECTION, int nPtsSmooth = 11);


/**
	Remarks:
	Keywords:
	Example1:
		void find_peak_deconvolute_ex1
		{
		
		}
	Parameters:
	Return:
	SeeAlso:
 */ 
//bool find_peaks_by_deconvolute(const vector& vx,const vector& vy, vector& vxPeaks, vector& vyPeaks, vector<int>& vnIndices, int nDir, int num, int nPtsSmooth);

/**
	Remarks:
	Keywords:
	Example1:
		void peak_fit_with_fixed_xc_ex1
		{
		
		}
	Parameters:
	Return:
	SeeAlso:
 */ 
bool peak_fit_with_fixed_xc(string strFuncName, vector& vX, vector& vY, double xc, vector& vParams, double dCOD = 0.50);

/*

//bool create_Gauss_peak_by_nlsf_evluate(const vector& vx, const vector& vy, double xc, double yc, int nDir, int nPtsSmooth, vector& vGaussPeak, vector& vParams);
bool create_Gauss_peak_by_nlsf_evluate(const vector& vx, const vector& vy, double xc, double yc, int nDir, int nPtsSmooth, 
		vector& vGaussPeak, vector& vParams, int* nPeakStart = NULL, int* nPeakEnd = NULL);
*/
/**
	Remarks:
	Keywords:
	Example1:
		void create_Gauss_peak_by_nlsf_evluate_ex1
		{
		
		}
	Parameters:
	Return:
	SeeAlso:
 */ 		
///Sandy add 2007-6-21 for improve same thing in create_Gauss_peak_by_nlsf_evluate
///Sandy add 2007-6-21 for improve same thing in create_Gauss_peak_by_nlsf_evluate
///Sandy add 2007-6-21 for improve same thing in create_Gauss_peak_by_nlsf_evluate

//------ Folger 04/08/08 QA80-11364 IMPROVE_PA_CREATE_GAUSSIAN_PEAK_MECHANISM
/*
bool create_Gaussian_peak_by_nlsf_evluate(const vector& vx, const vector& vy, double dWholeWidth,
				double xc, double yc, int nDir, int nPtsSmooth, vector& vGaussianPeak, vector& vParams
				//------ Folger 04/02/08 QA80-11364 IMRPOVE_PA_FIT_BY_STORE_FIT_FUNCTION_TREE_FOR_LOOP
				, TreeNode &trGaussianFF = NULL);
				//------
*/

bool create_Gaussian_peak_by_nlsf_evluate(const vector& vx, double dWholeWidth, double xc, double yc, vector& vParams, vector& vGaussianPeak = NULL, TreeNode &trGaussianFF = NULL);

void	pfm_init_Gaussian_parameters(vector& vParams, double xc, double yc, double dWholeWidth);
//------

/**
	Remarks:
	Keywords:
	Example1:
		void find_peaks_by_residuals_ex1
		{
		
		}
	Parameters:
	Return:
	SeeAlso:
 */ 
 
///Sandy 2007-6-21 there should be no number constrain in finding peaks
//bool find_peaks_by_residuals(const vector& vx,const vector& vy, vector& vxPeaks, vector& vyPeaks, vector<int>& vnIndices, int nDir, int& num, int nPtsSmooth);
//bool find_peaks_by_residuals(const vector& vX,const vector& vY, vector& vxPeaks, vector& vyPeaks, vector<int>& vnIndices, int nDir, int nPtsSmooth);
//---Sandy 2008-11-18 APPLY_NEW_OCMATH_FUNCTION_PROTOTYPE_WITH_SG_DERIV
//int find_peaks_by_residuals(const vector& vX,const vector& vY, vector& vxPeaks, vector& vyPeaks, vector<int>& vnIndices, int nDir, int nPtsSmooth);
int find_peaks_by_residuals(const vector& vX,const vector& vY, vector& vxPeaks, vector& vyPeaks, vector<int>& vnIndices, int nDir, bool bUseSG = false, int nPtsSmooth = 11, int nPloyDeg = 2);

//----- CPY 12/8/2007 QA80-10788 CURVE_UTILS_SHOULD_NOT_NEED_PRO_DLLS
int find_peaks_2nd_derivative_ex(UINT* lSize, const vector& vx,const vector& vy, vector& vxPeaks, vector& vyPeaks, vector<int>& vnIndices, DWORD dwCtrl, int nPtsSmooth);
//-----

/*
///Raine 2006-04-30 GET_GAUSSIAN_FILTER
bool get_gaussian_filter(vector& vxData, vector& vyData, vector& vGaussian);
///END GET_GAUSSIAN_FILTER
*/

//#define STR_DEFAULT_PEAK	"Gaussian"


/*///Sandy remove pfmLineControlList
class pfmLineControl
{
public:
	pfmLineControl()
	{
		m_nPlotIndex = -1;
	}
	
	pfmLineControl(const GraphObject& goOriginal);
	
	pfmLineControl(const GraphLayer& gl, LPCSTR lpcszName);
	
	~pfmLineControl(){}
	
public:
	///Sandy 2007-11-29 for support no subtract baseline and can update control position by dp
	///Sandy 2007-4-26 remove trSetting since the infomation can be create from dataplot
	//bool Create(const GraphLayer& gl, LPCSTR lpcszNameBase, const DataPlot& dp, const TreeNode& trSetting, LPCSTR lpcszLabel  = NULL);
	//bool Create(const GraphLayer& gl, LPCSTR lpcszNameBase, const DataPlot& dp, LPCSTR lpcszLabel = NULL);
	bool Create(const GraphLayer& gl, LPCSTR lpcszNameBase, const DataPlot& dp, LPCSTR lpcszLabel = NULL, const DataPlot& dpBase = NULL);
		
	int GetTargetPlotIndex()
	{
		return m_nPlotIndex;
	}
	
	int GetLabelNum()
	{
		string strLabel = m_goLabel.Text;
		int nLabelNum = atoi(strLabel);
		return nLabelNum;
	}
	bool IsValid()
	{
		return -1 == m_nPlotIndex ? false : true;
	}
	
	bool UpdateObjectName(LPCSTR lpcszName, LPCSTR lpcszLabel = NULL);
	
	///Sandy add
	double GetLinePos()
	{
		return m_goLine.X;
	}
	
	void UpdateHalfLine(int nActiveHalf);
	
	bool Update(bool bFromControls = true, double xc = 0, double w = 0, double h = 0, string func = STR_DEFAULT_PEAK);
	
	bool ShowEditControls(bool bShow = false);
	
	void ShowControls(bool bShow = true)
	{
		m_goLine.Show(bShow);
		m_goLabel.Show(bShow);
		m_goHorizonLine.Show(bShow);
		m_goHalfLeftLine.Show(bShow);
		m_goHalfRightLine.Show(bShow);
		
	}
	
	double GetPeakCenter()
	{
		return m_goLine.X;
	}
	
	double GetPeakHalfWidth()
	{
		return (m_goHalfLeftLine.DX + m_goHalfRightLine.DX);
	}
	
	double GetPeakHeight()
	{
		return ((m_goHorizonLine.Y-m_goHalfLeftLine.Y)*2.0);
	}
	
	bool UpdateParams(const vector& vParams);
	
private:
	bool Init(const GraphObject & goOriginal);
	bool getDataPlotControlsPos(DataPlot& dp, double& dX, double& dY, double& dHalfWidth, const DataPlot& dpBase = NULL);
	bool updateControlsPos(double dX, double dY, double dHalfWidth);
	
	
private:
	int		m_nPlotIndex;
	GraphObject		m_goLine;
	GraphObject		m_goLabel;
	GraphObject		m_goHorizonLine;
	
	///Sandy 2007-7-9 change one half line to two for better controling.
	//GraphObject		m_goHalfLine;	
	GraphObject		m_goHalfLeftLine;
	GraphObject		m_goHalfRightLine;
	
	///Sandy 2007-6-11 can not record the height and width by member variables
	///// Cloud 4/27/2007 add
	//double	m_dHeight;
	//double	m_dWidth;
};


// this class manage a list of pfmLineControl and it's attached DataPlot and Worksheet data
class pfmLineControlList
{
public:
	pfmLineControlList()
	{
		Reset();
	}
	
	pfmLineControlList(const GraphLayer& gl, LPCSTR lpcszNameBase);
		
	~pfmLineControlList(){}
	
public:
	
	///Sandy 2007-4-26 remove trSetting
	//int CreateList(const GraphLayer& gl, LPCSTR lpcszNameBase, const TreeNode& trSetting, int nNum = -1, int nOffset = 0);
	//int CreateList(const GraphLayer& gl, LPCSTR lpcszNameBase, const TreeNode& trSetting, const vector<int> vnPlotIndex);
	int CreateList(const GraphLayer& gl, LPCSTR lpcszNameBase, int nNum = -1, int nOffset = 0);

	/// Cloud 04/27/2007 ADD_CUMULATE_INDEX
	int CreateList(const GraphLayer& gl, LPCSTR lpcszNameBase, const vector<int> vnPlotIndex);
	//int CreateList(const GraphLayer& gl, LPCSTR lpcszNameBase, const vector<int> vnPlotIndex, const int nCumIndex);
	
	pfmLineControl GetAt(int nIndex);
	
	pfmLineControl GetByPlotIndex(int nPlotIndex);
	
	int RemoveAt(int nIndex); // this will delete the List Control in target GraphLyaer
	
	int RemoveByPlotIndex(int nPlotIndex); 
	
	int RemoveAll();
	
	///Sandy 2007-4-26 remove trSetting
	//int Add(const DataPlot& dp, const TreeNode& trSetting, bool bReplace = false);
	int Add(const DataPlot& dp, bool bReplace = false);

	bool UpdateEditControls(int nPlotIndex = -1); // default to hide all
	
	int GetCount()
	{
		return m_nCount;
	}
	
	bool IsValid()
	{
		if ( !m_glTarget || m_strNameBase.IsEmpty() || 0 == m_nCount )
			return false;
			
		return true;
	}
	///Sandy add 2007-6-28
	bool ShowAll(bool bShow = true);
	
	bool DisableControl();
	

	int GetTargetPlotsIndex(vector<int>& vnPlotIndex)///Add by Sandy 2007-11-8
	{
		vnPlotIndex = m_vnPlotIndex;
		return m_vnPlotIndex.GetSize();
	}
	
	bool GetPeaksInfoList(vector<int>& vnPlotIndex,
						vector<int>& vnLabel,
						vector& vxc,
						vector& vw,
						vector& vh,
						vector<string>& vstrFunc);

private:
	int updateObjectsAfterRemoveAt(int nIndexOffset);

	int initList();
	
	void Reset()
	{
		m_nCount = 0;
		m_vnPlotIndex.SetSize(0);
		m_strNameBase = "";
	}
	
private:
	string	m_strNameBase;
	int 	m_nCount;
	vector<int>	m_vnPlotIndex; 
	GraphLayer	m_glTarget;	
	

};


///Sandy 2007-4-29 pfmLineControlList event has been moved to cpp
//void events_from_pka_control_line_go(int nID, int nEvent);
*/ //-end of remove pfmLineControl

//bool get_func_info_from_dp(DataPlot dp, string& strFuncName, string& strFuncFDFName, string strCategory = STR_NLSF_CAT_PFM, bool bSetDefaultPeakFunc = true);
//
/////Sandy 2007-11-14 rename
////void set_params_info_to_dp(DataPlot dp, string strFuncName, vector<string>& vstrParam, vector& vParams);
//void set_params_info_to_dp(DataPlot dp,vector<string>& vstrParam, vector& vParams);
//
//void set_func_info_to_dp(DataPlot dp, string strFuncName, string strFileName,  string strCategory = STR_NLSF_CAT_PFM);
//
//void construct_pfw_tree_peak_func_node(TreeNode& tr, string strFullPath, string strFileName, string strFuncName);
//void construct_pfw_tree_peak_params_node(TreeNode& tr, vector<string>& vstrParam, vector& vParams);

///////////////////////////////////////////////////////////////////////
////Sandy 2007-7-4 Peaks' Characterize functions///////////////////////
///////////////////////////////////////////////////////////////////////


  typedef struct tagPFMPeakCharsRequire
  {
    bool _id(IDE_PFM_PKC_PEAKTYPE) bPeakType;		///------ Folger 03/06/09 SHOULD_NOT_NEW_SHEET_IF_NO_PEAK_PROPERTIES_OUTPUT
    bool _id(IDE_PFM_PKC_AREAFIT) bAreaFit; 
    bool _id(IDE_PFM_PKC_AREAFIT_TRUNCATED) bAreaFitT;
    bool _id(IDE_PFM_PKC_AREAFIT_PERCENTAGE) bAreaFitTP;
    bool _id(IDE_PFM_PKC_AREA_INTEGRATE) bAreaIntg;
    bool _id(IDE_PFM_PKC_AREA_INTEGRATE_P) bAreaIntgP;
    bool _id(IDE_PFM_PKC_CENTERMAX) bCenterMax;
    bool _id(IDE_PFM_PKC_CENTERGRAVITY) bCenterGrvty;
    bool _id(IDE_PFM_PKC_MAXHEIGHT) bMaxHeight;
    bool _id(IDE_PFM_PKC_FWHM) bFWHM;
    bool _id(IDE_PFM_PKC_RESOLUTION) bResolution;
    bool _id(IDE_PFM_PKC_WIDTHAT) bWidthAtP;
    bool _id(IDE_PFM_PKC_AREAABOVE) bAreaAbove;
    bool _id(IDE_PFM_PKC_CUMAREA) bCumArea;    
    bool _id(IDE_PFM_PKC_VARIANCE) bVariance;
    bool _id(IDE_PFM_PKC_SKEW) bSkew;
    bool _id(IDE_PFM_PKC_EXCESS) bExcess;
    bool _id(IDE_PFM_PKC_MOMENT3) bMoment3;
    bool _id(IDE_PFM_PKC_MOMENT4) bMoment4;
  } PFMPeakCharsRequire;
  

  typedef struct tagPFMPeakCharsVaule  
  {
    double _id(IDE_PFM_PKC_AREAFIT) dAreaFit;
    double _id(IDE_PFM_PKC_AREAFIT_TRUNCATED) dAreaFitT;
    double _id(IDE_PFM_PKC_AREAFIT_PERCENTAGE) dAreaFitTP;
    double _id(IDE_PFM_PKC_AREA_INTEGRATE) dAreaIntg;
    double _id(IDE_PFM_PKC_AREA_INTEGRATE_P) dAreaIntgP;
    double _id(IDE_PFM_PKC_CENTERMAX) dCenterMax;
    double _id(IDE_PFM_PKC_CENTERGRAVITY) dCenterGrvty;
    double _id(IDE_PFM_PKC_MAXHEIGHT) dMaxHeight;
    double _id(IDE_PFM_PKC_FWHM) dFWHM;
    double _id(IDE_PFM_PKC_RESOLUTION) dResolution;
    double _id(IDE_PFM_PKC_WIDTHAT) dWidthAtP;
    double _id(IDE_PFM_PKC_WIDTHAT_PERCENT) dWidthAtPP;//add for output to result
    
    double _id(IDE_PFM_PKC_AREAABOVE) dAreaAbove;
    double _id(IDE_PFM_PKC_AREAABOVE_PERCENT) dAreaAboveP;//add for output to result
     
    double _id(IDE_PFM_PKC_CUMAREA) dCumArea;
    double _id(IDE_PFM_PKC_CUMAREA_PERCENT) dCumAreaP;//add for output to result
    
    double _id(IDE_PFM_PKC_VARIANCE) dVariance;
    double _id(IDE_PFM_PKC_SKEW) dSkew;
    double _id(IDE_PFM_PKC_EXCESS) dExcess;
    double _id(IDE_PFM_PKC_MOMENT3) dMoment3;
    double _id(IDE_PFM_PKC_MOMENT4) dMoment4;
  } PFMPeakCharsVaule;
  
///Jasmine 05/16/08 MOMENTS_COMPUTE_METHOD
enum{
	MOMENT_METHOD_NUM_INTEGRAL 		= 0,
	MOMENT_METHOD_FUNC_INTEGRAL,
};
///Kyle 11/24/2008 CALCULATE_PEAKS_CHARACTERIZATION_HAS_BEEN_MOVED_TO_FITPEAK
//int calculate_peaks_characterization( vector& vx, matrix& mPeaksData, vector& vXCenter, vector& vXWidth, vector& vyCum,  
		 //TreeNode trFitPeaks, 
         //const PFMPeakCharsRequire xRequireList, PFMPeakCharsVaule* pxPFMPeakCharsValueList,
         //double dWidthAtPercent = 10, double dAreaAbovePercent = 10, double dCumAreaTo = 0,
         //int nMomentmethod = MOMENT_METHOD_NUM_INTEGRAL);	
///End CALCULATE_PEAKS_CHARACTERIZATION_HAS_BEEN_MOVED_TO_FITPEAK
///End MOMENTS_COMPUTE_METHOD
         
////Sandy 2008-5-15 move generate infinite peak data outside, so need to clearup the pototype
//bool cal_peak_characterization(vector& vx, vector& vy, double dPeakXC, double dPeakWidth,  const IntegrationResult xCumIntg,  
		 ///*string strFullPathFileName,  */string strFuncName,  vector& vFitParams, 
		 //const PFMPeakCharsRequire xRequireList, PFMPeakCharsVaule& xPFMPeakCharsValueList,
         //double dWidthAtPercent, double dAreaAbovePercent, double dCumAreaTo 
         ////------ Folger 04/10/08 QA80-11364 REDUCE_FDF_LOADING_AND_SETTING_TREE_IN_PEAK_CALCULATION
         //, TreeNode &trFF, NumericFunction &NF);
         ////------
///Kyle 10/10/08 CLEAN_PFW_TREE_MOVE_CODE_FROM_PFM_UTILS
//bool cal_peak_characterization(vector& vx, vector& vy , vector& vFullPeakX, vector& vFullPeakY, double dPeakXC, double dPeakWidth, 
		//double dCumArea, double dFullCumArea,	string strFuncName,  vector& vFitParams,vector& vZeroY0Params, TreeNode trIdealPeak,
		//const PFMPeakCharsRequire xRequireList, PFMPeakCharsVaule& xPFMPeakCharsValueList,
        //double dWidthAtPercent, double dAreaAbovePercent, double dCumAreaTo , double& dLastXC, double& dLastWidth, NumericFunction &NF);
        //
bool cal_peak_characterization(vector& vx, vector& vy , vector& vFullPeakX, vector& vFullPeakY, double dPeakXC, double dPeakWidth, double dAreaFitT,
		double dCumArea, double dAreaFitTCumArea, string strFuncName,  vector& vFitParams, vector& vZeroY0Params, TreeNode trIdealPeak,
		const PFMPeakCharsRequire xRequireList, PFMPeakCharsVaule& xPFMPeakCharsValueList,
        double dWidthAtPercent, double dAreaAbovePercent, double dCumAreaTo , double& dLastXC, double& dLastWidth,NumericFunction &NF, int nMomentdMode);

int generate_peak_data(const NumericFunction& NF, const vector& vParams, vector& vDestX, vector& vDestY, double dFrom, double dTo, double dxPeakCenter, double dPeakWidth);		//Kyle 10/10/08 to be used in FitPeak.cpp
///End CLEAN_PFW_TREE_MOVE_CODE_FROM_PFM_UTILS

/// Hong 01/13/09 v8.0995d IMPROVE_CODE_OF_MEMORY_CONSUMER_IN_PA
double cal_area_fit_TP(double dAreaFitT, double dAreaFitTCumArea);
/// end IMPROVE_CODE_OF_MEMORY_CONSUMER_IN_PA
         
/////////////////////////////////////////////////////////////////////////////////////////////////
////////////////Move From PFMWiz.h//////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
//void events_from_peaks_finding_control_line_go(int nID);

//bool create_baseline_events_handler(TreeNode& trGetN, int nEventID, LPCSTR lpcszNodeName, bool& bOKEnable, string& strAux, string& strErrMsg);


//bool find_peaks_events_handler(TreeNode& trGetN, int nEventID, LPCSTR lpcszNodeName, bool bOKEnable, string& strAux, string& strErrMsg);


//bool pfm_save_peaks_to_tree(GraphLayer gl, XYRange& xyPeaks);

///Sandy 2007-12-3 add
//bool check_peaks_plot(GraphLayer gl, DataPlot& dpPeaksPlot);

///Sandy 2007-4-23 add
//bool pfm_update_peaks_center(TreeNode& trGetN, GraphLayer& gl);
//bool pfw8_get_peaks_center_from_ctrls(GraphLayer& gl, const vector& vx, const vector& vy, vector& vxNewPeaks, vector& vyNewPeaks);
///end







//bool is_existed_baseline_in_gp_storage(GraphLayer gl,bool bClean = false);
//bool set_existed_baseline_to_gp_storage(GraphLayer gl,bool bBaselineExisted);

//Sandy 2007-11-16 add
//bool auto_find_baseline_points(vector& vx, vector& vy, int npts);

//Sandy 2007-11-20 add
//void clean_find_peaks_temp_wks();
//void clean_edit_peaks_temp_wks();

///Sandy 2007-11-21 add
//Worksheet check_get_pfw_temp_wp(string strWpName, bool bCleanUp = true);
//
//void destroy_pfw_temp_wps(string strWksList);
//void back_up_page(const GraphPage& gp);
//void clean_up_pfw_trace(Page& pg, bool bRecover = true, bool bShowOriginalData = true, bool bKeepBaseline = false, bool bCleanTree = true);

///Arvin 12/05/07 XOP_NEED_SUPPORT_PFW
//If user haven't add pfw functions to user or system folder,
//when he do multiply peak fit from xop, we need add these functions to folder 
//bool add_pfw_functions_to_folder(bool bUserFolder = true);
///END XOP_NEED_SUPPORT_PFW


     									 
     									 
//TreeNode pfw8_construst_default_baseline_branch_in_pfw_tree(TreeNode trPeaks);   

//int pfw8_add_peaks_data_to_temp_wks(Worksheet& wks, vector& vx, vector& vy,  bool bIsPeakData = true);//, Page& pgStorage = NULL); 	


//bool check_peaks_cum_range(Page& pg, XYRange& yc);	


//bool pfw8_save_curve_fitting_info_to_col(Column& colY, vector<string>& vsParams, vector& vParams, string strFuncName, string strFileName, string strCategory = STR_NLSF_CAT_PFM);	

//bool pfw8_save_curve_fitting_info_to_dateplot(DataPlot& dp, vector<string>& vsParams, vector& vParams, string strFuncName, string strFileName, string strCategory  = STR_NLSF_CAT_PFM);

//bool pfw8_update_peak_data_by_Gaussian(Page& pgStorage, XYRange& xyPeak,  double dX, double dHalfWidth, double dY,  vector& voGuassian = NULL, vector& voGuassianParams = NULL);						 


//void pfw8_update_2ndDeriative_preivew_of_findpeak_page(TreeNode trGetN, GraphLayer& gl, int nEventID, string strNode, const vector& vx, const vector& vy,bool bUpdate);

/// Hong 02/18/08 v8.0806 CHANGE_BTN_BEHAVIOR_BY_EDIT_TEMP_WORKSHEET
//bool pfw8_line_controls_handler_of_findpeak_page(GraphLayer& gl, TreeNode& trGetN, int nEventID, string strNode, string& strErrMsg);
//bool pfw8_line_controls_handler_of_findpeak_page(GraphLayer& gl, TreeNode& trGetN, int nEventID, string strNode, string& strErrMsg, const XYRange* pyp = NULL);
/// end CHANGE_BTN_BEHAVIOR_BY_EDIT_TEMP_WORKSHEET

//bool pfw8_clean_apply_result_of_findpeak_page(Page& pg, TreeNode& trGetN);

//bool pfw8_line_controls_to_yp_of_findpeak_page(Page& pg, const vector& vxi,const vector& vyi, XYRange& yp);

//bool xf_construct_func_combo_string(TreeNode& trCombo, vector<string>& vsOps);



//#define STR_FIX_ATTRIBUTE	"Fixed"  CPY 4/14/08 moved to nlfitsession.h
//bool pfw8_is_baseline_fixed(const Page& pg, bool& bFixed);

/// Iris 11/11/2008 v8.0968 MOVE_PA_ENUM_TO_NEW_HEADER_PA_UTILS
/*
enum{
	PARAM_DLG_NEW_GRID		=	0x0001,			//reconstruct the grid control
	PARAM_DLG_ENABLE_FIT	=	0x0002,
	PARAM_DLG_DISABLE_FIT	=	0x0004,
	PARAM_DLG_MULTI_FUNC	=	0x0008,		
	PARAM_DLG_ADVANCE		=	0x0010,
	PARAM_DLG_UPDATE_GRID   = 	0x0020, /// Iris 9/16/2008 PA_PARAM_DLG_USE_NEW_FIT_CLASS
};
*/

/// Iris 9/05/2008 PA_PARAM_DLG_USE_NEW_FIT_CLASS
//bool open_params_dlg(int nOption, DWORD dwCntrl = 0);
///end PA_PARAM_DLG_USE_NEW_FIT_CLASS

bool  pfw8_get_executed_output_xyrange(TreeNode trGetN, string strTag, XYRange& xy);

///---Sim 03-11-2008 STORE_PEAK_INFO_SETTING_TO_FILE
struct PEAKINFO{
	vector<string> vsFunc;
	vector vxc;
	vector vh;
	int nNumPeaks;
};
bool store_peak_info_ini_file(LPCSTR lpcszINIFile, bool bSave, PEAKINFO& pkinfo);
///---END STORE_PEAK_INFO_SETTING_TO_FILE

///Jasmine 05/16/08 MOMENTS_COMPUTE_METHOD
bool pa_fit_enable_disable_MomentMethod_node(TreeNode& tr, int nRow = -1, int nCol = -1, TreeNode& trNode = NULL, DWORD dwCntrl = 0, int nType = -1, WndContainer& theDlg = NULL);
///End MOMENTS_COMPUTE_METHOD

/// Iris 11/11/2008 v8.0968 MOVE_PA_ENUM_TO_NEW_HEADER_PA_UTILS, moved to nlsf_utils
//string get_function_list(LPCSTR lpcszCategory);
///end MOVE_PA_ENUM_TO_NEW_HEADER_PA_UTILS

#endif		//__PFM_UTILS_H__
