using System;
using System.Collections;
using System.Text;
namespace DrawGraph
{
	/// 
	/// enumeration used to indicate which type of data will be plotted.
	/// 
	public enum SampleType
	{
		/// 
		/// Designates the "Time" property will be used
		/// 
		Time,
		/// 
		/// Designates the "Position" property will be used
		/// 
		Position,
		/// 
		/// Designates the Instantaneous Velocity property will be used
		/// 
		VelocityInst,
		/// 
		/// Designates the "Time since start" property will be used
		/// 
		TimeDiff,
		/// 
		/// Designates the Average Velocity property will be used
		/// 
		VelocityAvg
	};
	/// 
	/// A simple storage class to maintain an individual sampling of data
	/// 
	public class Sample : System.Object
	{
		private DateTime	_time;
		private double		_position;
		private double		_velocity;
		/// 
		/// The time of the sample
		/// 
		public DateTime Time
		{
			get { return _time; }
			set { _time = value; }
		}
		/// 
		/// The position at sample time
		/// 
		public double Position
		{
			get { return _position; }
			set { _position = value; }
		}
		/// 
		/// The instantaneous velocity at sample time
		/// 
		public double Velocity
		{
			get { return _velocity; }
			set { _velocity = value; }
		}
	}
	/// 
	/// A collection class to maintain a set of samples
	/// 
	[Serializable]
	public class SamplePointList : IPointList
	{
		/// 
		/// Determines what data type gets plotted for the X values
		/// 
		public SampleType XType;
		/// 
		/// Determines what data type gets plotted for the Y values
		/// 
		public SampleType YType;
		// Stores the collection of samples
		private ArrayList list;
		/// 
		/// Indexer: get the Sample instance at the specified ordinal position in the list
		/// 
		/// The ordinal position in the list of samples
		/// Returns a  instance containing the
		/// data specified by  and 
		/// 
		public PointPair this[int index]
		{
			get
			{
				PointPair pt = new PointPair();
				Sample sample = (Sample) list[index];
				pt.X = GetValue( sample, XType );
				pt.Y = GetValue( sample, YType );
				return pt;
			}
		}
		/// 
		/// Gets the number of samples in the collection
		/// 
		public int Count
		{
			get { return list.Count; }
		}
		/// 
		/// Get the specified data type from the specified sample
		/// 
		/// The sample instance of interest
		/// The data type to be extracted from the sample
		/// A double value representing the requested data
		public double GetValue( Sample sample, SampleType type )
		{
			switch ( type )
			{
				case SampleType.Position:
					return sample.Position;
				case SampleType.Time:
					return sample.Time.ToOADate();
				case SampleType.TimeDiff:
					return sample.Time.ToOADate() - ( (Sample)list[0] ).Time.ToOADate();
				case SampleType.VelocityAvg:
					double timeDiff = sample.Time.ToOADate() - ( (Sample)list[0] ).Time.ToOADate();
					if ( timeDiff <= 0 )
						return PointPair.Missing;
					else
						return ( sample.Position - ( (Sample)list[0] ).Position ) / timeDiff;
				case SampleType.VelocityInst:
					return sample.Velocity;
				default:
					return PointPair.Missing;
			}
		}
		/// 
		/// Append a sample to the collection
		/// 
		/// The sample to append
		/// The ordinal position at which the sample was added
		public int Add( Sample sample )
		{
			return list.Add( sample );
		}
		// generic Clone: just call the typesafe version
		object ICloneable.Clone()
		{
			return this.Clone();
		}
		/// 
		/// typesafe clone method
		/// 
		/// A new cloned SamplePointList.  This returns a copy of the structure,
		/// but it does not duplicate the data (it just keeps a reference to the original)
		/// 
		public SamplePointList Clone()
		{
			return new SamplePointList( this );
		}
		/// 
		/// default constructor
		/// 
		public SamplePointList()
		{
			XType = SampleType.Time;
			YType = SampleType.Position;
			list = new ArrayList();
		}
		/// 
		/// copy constructor -- this returns a copy of the structure,
		/// but it does not duplicate the data (it just keeps a reference to the original)
		/// 
		/// The SamplePointList to be copied
		public SamplePointList( SamplePointList rhs )
		{
			XType = rhs.XType;
			YType = rhs.YType;
			// Don't duplicate the data values, just copy the reference to the ArrayList
			this.list = rhs.list;
			//foreach ( Sample sample in rhs )
			//	list.Add( sample );
		}
	}
}