/*------------------------------------------------------------------------------*
 * File Name: Curve.h															*
 * Creation: TD 4-14-03															*
 * Purpose: Origin C header file for Origin basic Data types					*
 * Copyright (c) OriginLab Corp.	2002 - 2007									*
 * All Rights Reserved															*
 * Modifications:																*
 *------------------------------------------------------------------------------*/

#ifndef _CURVE_H
#define _CURVE_H
#define _CURVE_BASE

#include <vector.h>


// The following are related to sorting
#define		NS_DESCENDING			0x2000
#define		NS_MISSING_AS_SMALLEST	0x1000 // If this bit is on missing values are treated as the smallest value when sorting...otherwise they are treated as the as the largest value

/** >Composite Data Types
		The Origin C curvebase class is an abstract base class used for polymorphic handling
		of Curve related template class types. Consequently, Origin C objects of type curvebase
		can not be constructed. Derived classes, such as Curve, inherit curvebase class methods
		and should be used instead. The curvebase class is derived from vectorbase class from
		which it inherits methods and properties.
	Example:
		// Assumes Data1_A and Data1_B exist and contain data 
		Dataset ds1("Data1_A"), ds2("Data1_B");
		Curve crvCopy( ds1, ds2 );
		crvCopy.Sort(); // Does not effect ds1, ds2
*/ 
class curvebase : public vectorbase
{

	/**
			Get the name of an internal Origin data set.
		Example:
			// Worksheet column Data1_A must exist prior to execution
			string strName;
			Dataset	dsA("Data1_A");
			dsA.GetName(strName);
			out_str("Data set name is " + strName);
		Parameters:
			strName=Returned name of an internal Origin data set 
		Return:
			Returns TRUE on successful exit and FALSE on failure. Also returns the name of an internal Origin data set.
	*/
	BOOL	GetName(string& strName); // Get the name of an internal Origin data set.

	/**
			Get the name of an internal Origin data set.
		Example:
			// Worksheet column Data1_A must exist prior to execution
			string strName;
			Dataset dsA("Data1_A");
			strName = dsA.GetName();
			out_str("Data set name is " + strName);
		Return:
			Returns the name of an internal Origin data set.
	*/
	string  GetName(); // Get the name of an internal Origin data set.

	/**
			Checks the validity of an Origin C Dataset object. Dataset objects
			are valid when they are successfully attached to an internal Origin
			data set.
		Example:
			// Worksheet column Data1_A must exist prior to execution
			Dataset dsA;                          // Dataset is not yet attached and is not valid
			if(dsA.IsValid())
				out_str("Dataset is valid!");
			else
				out_str("Dataset is not valid!");
			dsA.Attach("Data1_A");                // Dataset is now attached and is valid
			if(dsA.IsValid())
				out_str("Dataset is valid!");
			else
				out_str("Dataset is not valid!");
		Return:
			Returns TRUE if Dataset object is valid and FALSE if not.
		SeeAlso:
			Dataset::Attach, Dataset::Detach
	*/
	BOOL	IsValid(); // Checks the validity of an Origin C Dataset object.
	
	/**
			Update an Origin C Dataset object from an Origin data set or update
			an Origin data set from an Origin C Dataset object. The number of
			elements and memory allocated are primarily affected by this method.
		Example:
			// Worksheet column Data1_A must exist prior to execution
			void test_update_OC_when_Origin_changed()
			{
				Dataset	dsA("Data1_A");
				dsA.SetSize(10);
				dsA=1;
				LT_execute("set Data1_A -e 20;Data1_A=2;"); // Note Dataset size is not updated but Dataset values change in Local Variables windows of Debug mode 
				dsA.Update(TRUE); // Note Dataset dsA size is now updated in Local Variables windows of Debug mode
				ASSERT(dsA.GetSize()==20);
			}
			
			// Assumes Data1 worksheet with column B
			// This example shows how to update Origin from inside Origin C program before it returns
			void test_update_Origin_when_OC_data_changed()
			{
				Dataset aa("Data1_b");
				// in case column is empty
				if(aa.GetSize()<1)
				{
					aa.SetSize(10);
					aa=0;
				}
				
				aa[0]+= 1;
				aa.Update(FALSE, REDRAW_REFRESH);
				MessageBox(GetWindow(),"Data1_b increment 1, click OK to increment again");
				aa[0]+=1;
			}
			
			// Demonstrate the usage of REDRAW_REALTIME_SCOPE and REDRAW_REALTIME_WKS
			// Assumes:
			//    1) Data1_A is filled with row numbers
			//    2) Data1_A(X) vs. B(Y) is plotted as line plot
			//    3) The line plot is set to animate mode so that the effect is fully visualized
			//       (set plot active and then execute LabTalk script command "set %C -an 1")
			
			void test_realtime_update_Origin_fromOC(int imax = 20)
			{
				Dataset aa("Data1_b");
				int	nMaxRows = 10;
				if(aa.GetSize()<nMaxRows)
				{
					aa.SetSize(nMaxRows);
					aa=0;
				}
				
				int ic = 0;//current cell
			
				for(int ii = 0; ii < imax; ii++)
				{
					for(int jj = 0; jj < nMaxRows; jj++)
						aa[jj] = 1;
					
					aa[ic++] = 2;
					if(ic >= nMaxRows)
						ic = 0;
					//aa.Update(FALSE, REDRAW_REALTIME_WKS);
					aa.Update(FALSE, REDRAW_REALTIME_SCOPE);
					LT_execute("sec -w 0.1;");// hard wait 
				}
			}
		Parameters:
			bFromOrigin=TRUE updates the Origin C Dataset object from the Origin data set, FALSE updates the Origin dataset
				from an Origin C Dataset object.
			mode=Dataset update mode, used only if bFromOrigin=FALSE. Supported values are
		mode=Dataset update mode, allowed values are
			REDRAW_NONE				do update
			REDRAW_REALTIME_WKS		similar to REDRAW_REALTIME_SCOPE, but redraw the entire worksheet	
			REDRAW_REFRESH			do a simple refresh of the data
			REDRAW_REALTIME_SCOPE	this is used to do realtime drawing for the entire range of data. To see effect in plots, must set dataplots to animate mode
		SeeAlso:
			Dataset::Append
	*/
	void	Update(BOOL bFromOrigin, int mode = -1); // Update an Origin C Dataset object from an Origin data set or vice-versa. 

#ifdef _POST_ORIGIN7_
	/**#
	*/
	BOOL	Append(vectorbase& v, int iMode);
#else
	/**
			Append data from a vector or Dataset object to this Origin C Dataset
			object and update the Origin data set from this Origin C Dataset object.
		Example:
			// Assume Data1 worksheet and with A(X) vs. B(Y) plotted in graph window
			// Can test by typing "rt_add 10" into Script window with the graph active
			void rt_add(int npts)
			{
				static int nn = 1; 
	
				Worksheet wks("data1");
				Dataset aa(wks,0);
				Dataset bb(wks,1);

				vector a(npts);
				vector b(npts);

				for(int ii = 0; ii < npts; ii++)
				{
					a[ii] = nn++;
					b[ii] = rnd();
				}

				aa.Append(a, REDRAW_REALTIME);
				bb.Append(b, REDRAW_REALTIME);
				return;
			}
		Parameters:
			v=vector or Dataset to append
			iMode=Dataset update mode, allowed values are
				REDRAW_NONE				do update
				REDRAW_REALTIME			graph realtime drawing, only the new added data will be drawn		
				REDRAW_REALTIME_WKS		similar to REDRAW_REALTIME_SCOPE, but redraw the entire worksheet	
				REDRAW_REFRESH			do a simple refresh of the data
				REDRAW_REALTIME_SCOPE	this is used to do realtime drawing for the entire range of data. To see effect in plots, must set dataplots to animate mode
		Return:
			Returns TRUE on successful exit and FALSE on failure.
		SeeAlso:
			vectorbase::Append, Dataset::Update
	*/
	BOOL	Append(vector& v, int iMode = REDRAW_NONE); // Append data from a vector or Dataset object to this Origin C Dataset object.
#endif //!_POST_ORIGIN7_

 	/**
			TrimLeft removes elements having the value NANUM from the left end or
			beginning of the Dataset by advancing the lower index to the first
			valid numeric value. If bShiftLeft is TRUE cells containing NANUM
			are deleted from the Dataset and a lower index value of 0 is returned
			shifting numeric values left to the beginning of the Dataset. When bShiftLeft 
			is TRUE TrimLeft of Curve objects causes both X and Y Datasets to be trimmed.
		Example:
			// Worksheet columns Data1_A and data1_B must exist prior to execution
			Dataset	dsA("Data1",0);
			dsA.TrimLeft(TRUE);
			Curve crvAxBy("Data1_A","Data1_B");
			crvAxBy.TrimLeft(TRUE);
			LT_execute("doc -uw");
		Parameters:
			bShiftLeft=TRUE will delete cells on the left of (before) the first valid numeric value, FASLE will cause the lower bound
				or index to be adjusted upward but no cells are deleted.
		Returns:
			Returns -1 on error, 0 on success, and N > 0 for number of cells deleted.
		SeeAlso:
			Dataset::TrimRight, vectorbase::GetLowerBound, vector::vector
	*/
 	int		TrimLeft(BOOL bShiftLeft = FALSE); // TrimLeft removes elements having the value NANUM from the left end of a Dataset.

 	/**
			TrimRight removes elements having the value NANUM from the right end or
			bottom of the Dataset by retarding the upper index to the last valid numeric
			value. If bDelExtra is set to TRUE cells containing NANUM are deleted from
			the Dataset. When bDelExtra is TRUE TrimRight of Curve objects causes both
			X and Y Datasets to be trimmed.
		Example:
			// Worksheet columns Data1_A and data1_B must exist prior to execution
			Dataset	dsA("Data1",0);
			dsA.TrimRight(TRUE);
			Curve crvAxBy("Data1_A","Data1_B");
			crvAxBy.TrimRight(TRUE);
			LT_execute("doc -uw");
		Parameters:
			bDelExtra=TRUE will delete cells on the right of (after) the last valid numeric value, FASLE will cause the upper bound
				or index to be adjusted downward but no cells are deleted.
		Returns:
			Returns -1 on error, 0 on success, and N > 0 for number of cells deleted.
		SeeAlso:
			Dataset::TrimLeft, vectorbase::GetUpperBound, vectorbase::GetSize, vector::vector
	*/
 	int		TrimRight(BOOL bDelExtra = FALSE); // TrimRight removes elements having the value NANUM from the right end of a Dataset.
	
	/**
			Use a Curve object to sort a Y data set according to an X data set. This function does nothing if is there
			is no X data set associated with the Y data set.
			Please note that constructor of curve that takes two Dataset is just making a copy of the Datasets, they are not attched to the curve. 
			So even you made some changes to the curve, it will not affect the original Dataset. Due to this reason, the curve sort will ONLY 
			work on the X Dataset, So if one want to make sort on Y Dataset, he may need to construct a curve with X and Y dataset swapped first.  
		Example:
			// Assumes Data1_A and Data1_B exist and contain data
			Curve crv("Data1_A","Data1_B");
			crv.Sort(NS_DESCENDING | NS_MISSING_AS_SMALLEST);
		Parameters:
			 dwFlags=Sort options. Default 0 sorts in ascending order and places missing values at the end. See
			 the NS_DESCENDING and NS_MISSING_AS_SMALLEST macro definitions in system header file data.h
		Return:
			Returns TRUE on successful exit and FALSE on error.
		SeeAlso:
			Data_sort
	*/
	BOOL	Sort(DWORD dwFlags = 0); // Use a Curve object to sort a Y data set according to an X data set.

	/**
			Checks whether or not this Curve object has an associated X data set.
		Example:
			// Assumes Data1_B exists and contains data
			Curve crv("Data1_B");
			BOOL bHasX = crv.HasX();
		Parameters:			
			strXdatasetName = optional string to receive the X dataset name
		Return:
			Returns TRUE if this Curve object has an associated X data set.
		SeeAlso:
			Curve::Attach, Curve::Curve
	*/
	BOOL HasX(string& strXdatasetName = NULL); // Checks whether or not this Curve object has an associated X data set.

	/**
			Attach an Origin C Dataset object to the X data set associated with this Curve object (if there is
			one) and optionally set the upper and lower bounds of the X data set to the upper and lower bounds
			of the Curve object's Y data set.
		Example:
			// Assumes Data1_A(X) and Data2_B(Y) exist with the following data:
			// Data1_B={1,2,3,4,5,6,7}
			// Data1_A={1,2,3,4,5,6,7,-10,10};
			Curve crv("Data1_B");
			Dataset dsX;
			BOOL bRet = crv.AttachX(dsX);
			double xMin = min( dsX );
			double xMax = max( dsX );
			printf( "Due to upper bound restriction of Y Dataset the Minimum X in dsX is %g not -10\n", xMin );
			printf( "Due to upper bound restriction of Y Dataset the Maximum X in dsX is %g not 10\n", xMax );
		Parameters:
			dsX=A Dataset object which is attached to the X data set of this Curve object (if any)
			SetXRangeToYRange=TRUE (default) sets the upper and lower bounds of the X data set to the upper
				and lower bounds of the Curve object's Y data set. This setting is temporary and may be over-
				ridden when using multiple Curve objects linked to the same X data set.
		Return:
			Returns TRUE if the Curve object has an associated X data set and the attachment is successful and FALSE
				if there is no X data set or the attachment fails.
		SeeAlso:
			Dataset::Attach, Curve::Attach, Curve::Detach
	*/
	BOOL AttachX(Dataset& dsX, BOOL SetXRangeToYRange = TRUE); // Attach an Origin C Dataset object to the X data set associated with this Curve object.
	/**
			Set the upper display index of the Dataset range. Index values are 0 based
			offsets so use SetUpperBound(-1) to dispaly no rows. SetUpperBound is supported
			only for Datasets (not vectors) while GetUpperBound is supported for all
			vectorbase derived objects. This allows for creation of more general purpose
			functions that can take vectorbase objects as arguments in place of Dataset
			objects. Essentially, the upper bound can be read but not written for vectors.
			SetUpperIndex is a synonym for SetUpperBound. 
		Example:
			// Worksheet column Data1_A must exist prior to execution
			Dataset	dsA("Data1_A");
			dsA.SetSize(10);
			for(int ii = 0; ii < 10; ii++)
				dsA[ii] = ii;

			dsA.SetLowerBound(2);
			dsA.SetUpperBound(7);
			BasicStats bsStatVal;
			Data_sum(&dsA, &bsStatVal);
			ASSERT( bsStatVal.min == 2 );
			ASSERT( bsStatVal.max == 7 );
	
			dsA.SetLowerBound(0);
			dsA.SetUpperBound(9);
			Data_sum(&dsA, &bsStatVal);
			ASSERT( bsStatVal.min == 0 );
			ASSERT( bsStatVal.max == 9 );
		Parameters:
			nUpper=New upper display index of the Dataset
		Return:
			Returns TRUE on successful exit and FALSE on failure.
		SeeAlso:
			 vectorbase::GetUpperBound, vectorbase::GetSize, vectorbase::SetSize, vectorbase::GetLowerBound, Dataset::SetLowerBound
	*/
	BOOL 	SetUpperBound(int nUpper); // Set the upper display index of the Dataset.

		/**
			Set the lower display index of the Dataset range. Index values are 0 based
			offsets. SetLowerBound is supported only for Datasets (not vectors) while
			GetLowerBound is supported for all vectorbase derived objects. This allows
			for creation of more general purpose functions that can take vectorbase
			objects as arguments in place of Dataset objects. Essentially, the lower
			bound can be read but not written for vectors. SetLowerIndex is a synonym
			for SetLowerBound.  
		Example:
			// Worksheet column Data1_A must exist prior to execution
			Dataset	dsA("Data1_A");
			dsA.SetSize(10);
			for(int ii = 0; ii < 10; ii++)
				dsA[ii] = ii;

			dsA.SetLowerBound(2);
			dsA.SetUpperBound(7);
			BasicStats bsStatVal;
			Data_sum(&dsA, &bsStatVal);
			ASSERT( bsStatVal.min == 2 );
			ASSERT( bsStatVal.max == 7 );
	
			dsA.SetLowerBound(0);
			dsA.SetUpperBound(9);
			Data_sum(&dsA, &bsStatVal);
			ASSERT( bsStatVal.min == 0 );
			ASSERT( bsStatVal.max == 9 );
		Parameters:
			nLower=New lower display index of the Dataset
		Return:
			Returns TRUE on successful exit and FALSE on failure.
		SeeAlso:
			 vectorbase::GetLowerBound, vectorbase::GetSize, vectorbase::SetSize, vectorbase::GetUpperBound, Dataset::SetUpperBound
	*/
	BOOL 	SetLowerBound(int nLower); // Set the lower display index of the Dataset.
	
	/**
			Find all the points in a Curve which fall on or within a specified rectangle. The rectangle is specified by
			its top-left and bottom-right corners.
		Example:
			// Assumes Data1_A(X) and Data1_B(Y) exist with the following data:
			// Data1_B={1,2,3,4,5,6,7,8,9,10}
			// Data1_A={1,2,3,4,5,6,7,8,9,10};
			Dataset ds1("Data1_A"), ds2("Data1_B");
			Curve crv(ds1, ds2);
			fpoint fptTL(3,8);
			fpoint fptBR(7,2);
			vector<double> vX, vY;
			vector<int> vIndex; 
			int num = crv.GetRectPoints( fptTL, fptBR, vX, vY, vIndex );
		Parameters:
			fptTopLeft=Input fpoint identifying the top-left corner of the rectangle
			fptBottomRight=Input fpoint identifying the bottom-right corner of the rectangle
			vX=Output vector containing the X coordinates of all points in the rectangele, paired with vY and vIndex
			vY=Output vector containing the Y coordinates of all points in the rectangele, paired with vX and vIndex
			vIndex=Output vector containing the row index (0 based) into the Curve's X and Y data sets, paired with vX and vY
		Return:
			Returns the number of data points found within the rectangle (0,1,2,3...) on success and returns a
			negative integer on failure. Also returns the coordinates and index of all points within the rectangle.
	*/
	int GetRectPoints( fpoint& fptTopLeft, fpoint& fptBottomRight, vector<double>& vX, vector<double>& vY, vector<int>& vIndex ); // Find all the points in a Curve which fall on or within a specified rectangle.
 	/**
 		Example:
 			void run_GetSourceRange()
			{
				// Assumes Data1_A(X) and Data1_B(Y) exist with the following data:
				// Data1_B={1,2,3,4,5,6,7,8,9,10}
				// Data1_A={1,2,3,4,5,6,7,8,9,10};
				Curve crv("Data1_B");
				int nLow, nUp;
				crv.SetLowerBound(1);
				crv.SetUpperBound(8);
				bool bOK = crv.GetSourceRange(nLow, nUp);
				out_int("bOK = ", bOK);
			}
	*/
	bool	GetSourceRange(int &nLower, int &nUpper);
	
	/**
			It copies x values from cbSource.
		Example:
			// The example assumes that the worksheet "Data1" exists with four columns
			// A, B, C, D, and some values in them.
			Curve	crvData("data1_a", "data1_b");
			Curve	crvBaseline("data1_c", "data1_d");
			
			BOOL	bOK = crvBaseline.CopyX(crvData);
			out_int("OK = ", bOK);
		Parameters:
			cbSource=the source curve
		Return:
			TRUE for success, otherwise FALSE.
	*/
	bool	CopyX(curvebase &cbSource);
	
	
	/**
		Example:
			void run_CopyData()
			{
				// Assumes Data1_A(X) and Data1_B(Y) with the following data:
				// Data1_B={1,2,3,4,5,6,7,8,9,10}
				// Data1_A={1,2,3,4,5,6,7,8,9,10};
				Curve crv("Data1_A", "Data1_B");
				vector vDatax;
				vector vDatay;
				bool bOK = crv.CopyData(vDatax, vDatay);
				out_int("bOK = ", bOK);
			}
	*/
	bool	CopyData(vector& vx, vector& vy, vector& yWeight = NULL, vector& xWeight = NULL);

};


















/** >Composite Data Types
		An Origin C Curve is comprised of a Y Dataset and typically (but not necessarily)
		an associated X Dataset. For example, a data set plotted against row numbers
		will not have an associated X data set. An Origin C Curve object can easily be
		plotted using methods of the GraphLayer class. The Curve class is derived from
		the curvebase, and vectorbase classes from which it inherits methods and
		properties.
	Example:
		// Assumes Data1_A and Data1_B exist and contain data 
		Dataset ds1("Data1_A"), ds2("Data1_B");
		Curve crvCopy( ds1, ds2 );
		crvCopy.Sort(); // Does not effect ds1, ds2
*/ 
class Curve : public curvebase
{
public:
	
	/**
			Default constructor for Curve class.
		Example:
			// Assumes Data1_A and Data1_B exist and contain data
			Curve crv; // Use default constructor to create unattached Origin C Curve object
			crv.Attach( "Data1_A", "Data1_B" ); // Attach Origin C Curve object to internal Origin data sets
			crv.Sort(); // Does effect Data1_A and Data1_B
		SeeAlso:
			Curve::Attach, Curve::Detach
	*/
	Curve(); // Default constructor for Curve class.

	/**
			Copy constructor for Curve class. The original Y data set is copied into a new Curve object and
			is then associated with a copy of the original X data set. The Datasets of the original Curve
			object are not effected by operations on the copy Curve. 
		Example:
			// Assumes Data1_A and Data1_B exist and contain data
			Dataset ds1("Data1_A"), ds2("Data1_B");
			Curve crv1( ds1, ds2 );
			Curve crv2( crv1 );
			crv2.Sort(); // Does not effect ds1, ds2
		Parameters:
			crvOriginal=Curve object which is copied
		SeeAlso:
			Curve::Attach, Curve::Detach
	*/
	Curve(Curve crvOriginal); // Copy constructor for Curve class.

	/**
			Constructor for Curve class. The Y data set is specified by name and, if it exists, the Y data
			set's internally associated X data set is automatically used for the X data set. Otherwise, row numbers
			are used for the X data set. Operations on the Curve object do effect the X and/or the specified Y data
			set(s).
		Example:
			// Assumes Data1_B exists and contains data
			Curve crv( "Data1_B" );
			crv.Sort(); // Does effect Data1_B
		Parameters:
			lpcszYData=Name of Y Dataset
		SeeAlso:
			Curve::Attach, Curve::Detach
	*/
	Curve(LPCSTR lpcszYData); // Construct a Curve from a Y data set name and an associated X data set.

	/**
			Constructor for Curve class. Both the X and Y data sets are specified by name. Operations on the Curve
			object do effect the specified X and Y data sets.
		Example:
			// Assumes Data1_A and Data1_B exist and contain data
			Curve crv( "Data1_A", "Data1_B" ); // Attach Origin C Curve object to internal Origin data sets
			crv.Sort(); // Does effect Data1_A and Data1_B
		Parameters:
			lpcszXData=Name of X Dataset
			lpcszYData=Name of Y Dataset
		SeeAlso:
			Curve::Attach, Curve::Detach
	*/
	Curve(LPCSTR lpcszXData, LPCSTR lpcszYData); // Construct a Curve from X and Y data set names.

	/**
			Constructor for Curve class. Both the X and Y data sets are specified by Origin C Dataset objects
			which are attached to internal Origin data sets. Operations on the Curve object do not effect the
			associated Origin X and Y data sets.
		Example:
			// Assumes Data1_A and Data1_B exist and contain data 
			Dataset ds1("Data1_A"), ds2("Data1_B");
			Curve crv( ds1, ds2 );
			crv.Sort(); // Does not effect ds1, ds2
		Parameters:
			dsX=Origin C Dataset object attached to internal Origin X data set
			dsY=Origin C Dataset object attached to internal Origin Y data set
		SeeAlso:
			Curve::Attach, Curve::Detach
	*/
	Curve(Dataset dsX, Dataset dsY); // Construct a Curve from X and Y Datasets.

	/**
			Constructor for Curve class. The X and Y data sets are specified by column number in an Origin C
			worksheet object. Operations on the Curve object do effect the associated Origin X and Y worksheet
			columns (data sets).
		Example:
			// Assumes Data1_A and Data1_B exist and contain data
			Worksheet wks("Data1");
			Curve crv( wks, 0, 1 ); // Data1 worksheet and columns 1 (X) and 2 (Y)
			crv.Sort(); // Does effect columns 1 and 2 in wks
		Parameters:
			wks=Origin C Dataset object attached to an internal Origin worksheet
			nColX=0 based offset or column number of X column (data set)
			nColY=0 based offset or column number of Y column (data set)
		SeeAlso:
			Curve::Attach, Curve::Detach
	*/
	Curve(Worksheet & wks, int nColX, int nColY); // Construct a Curve from a Worksheet and X and Y column numbers.

	/**
			Constructor for Curve class. The Y data set is specified by column number in an Origin C
			worksheet object and, if it exists, the Y column's internally associated X column is
			automatically used for the X column. Otherwise, row numbers are used for the X data set.
			Operations on the Curve object do effect the X and/or the specified Y column(s).
		Example:
			// Assumes Data1_B exists and contains data
			Worksheet wks("Data1");
			Curve crv( wks, 1 ); // Data1 worksheet and column 2 (Y)
			crv.Sort(); // Does effect column 2 in wks
		Parameters:
			wks=Origin C Dataset object attached to an internal Origin worksheet
			nColY=0 based offset or column number of Y column (data set)
		SeeAlso:
			Curve::Attach, Curve::Detach
	*/
	Curve(Worksheet & wks, int nColY); // Construct a Curve from a Worksheet, a Y column number, and an associated X column.

	/**
			Constructor for Curve class. The X and Y data sets are specified by an Origin C DataPlot object.
			Operations on the Curve object do effect the associated data plot and underlying data sets in
			Origin.
		Example:
			// Assumes Graph1 window with one or more data plots is active in Origin
			GraphLayer	gl = Project.ActiveLayer(); // Get active layer in project file
			if(gl)                                  // If valid graph layer...
			{
				DataPlot dp = gl.DataPlots(0);      // Get first data plot in graph layer
				if(dp)                              // If valid DataPlot...
				{
					Curve crv(dp);                  // Get Curve from DataPlot
					crv.Sort();                     // Does effect DataPlot
				}
			}
		Parameters:
			DataPlot=Origin C DataPlot object attached to an internal Origin data plot
		SeeAlso:
			Curve::Attach, Curve::Detach
	*/
	Curve(DataPlot& dp); // Construct a Curve from a DataPlot
	
	/**
			It creates a temporary curve object from the supplied source.
		Example:
		Paramaters:
			cv = [in] source curve
			nNumMissingInCopy = [output] number of missing values in the created curve.
			nSrcOffset = index in source curve that the result curve's 1st point is copied from
			dwOptions = a combination of values from the enumeration:
					enum {
						CURVECOPY_SCAN_OVER_MISSING_FROM_LEFT	= 0x00000001,   // if on, it will scan from the left (see the parameter nLower) until it finds the first nonmissing value
						CURVECOPY_SCAN_OVER_MISSING_FROM_RIGHT	= 0x00000002,   // if on, it will scan back from the right (see the parameter nUpper) until it finds the first nonmissing value
						CURVECOPY_SKIP_MISSING_INSIDE			= 0x00000004,   // if on, it will not copy any missing values found in the middle
						CURVECOPY_REPLACE_MISSING_INSIDE		= 0x00000008,   // if on, any missing values in the middle will be replaced with the average of neighboring points (not used if the bit CURVECOPY_SKIP_MISSING_INSIDE  is on)
					};
			nLower = lower index to start from or -1 to start from the lower bound.
			nUpper = upper index to end at, or -1 to end at the upper bound.
	*/
	Curve(curvebase &cv, int &nNumMissingInCopy, int &nSrcOffset, DWORD dwOptions = 0, int nLower = -1, int nUpper = -1);


	/**
			Attach an Origin C Curve object to an internal Origin Y data set and its associated X data set. The Y data
			set is specified by name and, if it exists, the Y data set's internally associated X data set is automatically
			used for the X data set. Otherwise, row numbers are used for the X data set. Operations on the Curve object
			do effect the X and/or the specified Y data set(s).
		Example:
			// Assumes Data1_B exists and contains data
			Curve crv;               // Declare Curve object
			crv.Attach( "Data1_B" ); // Attach to Y data set by name
			crv.Sort();              // Does effect Data1_B
		Parameters:
			lpcszYData=Name of Y Dataset
		Return:
			Returns TRUE on successful exit and FALSE on error.
		SeeAlso:
			Curve::Curve, Curve::Detach
	*/
	BOOL	Attach(LPCSTR lpcszYData); // Attach an Origin C Curve object to an internal Origin Y data set and its associated X data set.

	/**
			Attach an Origin C Curve object to internal Origin X and Y data sets. Both the X and Y data sets are specified
			by name. Operations on the Curve object do effect the specified X and Y data sets.
		Example:
			// Assumes Data1_A and Data1_B exist and contain data
			Curve crv;                          // Declare Curve object
			crv.Attach( "Data1_A", "Data1_B" ); // Attach Curve object to X and Y data sets by name
			crv.Sort();                         // Does effect data sets Data1_A and Data1_B
		Parameters:
			lpcszXData=Name of X Dataset
			lpcszYData=Name of Y Dataset
		Return:
			Returns TRUE on successful exit and FALSE on error.
		SeeAlso:
			Curve::Curve, Curve::Detach
	*/
	BOOL	Attach(LPCSTR lpcszXData, LPCSTR lpcszYData); // Attach an Origin C Curve object to internal Origin X and Y data sets.

	/**
			Detach an Origin C Curve object from internal Origin data sets. The Curve object can only
			be attached to one pair of internal Origin data sets at a time but it may be sequentially
			detached and re-attached as many times as desired.
		Example:
			// Assumes Data1_A, Data1_B, Data2_A, and Data2_B exist and contain data
			Curve crv( "Data1_A", "Data1_B" );  // Declare Curve object and attach to X and Y data sets
			crv.Sort();
			crv.Detach();                       // Detach Curve Object from X and Y data sets 
			crv.Attach( "Data2_A", "Data2_B" ); // Re-Attach Curve object to different X and Y data sets
			crv.Sort();
		Return:
			Returns TRUE on successful exit and FALSE on error.
		SeeAlso:
			Curve::Attach, Curve::Curve
	*/
	BOOL	Detach(); // Detach an Origin C Curve object from internal Origin data sets.
	
	/**
			Attach an Origin C Curve object to internal Origin X and Y datasets.
			The X and Y data sets are specified by column number in an Origin C
			worksheet object. Operations on the Curve object do affect the associated Origin X and Y worksheet
			columns (data sets).
		Example:
			// Assumes Data1_A and Data1_B exist and contain data
			Worksheet wks("Data1");
			Curve crv; // Data1 worksheet and columns 1 (X) and 2 (Y)
			crv.Attach( wks, 0, 1 ); // Data1 worksheet and columns 1 (X) and 2 (Y)
			crv.Sort(); // Does affect columns 1 and 2 in wks
		Parameters:
			wks=Origin C Dataset object attached to an internal Origin worksheet
			nColX=0 based offset or column number of X column (data set)
			nColY=0 based offset or column number of Y column (data set)
		Return:
			Returns TRUE on successful exit and FALSE on error.
	*/
	BOOL	Attach(Worksheet & wks, int nColX, int nColY);
	
	/**
			Attach an Origin C Curve object to internal Origin X and Y datasets.
			The Y data set is specified by the column number in an Origin C
			worksheet object. The Y data set's internally associated X data set is automatically
			used for the X data set. Otherwise, row numbers are used for the X data set.
			Operations on the Curve object do affect the associated Origin X and Y worksheet
			columns (data sets).
		Example:
			// Assumes Data1_A and Data1_B exist and contain data
			Worksheet wks("Data1");
			Curve crv; // Data1 worksheet and columns 1 (X) and 2 (Y)
			crv.Attach( wks, 1 ); // Data1 worksheet and column 2 (Y)
			crv.Sort(); // Does affect columns 1 and 2 in wks
		Parameters:
			wks=Origin C Dataset object attached to an internal Origin worksheet
			nColY=0 based offset or column number of Y column (data set)
		Return:
			Returns TRUE on successful exit and FALSE on error.
	*/
	BOOL	Attach(Worksheet & wks, int nColY);
	/**
			Create a temporary (or permanent) Origin data set and attach the
			Dataset object to it. If Option=1 is specified and data set is not
			destroyed by calling the Dataset::Destroy method the data set will
			remain in Origin after the Origin C function completes execution. 
		Example:
			int ii;
			{
				LT_execute("list s;");
				Dataset	ds0;
				ds0.Create(3);         // Size=3 & Option=0 by default (create and attach to temporary data set)
				for(ii = 0; ii < 3; ii++)
					ds0[ii] = ii;
				LT_execute("list s;"); // Note new ds0 TEMP_ data set
			}
			LT_execute("list s;");     // Out of ds0's scope, note new ds0 TEMP_ data set is destroyed
	
			Dataset	ds1;
			ds1.Create(3,1);           // Size=3 & Option=1 (create and attach to a second data set that is not temporary)
			for(ii = 0; ii < 3; ii++)
				ds1[ii] = ii;
			LT_execute("list s;");     // Note new ds1 TEMP_ data set
			ds1.Destroy();             // Destroy ds1 TEMP_ data set (comment out this line and TEMP_ data set does not get deleted)
			LT_execute("list s;");     // Note new ds1 TEMP_ data set is destroyed (or not if above line is commented out)
		Parameters:
			Size=Size of the data set
			Option=0 (default) causes temporary Origin data set to be automatically deleted when program control exits scope
				of Dataset object, Option=1 causes data set to not be deleted unless user calls Dataset::Destroy method
		Return:
			Returns TRUE on successful exit and FALSE on error.
		SeeAlso:
			Dataset::Destroy, Dataset::Detach, Dataset::Dataset, Dataset::Attach 
	*/
	BOOL	Create(int Size, UINT Option = 0); // Create an internal Origin data set (may or may not be temporary).

	/**
			Delete (destroy) an Origin data set created using the Dataset::Create
			method. For data sets not created by the Dataset::Create method the
			Destroy method functions identically to the Dataset::Detach method.
		Example:
			// Worksheet column Data1_A must exist prior to execution
			int ii;
			Dataset	ds1;
			ds1.Create(3,1);           // Create data set with Size=3 & Option=1 (not a temporary data set)
			for(ii = 0; ii < 3; ii++)
				ds1[ii] = ii;
			LT_execute("list s;");     // Note new ds1 TEMP_ data set
			ds1.Destroy();             // Destroy ds1 TEMP_ data set
			LT_execute("list s;");     // Note new ds1 TEMP_ data set is destroyed
		
			Dataset	ds2("Data1_A");    // Construct and attach to pre-existing Origin data set
			ds2.Destroy();             // Detaches ds2 from Data1_A but does not delete pre-existing data set from Origin
			LT_execute("list s;");     // Note ds2 is an Invalid Object but Data1_A still exists 
		SeeAlso:
			Dataset::Detach, Dataset::Attach, Dataset::Create 
	*/
	void 	Destroy(); // Detach the Origin C Dataset object and Destroy (delete) the internal Origin data set.





};

#endif//_CURVE_H
