/*
ScPl - A plotting library for .NET

PointPlot.cs
Copyright (C) 2003
Matt Howlett, Paolo Pierini

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
   
2. Redistributions in binary form must reproduce the following text in 
   the documentation and / or other materials provided with the 
   distribution: 
   
   "This product includes software developed as part of 
   the ScPl plotting library project available from: 
   http://www.netcontrols.org/scpl/" 

------------------------------------------------------------------------

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

$Id: PointPlot.cs,v 1.23 2004/04/25 12:58:06 mhowlett Exp $

*/

using System;
using System.Drawing;

namespace scpl
{
	/// <summary>
	/// Provides ability to trace marker plots.
	/// </summary>
	public class PointPlot : ISequencePlot
	{
		/// <summary>
		/// The protected marker member.
		/// </summary>
		protected Marker marker_;

		#region Constructors
		/// <summary>
		/// Constructor for the marker plot.
		/// </summary>
		public PointPlot()
		{
			marker_ = new Marker();
		}
		/// <summary>
		/// Constructor for the marker plot.
		/// </summary>
		/// <param name="marker">The marker to use.</param>
		public PointPlot( Marker marker )
		{
			marker_ = marker;
		}
		#endregion

		#region DataSource
		public object DataSource
		{
			get
			{
				return this.dataSource_;
			}
			set
			{
				this.dataSource_ = value;
			}
		}
		private object dataSource_ = null;
		#endregion
		#region ValueData
		public object ValueData
		{
			get
			{
				return this.valueData_;
			}
			set
			{
				this.valueData_ = value;
			}
		}
		private object valueData_ = null;
		#endregion		
		#region AbscissaData
		public object AbscissaData
		{
			get
			{
				return this.abscissaData_;
			}
			set
			{
				this.abscissaData_ = value;
			}
		}
		private object abscissaData_ = null;
		#endregion
		#region DataMember
		public string DataMember
		{
			get
			{
				return this.dataMember_;
			}
			set
			{
				this.dataMember_ = value;
			}
		}
		protected string dataMember_ = null;
		#endregion

		#region Draw
		/// <summary>
		/// Renders the marker plot.
		/// </summary>
		/// <param name="g">The Graphics surface.</param>
		/// <param name="xAxis">The X axis where the trace plot is attached to.</param>
		/// <param name="yAxis">The Y axis where the trace plot is attached to.</param>
		public virtual void Draw( Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis )
		{
			SequenceAdapter data_ = 
				new SequenceAdapter( this.DataSource, this.DataMember, this.ValueData, this.AbscissaData );

			for (int i=0; i<data_.Count; ++i)
			{
				if ( !Double.IsNaN(data_[i].X) && !Double.IsNaN(data_[i].Y) )
				{
					PointF xPos = xAxis.WorldToPhysical( data_[i].X, false);
					PointF yPos = yAxis.WorldToPhysical( data_[i].Y, false);
					marker_.Draw(g,(int)xPos.X, (int)yPos.Y);
					if (marker_.DropLine)
					{
						PointD yMin = new PointD(data_[i].X,Math.Max(0.0f,xAxis.Axis.WorldMin));
						PointF yStart = yAxis.WorldToPhysical( yMin.Y,false);
						g.DrawLine(marker_.Pen,new Point((int)xPos.X,(int)yStart.Y),new Point((int)xPos.X,(int)yPos.Y));
					}
				}
			}
		}
		#endregion
		#region SuggestXAxis
		/// <summary>
		/// Provides a hint for the X axis.
		/// </summary>
		/// <returns>The X axis.</returns>
		public Axis SuggestXAxis()
		{
			SequenceAdapter data_ = 
				new SequenceAdapter( this.DataSource, this.DataMember, this.ValueData, this.AbscissaData );

			return data_.SuggestXAxis();
		}
		#endregion
		#region SuggestYAxis
		/// <summary>
		/// Provides a hint for the Y axis.
		/// </summary>
		/// <returns>The Y axis.</returns>
		public Axis SuggestYAxis()
		{
			SequenceAdapter data_ = 
				new SequenceAdapter( this.DataSource, this.DataMember, this.ValueData, this.AbscissaData );

			return data_.SuggestYAxis();
		}
		#endregion

		/// <summary>
		/// The protected label member.
		/// </summary>
		protected string label_ = "";
		/// <summary>
		/// The trace label.
		/// </summary>
		public string Label
		{
			get
			{
				return label_;
			}
			set
			{
				this.label_ = value;
			}
		}

		/// <summary>
		/// Method used to draw the line in the plot legend.
		/// </summary>
		/// <param name="g">The Graphics surface.</param>
		/// <param name="startEnd">The RectangleF storing the position of the legend line.</param>
		public void DrawLegendLine( Graphics g, RectangleF startEnd )
		{
			// it looks silly drawing two markers - now only draw one.
			/*
			marker_.Draw( g, (int)startEnd.Left+4, (int)((startEnd.Top + startEnd.Bottom)/2.0f) );
			marker_.Draw( g, (int)startEnd.Right-4, (int)((startEnd.Top + startEnd.Bottom)/2.0f) );
			*/

			marker_.Draw( g, (int)((startEnd.Left+startEnd.Right)/2.0f), (int)((startEnd.Top + startEnd.Bottom)/2.0f) );
		}

		#region get/set Marker
		/// <summary>
		/// The Marker object used for the plot.
		/// </summary>
		public Marker Marker
		{
			set
			{
				marker_ = value;
			}
			get
			{
				return marker_;
			}
		}
		#endregion

		#region ShowLegendLine
		public bool ShowLegendLine
		{
			get
			{
				return showLegendLine_;
			}
			set
			{
				this.showLegendLine_ = value;
			}
		}
		private bool showLegendLine_ = true;
		#endregion

	}
}