//============================================================================
//ZedGraph Class Library - A Flexible Charting Library for .Net
//Copyright ?2005 John Champion and Jerry Vos
//
//This library is free software; you can redistribute it and/or
//modify it under the terms of the GNU Lesser General Public
//License as published by the Free Software Foundation; either
//version 2.1 of the License, or (at your option) any later version.
//
//This library is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//Lesser General Public License for more details.
//
//You should have received a copy of the GNU Lesser General Public
//License along with this library; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//=============================================================================
using System;
using System.Collections;
using System.Text;
using System.Drawing;
namespace DrawGraph
{
	/// 
	/// An enum used to specify the X or Y data type of interest -- see
	///  and .
	/// 
	public enum PerfDataType
	{
		/// 
		/// The time (seconds) at which these data are measured
		/// 
		Time,
		/// 
		/// The distance traveled, meters
		/// 
		Distance,
		/// 
		/// The instantaneous velocity, meters per second
		/// 
		Velocity,
		/// 
		/// The instantaneous acceleration, meters per second squared
		/// 
		Acceleration
	};
	/// 
	/// Sample data structure containing a variety of data values, in this case the values
	/// are related in that they correspond to the same time value.
	/// 
	public class PerformanceData
	{
		/// 
		/// The time (seconds) at which these data are measured
		/// 
		public double	time;
		/// 
		/// The distance traveled, meters
		/// 
		public double	distance;
		/// 
		/// The instantaneous velocity, meters per second
		/// 
		public double	velocity;
		/// 
		/// The instantaneous acceleration, meters per second squared
		/// 
		public double	acceleration;
		/// 
		/// Constructor that specifies each data value in the PerformanceData struct
		/// 
		/// The time (seconds) at which these data are measured
		/// The distance traveled, meters
		/// The instantaneous velocity, meters per second
		/// The instantaneous acceleration, meters per second squared
		public PerformanceData( double time, double distance, double velocity, double acceleration )
		{
			this.time = time;
			this.distance = distance;
			this.velocity = velocity;
			this.acceleration = acceleration;
		}
		/// 
		/// Gets or sets the data value as specified by the  enum
		/// 
		/// The required data value type
		public double this[ PerfDataType type ]
		{
			get
			{
				switch( type )
				{
					default:
					case PerfDataType.Time:
						return time;
					case PerfDataType.Distance:
						return distance;
					case PerfDataType.Velocity:
						return velocity;
					case PerfDataType.Acceleration:
						return acceleration;
				}
			}
			set
			{
				switch( type )
				{
					case PerfDataType.Time:
						time = value;
						break;
					case PerfDataType.Distance:
						distance = value;
						break;
					case PerfDataType.Velocity:
						velocity = value;
						break;
					case PerfDataType.Acceleration:
						acceleration = value;
						break;
				}
			}
		}
	}
	/// 
	/// A sample class that holds an internal collection, and implements the
	///  interface so that it can be used by ZedGraph as curve data.
	/// 
	/// 
	/// This particular class efficiently implements the data storage so that the class
	/// can be cloned without duplicating the data points.  For example, you can create
	/// a , populate it with values, and set
	///  =  and
	///  = .
	/// You can then clone this  to a new one, and set
	///  = .
	/// Each of these 's can then be used as an
	///  argument,
	/// thereby plotting a distance vs time curve and a velocity vs time curve.  There
	/// will still be only one copy of the data in memory.
	/// 
	[Serializable]
	public class SampleMultiPointList : IPointList
	{
		/// 
		/// This is where the data are stored.  Duplicating the 
		/// copies the reference to this , but does not actually duplicate
		/// the data.
		/// 
		private ArrayList	DataCollection;
		/// 
		/// Determines what X data will be returned by the indexer of this list.
		/// 
		public PerfDataType XData;
		/// 
		/// Determines what Y data will be returned by the indexer of this list.
		/// 
		public PerfDataType YData;
		/// 
		/// Default constructor
		/// 
		public SampleMultiPointList()
		{
			XData = PerfDataType.Time;
			YData = PerfDataType.Distance;
			DataCollection = new ArrayList();
		}
		/// 
		/// The Copy Constructor.  This method does NOT duplicate the data, it merely makes
		/// another "Window" into the same collection.  You can make multiple copies and
		/// set the  and/or  properties to different
		/// values to plot different data, while maintaining only one copy of the original values.
		/// 
		/// The  from which to copy
		public SampleMultiPointList( SampleMultiPointList rhs )
		{
			DataCollection = rhs.DataCollection;
			XData = rhs.XData;
			YData = rhs.YData;
		}
		/// 
		/// Implement the  interface in a typesafe manner by just
		/// calling the typed version of 
		/// 
		/// A deep copy of this object
		object ICloneable.Clone()
		{
			return this.Clone();
		}
		/// 
		/// Typesafe, deep-copy clone method.
		/// 
		/// A new, independent copy of this class
		public SampleMultiPointList Clone()
		{
			return new SampleMultiPointList( this );
		}
		/// 
		/// Indexer to access the data.  This gets the appropriate data and converts to
		/// the  struct that is compatible with ZedGraph.  The
		/// actual data returned depends on the values of  and
		/// .
		/// 
		/// The ordinal position of the desired point in the list
		/// A  corresponding to the specified ordinal data position
		public PointPair this[ int index ]
		{
			get
			{
				double xVal, yVal;
				if ( index >= 0 && index < this.Count )
				{
					// grab the specified PerformanceData struct
					PerformanceData perfData = (PerformanceData) DataCollection[index];
					// extract the values from the struct according to the user-set
					// enum values of XData and YData
					xVal = perfData[XData];
					yVal = perfData[YData];
				}
				else
				{
					xVal = PointPair.Missing;
					yVal = PointPair.Missing;
				}
				// insert the values into a pointpair and return
				return new PointPair( xVal, yVal, PointPair.Missing, null );
			}
		}
		/// 
		/// Gets the number of data points in the collection
		/// 
		public int Count
		{
			get { return DataCollection.Count; }
		}
		/// 
		/// Adds the specified  struct to the end of the collection.
		/// 
		/// A  struct to be added
		/// The ordinal position in the collection where the values were added
		public int Add( PerformanceData perfData )
		{
			return DataCollection.Add( perfData );
		}
		/// 
		/// Remove the  struct from the list at the specified
		/// ordinal location.
		/// 
		/// The ordinal location of the 
		/// struct to be removed
		public void RemoveAt( int index )
		{
			DataCollection.RemoveAt( index );
		}
		/// 
		/// Insert the specified  struct into the list at
		/// the specified ordinal location.
		/// 
		/// The ordinal location at which to insert
		/// The  struct to be inserted
		public void Insert( int index, PerformanceData perfData )
		{
			DataCollection.Insert( index, perfData );
		}
	}
}