/*------------------------------------------------------------------------------*
 * File Name:PeakFitPreviewCtrl.h												*
 * Creation: Folger 10/14/2008													*
 * Purpose: OriginC Header file for PA fit Preview								*
 * Copyright (c) Originlab Corp. 2003, 2004, 2005, 2006, 						*
 * All Rights Reserved															*
 * Iris 10/23/2008 v8.0959b SET_PA_FIT_LINE_NOT_SELECTABLE						*
 * Sophy 10/31/2008 GROUP_CUMULATIVE_CURVE_WITH_FITTED_CURVES					*
 * Kyle 11/26/2008 SUPPORT_GETTING_FIT_Y_WITHOUT_OFFSET_FOR_PA					*
 *	Folger 01/04/09 QA80-12962 MORE_WORK_ON_GENERATE_INDIVIDUAL_FIT_CURVE_USING_INDEPENDENT_X_IN_PA
 *	Folger 02/04/09 QA80-12962 ADD_OPTION_IN_PA_FIT_TO_SWTICH_BACK_TO_OLD_FIT_CURVE_DATA_GENERATION_MECHANISM
 *	Folger 03/24/10 QA81-15237 GENERATE_FITY_BASED_ON_BASELINE_FOR_BETTER_PEAK_PROPERTIES_CALCULATION
 *------------------------------------------------------------------------------*/

#include "curve_utils.h" ///Sophy, use subtract_baseline()

class PeakFitCurves : public NLFCurves
	{
public:
	PeakFitCurves( NLFitSession * pNLFSession ) : NLFCurves( pNLFSession )
	{
	}
	//virtual
	///------ Folger 03/24/10 QA81-15237 GENERATE_FITY_BASED_ON_BASELINE_FOR_BETTER_PEAK_PROPERTIES_CALCULATION
	//bool	GetFitY(const vector& vX, vector& vFitY, NLParametersManager* pParamMngr, int nDatasetIndex = 0, int nPeakIndex = 0);
	bool	GetFitY(const vector& vX, vector& vFitY, NLParametersManager* pParamMngr, int nDatasetIndex = 0, int nPeakIndex = 0, BOOL bZeroY0 = FALSE);
	///------ End GENERATE_FITY_BASED_ON_BASELINE_FOR_BETTER_PEAK_PROPERTIES_CALCULATION
	///Sophy 10/13/2008 GET_CUMULATIVE_DATA_WHITH_BASELINE_MODE
	//virtual
	///------ Folger 01/04/09 QA80-12962 MORE_WORK_ON_GENERATE_INDIVIDUAL_FIT_CURVE_USING_INDEPENDENT_X_IN_PA
	//bool	GetCumulativeData(vector& vCumulative, NLParametersManager* pParamMngr, int nDatasetIndex = 0, int nPeaks = 1, bool bHasBaseLinePeak = false);
	bool	GetCumulativeData(vector& vCumulative, NLParametersManager* pParamMngr, int nDatasetIndex = 0, int nPeaks = 1, bool bHasBaseLinePeak = false, vector* pvXCumulative = NULL);
	///------ End MORE_WORK_ON_GENERATE_INDIVIDUAL_FIT_CURVE_USING_INDEPENDENT_X_IN_PA
	///end GET_CUMULATIVE_DATA_WHITH_BASELINE_MODE
	
	//virtual
	bool	GetBaselineData( vector& vX, vector& vY ); /// Iris 10/21/2008 FITSESSION_NEED_GETBASELINEDATA_FOR_REPORT
	///Kyle 11/26/2008 SUPPORT_GETTING_FIT_Y_WITHOUT_OFFSET_FOR_PA
	//virtual
	///------ Folger 03/24/10 QA81-15237 GENERATE_FITY_BASED_ON_BASELINE_FOR_BETTER_PEAK_PROPERTIES_CALCULATION
	//bool 	GetFitYWithoutOffset(const vector& vX, vector& vFitY, NLParametersManager* pParamMngr, int nDatasetIndex = 0, int nPeakIndex = 0);
	bool 	GetFitYWithoutOffset(const vector& vX, vector& vFitY, NLParametersManager* pParamMngr, int nDatasetIndex = 0, int nPeakIndex = 0, BOOL bZeroY0 = FALSE);
	///------ End GENERATE_FITY_BASED_ON_BASELINE_FOR_BETTER_PEAK_PROPERTIES_CALCULATION
	///End SUPPORT_GETTING_FIT_Y_WITHOUT_OFFSET_FOR_PA
	
	///------ Folger 01/04/09 QA80-12962 MORE_WORK_ON_GENERATE_INDIVIDUAL_FIT_CURVE_USING_INDEPENDENT_X_IN_PA
	/// virtual
	bool	CheckGetSmartXOnPeakShapeOption(SmartXOnPeakShapeOption& stSmartXOpt, int nPeak);
	///------ End MORE_WORK_ON_GENERATE_INDIVIDUAL_FIT_CURVE_USING_INDEPENDENT_X_IN_PA
	
private:	
	void	resetBaselineDataVectors();
	
	//virtual 
	///Sophy 10/31/2008 GROUP_CUMULATIVE_CURVE_WITH_FITTED_CURVES
	//bool 	setupFitPlot(GraphLayer& gl, const vector<int> &vnPlotIndices); /// Iris 10/23/2008 v8.0959b SET_PA_FIT_LINE_NOT_SELECTABLE
	bool 	setupFitPlot(GraphLayer& gl, const vector<int> &vnPlotIndices, int nCumulativeIndex = -1 ); 
	///end GROUP_CUMULATIVE_CURVE_WITH_FITTED_CURVES
	
private:
	///Sophy 10/13/2008 GET_CUMULATIVE_DATA_WHITH_BASELINE_MODE
	/// Iris 10/21/2008 FITSESSION_NEED_GETBASELINEDATA_FOR_REPORT
	// bool	getBaselineData( vector& vX, vector& vY );
	///end FITSESSION_NEED_GETBASELINEDATA_FOR_REPORT
	vector	m_vXBaseline, m_vYBaseline; //need this to avoid runtime ( compiler's problem )
	///end GET_CUMULATIVE_DATA_WHITH_BASELINE_MODE

};

///------ Folger 03/24/10 QA81-15237 GENERATE_FITY_BASED_ON_BASELINE_FOR_BETTER_PEAK_PROPERTIES_CALCULATION
//bool		PeakFitCurves::GetFitY(const vector& vX, vector& vFitY, NLParametersManager* pParamMngr, int nDatasetIndex, int nPeakIndex)//0, 0
bool		PeakFitCurves::GetFitY(const vector& vX, vector& vFitY, NLParametersManager* pParamMngr, int nDatasetIndex, int nPeakIndex, BOOL bZeroY0/* = FALSE*/)//0, 0
///------ End GENERATE_FITY_BASED_ON_BASELINE_FOR_BETTER_PEAK_PROPERTIES_CALCULATION
{
	///------ Folger 03/24/10 QA81-15237 GENERATE_FITY_BASED_ON_BASELINE_FOR_BETTER_PEAK_PROPERTIES_CALCULATION
	//if( !NLFCurves::GetFitY( vX, vFitY, pParamMngr, nDatasetIndex, nPeakIndex ) )
	if( !NLFCurves::GetFitY( vX, vFitY, pParamMngr, nDatasetIndex, nPeakIndex, bZeroY0 ) )
	///------ End GENERATE_FITY_BASED_ON_BASELINE_FOR_BETTER_PEAK_PROPERTIES_CALCULATION
		return false;
	if( 0 == nPeakIndex && m_pNLFSession->GetBaselineFitMode() )
		return true;
	
	vector vXBaseline, vYBaseline;
	///Sophy 10/13/2008 GET_CUMULATIVE_DATA_WHITH_BASELINE_MODE
	//m_pNLFSession->GetBaselineData( vXBaseline, vYBaseline );
	/// Iris 10/21/2008 FITSESSION_NEED_GETBASELINEDATA_FOR_REPORT
	//getBaselineData( vXBaseline, vYBaseline );
	GetBaselineData( vXBaseline, vYBaseline );
	///end FITSESSION_NEED_GETBASELINEDATA_FOR_REPORT
	///end GET_CUMULATIVE_DATA_WHITH_BASELINE_MODE
	if( m_vXBaseline.GetSize() && m_vYBaseline.GetSize() ) //Sophy, if use vXBaseline&vYBaseline, will cause runtime, due to compiler's problem
	{
		vector vXTemp, vYTemp;
		vXTemp = m_vXBaseline;
		vYTemp = m_vYBaseline * (-1);
		subtract_baseline( vX, vFitY, vXTemp, vYTemp ); //add baseline
	}
	return true;
}
///Kyle 11/26/2008 SUPPORT_GETTING_FIT_Y_WITHOUT_OFFSET_FOR_PA
///------ Folger 03/24/10 QA81-15237 GENERATE_FITY_BASED_ON_BASELINE_FOR_BETTER_PEAK_PROPERTIES_CALCULATION
//bool		PeakFitCurves::GetFitYWithoutOffset(const vector& vX, vector& vFitY, NLParametersManager* pParamMngr, int nDatasetIndex, int nPeakIndex)//0, 0
//{
	//return NLFCurves::GetFitY( vX, vFitY, pParamMngr, nDatasetIndex, nPeakIndex );
//}
bool		PeakFitCurves::GetFitYWithoutOffset(const vector& vX, vector& vFitY, NLParametersManager* pParamMngr, int nDatasetIndex, int nPeakIndex, BOOL bZeroY0/* = FALSE*/)//0, 0
{
	return NLFCurves::GetFitY( vX, vFitY, pParamMngr, nDatasetIndex, nPeakIndex, bZeroY0 );
}
///------ End GENERATE_FITY_BASED_ON_BASELINE_FOR_BETTER_PEAK_PROPERTIES_CALCULATION
///End SUPPORT_GETTING_FIT_Y_WITHOUT_OFFSET_FOR_PA

///Sophy 10/13/2008 GET_CUMULATIVE_DATA_WHITH_BASELINE_MODE
//virtual
///------ Folger 01/04/09 QA80-12962 MORE_WORK_ON_GENERATE_INDIVIDUAL_FIT_CURVE_USING_INDEPENDENT_X_IN_PA
//bool	PeakFitCurves::GetCumulativeData(vector& vCumulative, NLParametersManager* pParamMngr, int nDatasetIndex, int nPeaks, bool bHasBaseLinePeak) // 0 , 1, false
bool	PeakFitCurves::GetCumulativeData(vector& vCumulative, NLParametersManager* pParamMngr, int nDatasetIndex, int nPeaks, bool bHasBaseLinePeak, vector* pvXCumulative/* = NULL*/) // 0 , 1, false
///------ Ed MORE_WORK_ON_GENERATE_INDIVIDUAL_FIT_CURVE_USING_INDEPENDENT_X_IN_PA
{
	///------ Folger 01/04/09 QA80-12962 MORE_WORK_ON_GENERATE_INDIVIDUAL_FIT_CURVE_USING_INDEPENDENT_X_IN_PA
	//if(!NLFCurves::GetCumulativeData(vCumulative, pParamMngr, nDatasetIndex, nPeaks, bHasBaseLinePeak ) )
	if(!NLFCurves::GetCumulativeData(vCumulative, pParamMngr, nDatasetIndex, nPeaks, bHasBaseLinePeak, pvXCumulative) )
	///------ End MORE_WORK_ON_GENERATE_INDIVIDUAL_FIT_CURVE_USING_INDEPENDENT_X_IN_PA
		return false;
	vector vX, vY, vXBaseline, vYBaseline;
	//if(m_vXBaseline.GetSize() && m_vYBaseline.GetSize() && GetFit(vX, vY, nDataset) && vX.GetSize() == vCumulative.GetSize())
	/// Iris 10/21/2008 FITSESSION_NEED_GETBASELINEDATA_FOR_REPORT
	//getBaselineData( vXBaseline, vYBaseline );
	GetBaselineData( vXBaseline, vYBaseline );
	///end FITSESSION_NEED_GETBASELINEDATA_FOR_REPORT
	
	GetFit(vX, vY, nDatasetIndex ); 
	if(vXBaseline.GetSize() && vYBaseline.GetSize() && vX.GetSize() == vCumulative.GetSize())
	{
		int nNum = m_pNLFSession->GetNumPeaks() - 1;
		
		vYBaseline = vYBaseline * nNum;		
		subtract_baseline(vX, vCumulative, vXBaseline, vYBaseline);
	}
	return true;
}

/// Iris 10/21/2008 FITSESSION_NEED_GETBASELINEDATA_FOR_REPORT
//bool	PeakFitCurves::getBaselineData( vector& vX, vector& vY )
bool	PeakFitCurves::GetBaselineData( vector& vX, vector& vY )
///end FITSESSION_NEED_GETBASELINEDATA_FOR_REPORT
{
	///Kyle 10/21/08 CHANGE_FUNCTION_NAME_HASBASELINEPEAK_TO_GETBASELINEFITMODE
	//if( m_pNLFSession->HasBaselinePeak() )
	if( m_pNLFSession->GetBaselineFitMode() )
	///End CHANGE_FUNCTION_NAME_HASBASELINEPEAK_TO_GETBASELINEFITMODE
	{
		if ( !GetFit( m_vXBaseline, m_vYBaseline, 0, 0 ) )
		{
			resetBaselineDataVectors();
			return false;
		}
	}
	else
	{
		if ( !m_pNLFSession->GetBaselineData( m_vXBaseline, m_vYBaseline ) )
		{
			resetBaselineDataVectors();
			return false;
		}
	}
	
	vX = m_vXBaseline;
	vY = m_vYBaseline;
	return true;
}

///end GET_CUMULATIVE_DATA_WHITH_BASELINE_MODE

void	PeakFitCurves::resetBaselineDataVectors()
{
	m_vXBaseline.SetSize(0);
	m_vYBaseline.SetSize(0);
}

/// Iris 10/23/2008 v8.0959b SET_PA_FIT_LINE_NOT_SELECTABLE
///Sophy 10/31/2008 GROUP_CUMULATIVE_CURVE_WITH_FITTED_CURVES
//bool 	PeakFitCurves::setupFitPlot(GraphLayer& gl, const vector<int> &vnPlotIndices)
bool 	PeakFitCurves::setupFitPlot(GraphLayer& gl, const vector<int> &vnPlotIndices, int nCumulativeIndex )//-1
///end GROUP_CUMULATIVE_CURVE_WITH_FITTED_CURVES
{
	if( !gl || vnPlotIndices.GetSize() == 0 )
		return false;
	
	gl.UngroupPlots();
	for(int nn = 0; nn < vnPlotIndices.GetSize(); nn++)
	{
		DataPlot dp = gl.DataPlots(vnPlotIndices[nn]);
		if( dp )
		{
			set_dataplot_selectable(dp, false);
		
			///Sophy 10/31/2008 GROUP_CUMULATIVE_CURVE_WITH_FITTED_CURVES
			//if( vnPlotIndices.GetSize() > 1 ) // for multiple peaks plot, set to green color
				//dp.SetColor(SYSCOLOR_GREEN);
			//else
				//dp.SetColor(SYSCOLOR_RED);
			if( nn == nCumulativeIndex )
				dp.SetColor( SYSCOLOR_RED );
			else
				dp.SetColor( SYSCOLOR_CYAN );
			///end GROUP_CUMULATIVE_CURVE_WITH_FITTED_CURVES
		}
		else
			return error_report("Found invalid data plot index in PeakFitCurves::setupFitPlot");
	}
	return true;
}
///end SET_PA_FIT_LINE_NOT_SELECTABLE

///------ Folger 01/04/09 QA80-12962 MORE_WORK_ON_GENERATE_INDIVIDUAL_FIT_CURVE_USING_INDEPENDENT_X_IN_PA
/// virtual
bool	PeakFitCurves::CheckGetSmartXOnPeakShapeOption(SmartXOnPeakShapeOption& stSmartXOpt, int nPeak)
{
	///------ Folger 02/04/09 QA80-12962 ADD_OPTION_IN_PA_FIT_TO_SWTICH_BACK_TO_OLD_FIT_CURVE_DATA_GENERATION_MECHANISM
	if ( !m_pNLFSession->GetUseSmartX() )
		return false;
	///------ End ADD_OPTION_IN_PA_FIT_TO_SWTICH_BACK_TO_OLD_FIT_CURVE_DATA_GENERATION_MECHANISM
	
	NLParametersManager*		pMngr = m_pNLFSession->GetNLParamsMngr();
	int							nFunc = pMngr->GetFuncIndex(nPeak);
	TreeNode	trFDF = m_pNLFSession->GetTreeFDF(nFunc);
	
	if ( trFDF )
	{
		vector		vParams;
		pMngr->GetParamValues(vParams, 0, nPeak, true ); // force it to ignore offset setttings and get all params
		NumericFunction	nf(trFDF);
		NLPEAKPARAMS	stNLPEAKPARAMS;
		nf.GetPeakParametersIndices(&stNLPEAKPARAMS);
		if ( stNLPEAKPARAMS.nIndexCenter < 0 || stNLPEAKPARAMS.nIndexWidth < 0 )		/// baseline, not peak function
			return false;
		
		stSmartXOpt.nPts = m_pNLFSession->GetXPtsForEachPeak();		///------ Folger 02/04/09 QA80-12962 ADD_OPTION_IN_PA_FIT_TO_SWTICH_BACK_TO_OLD_FIT_CURVE_DATA_GENERATION_MECHANISM
		//stSmartXOpt.nPeaks = m_pNLFSession->GetNumPeaks();
		stSmartXOpt.x0 = vParams[stNLPEAKPARAMS.nIndexCenter];
		stSmartXOpt.w = vParams[stNLPEAKPARAMS.nIndexWidth];
		stSmartXOpt.nFuncForm = m_pNLFSession->GetFunctionName(NULL, nFunc).CompareNoCase("Lorentz") == 0 ? GPX_LORENTZ : GPX_GAUSS;

		return true;
	}
}
///------ End MORE_WORK_ON_GENERATE_INDIVIDUAL_FIT_CURVE_USING_INDEPENDENT_X_IN_PA

//-------------------------------------PeakFitCurves class end -----------------------------//
