/*------------------------------------------------------------------------------*
 * File Name: Smoothing.cpp	 													*
 * Creation: ML 5/9/2003														*
 * Purpose: OriginC Source CPP file for auto update smoothing routines	.		*
 * Copyright (c) OriginLab Corp.	2003-2007									*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *------------------------------------------------------------------------------*/



//////////////////////////////////////////////////////////////////////////////////
// Included header files
//////////////////////////////////////////////////////////////////////////////////

// System includes
#include <Origin.h>
#include <analysis_utils.h>
#include <GetNBox.h>
#include <Operation.h>    // Operation class
#include <ColumnFormulaEx.h>

//////////////////////////////////////////////////////////////////////////////////
// Class Smoothing
//////////////////////////////////////////////////////////////////////////////////
// Possible values of nOption in Init() 
enum
{
	OSMOOTHING_SAVITZKY_GOLAY		= 0,
	OSMOOTHING_ADJACENT_AVERAGING,
	OSMOOTHING_FFT_FILTER,
};


////////////////////////////////////////////////////////////////////////////
// GetNBox Event handlers
////////////////////////////////////////////////////////////////////////////
static bool Smoothing_dlg_event(TreeNode& trGUI, int nRow, int nType, Dialog& dlgGetNBox)
{
	TreeNode tr = trGUI.Smooth;
	if(!tr)
		return false;
	
	int nOption = tr.nMethodKind.nVal;
	switch (nOption)
	{
	case OSMOOTHING_SAVITZKY_GOLAY:
		tr.nPolyOrder.Show = 1;
		tr.nPtsToTheLeft.Show = 1;
		tr.nPtsToTheRight.Show = 1;
		tr.nNumPts.Show = 0;
		break;
			
	case OSMOOTHING_ADJACENT_AVERAGING:
	case OSMOOTHING_FFT_FILTER:
		tr.nPolyOrder.Show = 0;
		tr.nPtsToTheLeft.Show = 0;
		tr.nPtsToTheRight.Show = 0;
		tr.nNumPts.Show = 1;
		break;
		
	default:
		ASSERT(FALSE);
		return false;
	}
	return true;
}




const static char	s_cszSavGolPointsTo[] = "|0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25";

#define		SMOOTH_BASE_WKS_NAME			"Smooth"

class	Smoothing : public	ColumnOperationMultiOption
{
protected:	
	//virtual 
	uint ConstructGUIOptions(TreeNode& trGUI, int nOption = 0)
	{
		GETN_USE(trGUI)
		GETN_BEGIN_BRANCH(Smooth, "Smoothing Options") GETN_ID_BRANCH(IDST_SMOOTHING_OPTIONS) GETN_OPTION_BRANCH(GETNBRANCH_SAVE_SETTINGS)
			GETN_LIST(nMethodKind, "Smoothing Method", nOption, "Savitzky-Golay|Adjacent Averaging|FFT Filter")
			GETN_OPTION_EVENT(Smoothing_dlg_event)
			GETN_LIST(nPolyOrder, "Polynomial Order", 1, "First|Second|Third|Fourth|Fifth|Sixth|Seventh|Eighth|Ninth")
			GETN_COMBO(nPtsToTheLeft, "Points to the left", 1, s_cszSavGolPointsTo)
			GETN_COMBO(nPtsToTheRight, "Points to the right", 1, s_cszSavGolPointsTo)
			GETN_COMBO(nNumPts, "Number of points", 5, "|1|2|3|4|5|6|7|8|9|10")
			GETN_COLOR(CurveColor, "Smoothed Curve color", 1)
		GETN_END_BRANCH(Smooth)
		
		return IDST_REOPRT_OPTIONS_SMOOTHING;
	}
	
		
	string	GetAnalysisName(int nKind = 0)
	{
		string str;
		switch (nKind)
		{
		case OSMOOTHING_SAVITZKY_GOLAY:
			str = "Savitzky-Golay";
			break;
			
		case OSMOOTHING_ADJACENT_AVERAGING:
			str = "Adjacent Averaging";
			break;
			
		case OSMOOTHING_FFT_FILTER:
			str = "FFT Filter";
			break;
		
		default:
			
			ASSERT(FALSE);
			return GetClassName();
		}
		return str;
	}
	
	BOOL	GUItoOperationSpec(TreeNode& trOperation, TreeNode &trGUI, int nOption)
	{
		if(!ColumnOperationMultiOption::GUItoOperationSpec(trOperation, trGUI, nOption))
			return false;
		
		int			nKind = trOperation.Operation.Option.nVal;
		
		switch (nKind)
		{
		case OSMOOTHING_SAVITZKY_GOLAY:
			trOperation.Settings.nPolyOrder.nVal = trGUI.nPolyOrder.nVal;
			trOperation.Settings.nPtsToTheLeft.nVal = trGUI.nPtsToTheLeft.nVal;
			trOperation.Settings.nPtsToTheRight.nVal = trGUI.nPtsToTheRight.nVal;
			break;
		case OSMOOTHING_ADJACENT_AVERAGING:
			trOperation.Settings.nNumPts.nVal = trGUI.nNumPts.nVal;
			break;
		case OSMOOTHING_FFT_FILTER:
			trOperation.Settings.nNumPts.nVal = trGUI.nNumPts.nVal;
			break;
		
		default:
			ASSERT(FALSE);
			return FALSE;
		}
		//trOperation.Output.Name.strVal= "Smooth";
		trOperation.Output.DefaultName.strVal = SMOOTH_BASE_WKS_NAME;
		trOperation.Output.DefaultColName.strVal = SMOOTH_BASE_WKS_NAME;
		return TRUE;
	}
	
	BOOL	OperationtoGUISpec(TreeNode& trOperation, TreeNode &trGUI, bool bInit)
	{
		if(!ColumnOperationMultiOption::OperationtoGUISpec(trOperation, trGUI, bInit))
			return false;
		
		int			nKind = trOperation.Operation.Option.nVal;		
		switch (nKind)
		{
		case OSMOOTHING_SAVITZKY_GOLAY:
			trGUI.nPolyOrder.nVal = trOperation.Settings.nPolyOrder.nVal;
			trGUI.nPtsToTheLeft.nVal = trOperation.Settings.nPtsToTheLeft.nVal;
			trGUI.nPtsToTheRight.nVal = trOperation.Settings.nPtsToTheRight.nVal;
			break;
			
		case OSMOOTHING_ADJACENT_AVERAGING:
		case OSMOOTHING_FFT_FILTER:
			trGUI.nNumPts.nVal = trOperation.Settings.nNumPts.nVal;
			break;
		default:
			ASSERT(FALSE);
			return FALSE;
		}
		return TRUE;
	}

	/*
	
	// It calls LLOC:
	BOOL	DoFormula(Column &colOutput, Column &colOutputX, TreeNode &tr)
	{
		curvebase	&cvInput = GetCurveInput();
		vectorbase	&vResult = colOutput.GetDataObject();
		
		//int			nKind = tr.GUI.nMethodKind.nVal;
		int			nKind = tr.Operation.Option.nVal;
		
		int r1 = tr.Input.Range1.R1.nVal;
		int	r2 = tr.Input.Range1.R2.nVal;
		int	nErr;		

		// temp, there is a bug with ref assignment
		//vResult = cvInput;// this is not working yet, so need to go through a copy 
		Curve cvCopy(cvInput);
		vResult = cvCopy;
		//
		int nMissings, nOffset;
		DWORD dwCntrl = CURVECOPY_SCAN_OVER_MISSING_FROM_LEFT | CURVECOPY_SCAN_OVER_MISSING_FROM_RIGHT | CURVECOPY_REPLACE_MISSING_INSIDE;
		Curve cvTemp(cvInput, nMissings, nOffset, dwCntrl, r1, r2);

		int		nNumPts = tree_node_get_int(tr.Settings.nNumPts);
		// Calling LLOC functions:
		switch (nKind)
		{
		case OSMOOTHING_SAVITZKY_GOLAY:
			{
				//int		nPolyOrder = tr.GUI.nPolyOrder.nVal;
				//int		nPtsToTheLeft = tr.GUI.nPtsToTheLeft.nVal;
				//int		nPtsToTheRight = tr.GUI.nPtsToTheRight.nVal;
				int		nPolyOrder = tr.Settings.nPolyOrder.nVal;
				int		nPtsToTheLeft = tr.Settings.nPtsToTheLeft.nVal;
				int		nPtsToTheRight = tr.Settings.nPtsToTheRight.nVal;

				nErr = smooth_sg(cvTemp, nPolyOrder, nPtsToTheLeft, nPtsToTheRight);
			}
			break;
		case OSMOOTHING_ADJACENT_AVERAGING:
			nErr = smooth_adjave(cvTemp, nNumPts);
			break;
		case OSMOOTHING_FFT_FILTER:
			nErr = smooth_fft(cvTemp, nNumPts);
			break;
		default:
			ASSERT(FALSE);
			return FALSE;
		}
		
		//vResult.SetSubVector(cvTemp, nOffset);
		SetResultsData(vResult, colOutputX, cvTemp, nOffset);
		return TRUE;
	}
	*/
};




