/*------------------------------------------------------------------------------*
 * File Name: Integrate.cpp	 													*
 * Creation: GJL 5/13/2003														*
 * Purpose: OriginC Source CPP file for Autoupdate integrate routines.			*
 * Copyright (c) OriginLab Corp.	2003-2007									*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *------------------------------------------------------------------------------*/

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

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

// Define Constants
#define INTEG_CLASS_NAME			"Integrate"
#define INTEG_PLOT_OPTION			"Plot"
#define INTEG_CURVE_COLOR			"Curve Color"
#define INTEG_BASE_PLOT_NAME		"IntegPlot"
#define INTEG_PAGE_LABEL_PREFIX		"Integral of"
#define INTEG_PLOT_TEMPLATE			"Origin.otp"
#define INTEG_BASE_WKS_NAME			"Integral"
#define INTEG_RESULT_VALUE_NAMES	"Data Row Range|Area|Peak X Position|Peak Y Position|Peak Width"
#define INTEG_DELIM					'|'
#define INTEG_X_INDEX_FORMAT		"%d : %d"



////////////////////////////////////////////////////////////////////////////
// C - functions
////////////////////////////////////////////////////////////////////////////

static bool Integrate_dlg_event(TreeNode& tr, int nRow, int nType, Dialog& dlgGetNBox)
{
	if( TRGP_STR_LIST == nType && tr.PlotOption.IsValid() )
	{
		if( tr.PlotOption.nVal )
			tr.CurveColor.Show = 1;
		else
			tr.CurveColor.Show = 0;
	}

	return true;
}

//////////////////////////////////////////////////////////////////////////////////
// Class Integrate
//////////////////////////////////////////////////////////////////////////////////

class Integrate : public ColumnFormulaEx
{
	string GetClassName()
	{
		return INTEG_CLASS_NAME;
	}
	
	BOOL ConstructGUINode(TreeNode &tr, int nOption)
	{
		GETN_CURVE_OPERATION(myTree);

		GETN_LIST(PlotOption, INTEG_PLOT_OPTION, CFE_PLOT_OPTION_NEW_GRAPH, CFE_PLOT_OPTIONS);

		GETN_COLOR(CurveColor, INTEG_CURVE_COLOR, 1);

		ColumnFormulaEx::ConstructAddCommon(myTree);

		tr = myTree;

		return TRUE;
	}

	BOOL GUItoOperationSpec(TreeNode& trOperation, TreeNode &trGUI, int nOption)
	{
		//trOperation.Output.Name.strVal = INTEG_BASE_WKS_NAME;
		trOperation.Output.DefaultName.strVal = INTEG_BASE_WKS_NAME;
		trOperation.Output.DefaultColName.strVal = INTEG_BASE_WKS_NAME;	// same as def. wks. name
		//trOperation.Output.DefaultColXName.strVal = DEFAULT_RESULT_COLUMN_X_NAME;

		return TRUE;
	}

	BOOL OperationtoGUISpec(TreeNode& trOperation, TreeNode &trGUI)
	{
		return TRUE;
	}

	// Calls LLOC:
	BOOL DoFormula(Column &colOutput, Column &colOutputX, TreeNode &trOperation)
	{
		Curve crvInput = GetCurveInput();
		vectorbase& vResult = colOutput.GetDataObject();
		vResult.SetSize(crvInput.GetSize());

		vResult = 0; //CPY 6/7/03

		int r1 = trOperation.Input.Range1.R1.nVal;
		int r2 = trOperation.Input.Range1.R2.nVal;

		int nMissingValues, nOffset;
		DWORD dwCntrl = CURVECOPY_SCAN_OVER_MISSING_FROM_LEFT | CURVECOPY_SCAN_OVER_MISSING_FROM_RIGHT | CURVECOPY_REPLACE_MISSING_INSIDE;
		Curve crvTemp(crvInput, nMissingValues, nOffset, dwCntrl, r1, r2);

		// Calling LLOC function:
		BOOL bOK;
		Dataset dsTemp(crvTemp);
		IntegrationResult irResults; // Origin C structure to store integration results
		bOK = Curve_integrate(&crvTemp, &irResults, NULL, &dsTemp, TRUE); // Perform integration

		if( bOK )
		{
			/*
			// If a separate X in output:
			if (colOutputX)
			{
				vResult = dsTemp;
				Dataset			dsX;
				if (crvTemp.AttachX(dsX))
				{
					vectorbase		&vResultX = colOutputX.GetDataObject();
				
					vResultX = dsX;
				}
			}
			else
				vResult.SetSubVector(dsTemp, nOffset);
			*/
			SetResultsData(vResult, colOutputX, crvTemp, nOffset, dsTemp);

			trOperation.Output.Result.x1.dVal = 0;// make sure Result node present, will create if not
			TreeNode trResult = trOperation.Output.Result;
			
			//--CPY 6/7/03, changed from dVal = c_index_to_labtalk_index(irResults.i1), should use original data range
			trResult.i1.nVal = c_index_to_labtalk_index(r1);
			trResult.i2.nVal = c_index_to_labtalk_index(r2);
			//--
			trResult.x1.dVal = irResults.x1;
			trResult.x2.dVal = irResults.x2;
			trResult.Area.dVal = irResults.Area;
			trResult.xPeak.dVal = irResults.xPeak;
			trResult.yPeak.dVal = irResults.yPeak;	
			trResult.dxPeak.dVal = irResults.dxPeak;
		}

		return bOK;
	}

	void UpdateReportingHeaderContents(TreeNode &trOperation, bool bInit = false)
	{
		ColumnFormulaEx::UpdateReportingHeaderContents(trOperation, bInit);

		if( bInit )		
		{
			if( !trOperation.Reporting.Contents.Header.Table )
			{
				ASSERT(FALSE); // Should have been initialized in the baseclass
				return;
			}

			// Init values
			TreeNode trTable = trOperation.Reporting.Contents.Header.Table;
			trTable.xIndex.strVal = "junk";
			trTable.xIndex.strVal = "";
			trTable.Area.dVal = 0;
			trTable.xPeak.dVal = 0;
			trTable.yPeak.dVal = 0;
			trTable.dxPeak.dVal = 0;

			// Init labels
			string str = INTEG_RESULT_VALUE_NAMES;
			trTable.xIndex.SetAttribute(STR_LABEL_ATTRIB, str.GetToken(0, INTEG_DELIM));
			trTable.Area.SetAttribute(STR_LABEL_ATTRIB, str.GetToken(1, INTEG_DELIM));
			trTable.xPeak.SetAttribute(STR_LABEL_ATTRIB, str.GetToken(2, INTEG_DELIM));
			trTable.yPeak.SetAttribute(STR_LABEL_ATTRIB, str.GetToken(3, INTEG_DELIM));
			trTable.dxPeak.SetAttribute(STR_LABEL_ATTRIB, str.GetToken(4, INTEG_DELIM));
		}
		else // Update after execution
		{
			if( !trOperation.Reporting.Contents.Header.Table )
			{
				ASSERT(FALSE); // Must have been intialized before
				return;
			}

			if( !trOperation.Output.Result )
			{
				ASSERT(FALSE); // Must have been intialized before (in DoFormula())
				return;
			}

			TreeNode trResult = trOperation.Output.Result;
			TreeNode trTable = trOperation.Reporting.Contents.Header.Table;
			trTable.xIndex.strVal.Format(INTEG_X_INDEX_FORMAT, (int) trResult.i1.nVal, (int) trResult.i2.nVal);
			trTable.Area.dVal = trResult.Area.dVal;
			trTable.xPeak.dVal = trResult.xPeak.dVal;
			trTable.yPeak.dVal = trResult.yPeak.dVal;
			trTable.dxPeak.dVal = trResult.dxPeak.dVal;
		}
	}

	/// YuI 11/12/08 ADDITIONAL_CLEANUP_FOR_EXECUTE_ON_CHANGE_PARAM
	//	BOOL	OnAfterExecute()
	//	{
	//		return ColumnFormulaEx::OnAfterExecute();
	//	}
	/// end ADDITIONAL_CLEANUP_FOR_EXECUTE_ON_CHANGE_PARAM

	BOOL GetGraphInfo(string &strTemplate, string &strBasePageName, string &strPageLabelPrefix, int &nPlotType)
	{
		strTemplate = INTEG_PLOT_TEMPLATE;
		strBasePageName = INTEG_BASE_PLOT_NAME;					
		strPageLabelPrefix = INTEG_PAGE_LABEL_PREFIX;
		nPlotType = IDM_PLOT_LINE;
		return TRUE;
	}

	PEVENT_FUNC GetEventFunction()
	{
		return Integrate_dlg_event;
	}
};