/*------------------------------------------------------------------------------*
 * File Name:	PeakRectControlList.c											*
 * Creation: 	Hong 02/25/08													*
 * Purpose: OriginC Source H file												*
 * Copyright (c) ABCD Corp.	2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010		*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	Folger 02/11/10 QA81-15085 PA_INTEG_FAILS_WHEN_SCALE_IN						*
 *------------------------------------------------------------------------------*/
#include <origin.h>
#include "curve_utils.h"
#include "grobj_utils.h" 
#include "PeakRectControlList.h"


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////member functons of LineControl////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///------ Folger 02/11/10 QA81-15085 PA_INTEG_FAILS_WHEN_SCALE_IN
PeakRectControlList::PeakRectControlList()
{
	SetupLTVarTempChange();
}
PeakRectControlList::~PeakRectControlList()
{
	CleanupLTVarTempChange();
}
///------ End PA_INTEG_FAILS_WHEN_SCALE_IN

int PeakRectControlList::CreateList(Layer& lay, LPCSTR lpcszNameBase, int nMaxNum, int nNum, TreeNode& trSettings, const vector& vSrcX, const vector& vSrcY, 
    	bool bUpdate, bool bSkipRevise, int nMainObj, BOOL bLine, BOOL bTitle, BOOL bLabel) // = false, false, GROT_RECT, false, false, false
{
	if ( !CreateList(lay, lpcszNameBase, nMaxNum, nNum, trSettings, nMainObj, bLine, bTitle, bLabel) )
		return -1;
	
	m_vSrcX = vSrcX;
	m_vSrcY = vSrcY;	
	
	///Sandy 2008-8-18 sort vxi and vyi for ensure left is smaller than right
	vector<uint> vn;
	m_vSrcX.Sort(SORT_ASCENDING, true, vn);
	m_vSrcY.Reorder(vn);
	//end	
	if ( bUpdate )
	{				
		vector vxPeaks, vxLeft, vxRight;
		if ( !find_peaks_by_number_full_auto(vSrcX, vSrcY, nNum, vxPeaks, vxLeft, vxRight) )
			return -2;
				
		if ( !bSkipRevise && trSettings.Number && trSettings.Number.nVal > 0 )
		{				
			for ( int ii = 1; ii <= trSettings.Number.nVal; ii++ )
			{
				TreeNode trOldNode = tree_find_node_by_dataID(trSettings, IDE_ANCHOR_ID + ii);
				if(!trOldNode.LineX || !trOldNode.Left ||!trOldNode.Right)
					continue;
				
				double dOldLX = trOldNode.LineX.dVal;
				double dOldLM = trOldNode.Left.dVal;
				double dOldRM = trOldNode.Right.dVal;
				
				vector<uint> vecIndex;
				if ( 1 == vxPeaks.Find(vecIndex, dOldLM,dOldRM) )
				{
					vxLeft[vecIndex[0]] = dOldLM;
					vxRight[vecIndex[0]] = dOldRM;
				}
			}					
		}
		
		int nLastElemInx = vSrcX.GetSize() - 1;
		for(int ii = 0; ii< vxPeaks.GetSize(); ii++)
		{
			vxLeft[ii] = max(vxLeft[ii], vSrcX[0]);
			vxRight[ii] = min(vxRight[ii], vSrcX[nLastElemInx]);		
		}
		SetXPosition(vxPeaks, vxLeft, vxRight);
	}
	return 0;
}    	
	
int PeakRectControlList::UpdatePeak(int nIndex, const vector& vxBaseLine, const vector& vyBaseLine) // = NULL, NULL
{
	if ( !IsValid() )
		return -1;
	
	ShapeControl sc(m_layParent, m_strNameBase + "_" + (string)nIndex);
	if ( !sc.IsValid() )
		return -2;
	
	double dX, dY, dLeft, dRight, dTop, dBottom;
	sc.GetPosition(dX, dY, dLeft, dRight, dTop, dBottom);

	IntegrationResult IntResult;
	int nTo, nFrom;
	vector vyTemp;
	vyTemp = m_vSrcY;
	if ( vxBaseLine && vyBaseLine )
	{		
		vector vxTemp;
		vxTemp = m_vSrcX;
		subtract_baseline(vxTemp, vyTemp, vxBaseLine, vyBaseLine); // this function do NOT said vector of x column will NOT be modified
	}
	if ( integrate_individual_peak(m_vSrcX, vyTemp, dLeft, dRight, IntResult, nFrom, nTo) )
	{
		sc.SetLinePos(IntResult.xPeak);
		string  strData;
		strData.Format("Integrate from %s to %s: Area = %s", ftoa(m_vSrcX[nFrom]), ftoa(m_vSrcX[nTo]), ftoa(IntResult.Area));
		SetDataDisplayText(strData);	
	}
	return 0;
}



int PeakRectControlList::UpdatePeak(int nIndex, int nLocalBaselineType, vector& vxLocalBase, vector& vyLocalBase) 
{
	if ( !IsValid() )
		return -1;
	
	ShapeControl sc(m_layParent, m_strNameBase + "_" + (string)nIndex);
	if ( !sc.IsValid() )
		return -2;
	
	double dX, dY, dLeft, dRight, dTop, dBottom;
	sc.GetPosition(dX, dY, dLeft, dRight, dTop, dBottom);


	int nLeft, nRight;
	vector vyTemp, vxTemp;

	
	vector vxLocalBaseline, vyLocalBaseline;
	if(!get_local_baseline_by_interp(m_vSrcX, m_vSrcY, vxLocalBaseline, vyLocalBaseline, dLeft, dRight, nLocalBaselineType, nLeft, nRight) || abs(nRight - nLeft)<2)
		return -3;
	
	m_vSrcX.GetSubVector(vxTemp, nLeft, nRight);
	m_vSrcY.GetSubVector(vyTemp, nLeft, nRight);
	

	IntegrationResult IntResult;	
	int nTo, nFrom;
	if ( integrate_individual_peak(vxTemp, vyTemp, dLeft, dRight, IntResult, nFrom, nTo, NULL, vyLocalBaseline) )
	{
		sc.SetLinePos(IntResult.xPeak);
		string  strData;
		strData.Format("Integrate from %s to %s: Area = %s", ftoa(m_vSrcX[nLeft]), ftoa(m_vSrcX[nRight]), ftoa(IntResult.Area));
		SetDataDisplayText(strData);	
	}
	
	if(vxLocalBase)
		vxLocalBase = vxLocalBaseline;
	
	if(vyLocalBase)
		vyLocalBase = vyLocalBaseline;
	return 0;
}

bool PeakRectControlList::SetSource(const vector& vSrcX, const vector& vSrcY)
{
	if ( !IsValid() )
		return false;
	m_vSrcX = vSrcX;
	m_vSrcY = vSrcY;
	return true;
}

///------ Folger 02/11/10 QA81-15085 PA_INTEG_FAILS_WHEN_SCALE_IN
void	PeakRectControlList::SetupLTVarTempChange()
{
	LPCSTR	lpcszDEL = "@DEL";
	LPCSTR	lpcszDEU = "@DEU";
	int		nTimes = 100;

	double	rr = NANUM;

	LT_evaluate(lpcszDEL, &rr);
	m_pLTVarDEL = new LTVarTempChange(lpcszDEL, rr * nTimes);

	LT_evaluate(lpcszDEU, &rr);
	m_pLTVarDEU = new LTVarTempChange(lpcszDEU, rr * nTimes);
}
void	PeakRectControlList::CleanupLTVarTempChange()
{
	NICE_SAFE_REMOVAL(m_pLTVarDEL);
	NICE_SAFE_REMOVAL(m_pLTVarDEU);
}
///------ End PA_INTEG_FAILS_WHEN_SCALE_IN