//============================================================================
//ZedGraph Class Library - A Flexible Line Graph/Bar Graph Library in C#
//Copyright ?2004  John Champion
//
//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.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.Runtime.Serialization;
using System.Security.Permissions;
namespace DrawGraph
{
	/// 
	/// An abstract base class that represents a text object on the graph.  A list of
	///  objects is maintained by the
	///  collection class.
	/// 
	/// 
	///  John Champion 
	///  $Revision: 3.1 $ $Date: 2006/06/24 20:26:44 $ 
	[Serializable]
	abstract public class GraphObj : ISerializable, ICloneable
	{
	#region Fields
		/// 
		/// Protected field that stores the location of this .
		/// Use the public property  to access this value.
		/// 
		protected Location _location;
		/// 
		/// Protected field that determines whether or not this 
		/// is visible in the graph.  Use the public property  to
		/// access this value.
		/// 
		protected bool _isVisible;
		
		/// 
		/// Protected field that determines whether or not the rendering of this 
		/// will be clipped to the ChartRect.  Use the public property  to
		/// access this value.
		/// 
		protected bool _isClippedToChartRect;
		
		/// 
		/// A tag object for use by the user.  This can be used to store additional
		/// information associated with the .  ZedGraph does
		/// not use this value for any purpose.
		/// 
		/// 
		/// Note that, if you are going to Serialize ZedGraph data, then any type
		/// that you store in  must be a serializable type (or
		/// it will cause an exception).
		/// 
		public object Tag;
		/// 
		/// Internal field that determines the z-order "depth" of this
		/// item relative to other graphic objects.  Use the public property
		///  to access this value.
		/// 
		internal ZOrder _zOrder;
		/// 
		/// Internal field that stores the hyperlink information for this object.
		/// 
		internal Link _link;
	#endregion
	#region Defaults
		/// 
		/// A simple struct that defines the
		/// default property values for the  class.
		/// 
		public struct Default
		{
			// Default text item properties
			/// 
			/// Default value for the vertical 
			/// text alignment ( property).
			/// This is specified
			/// using the  enum type.
			/// 
			public static AlignV AlignV = AlignV.Center;
			/// 
			/// Default value for the horizontal 
			/// text alignment ( property).
			/// This is specified
			/// using the  enum type.
			/// 
			public static AlignH AlignH = AlignH.Center;
			/// 
			/// The default coordinate system to be used for defining the
			///  location coordinates
			/// ( property).
			/// 
			///  The coordinate system is defined with the 
			/// enum
			public static CoordType CoordFrame = CoordType.AxisXYScale;
			/// 
			/// The default value for .
			/// 
			public static bool IsClippedToChartRect = false;
		}
	#endregion
	#region Properties
		/// 
		/// The  struct that describes the location
		/// for this .
		/// 
		public Location Location
		{
			get { return _location; }
			set { _location = value; }
		}
		/// 
		/// Gets or sets a value that determines the z-order "depth" of this
		/// item relative to other graphic objects.
		/// 
		/// Note that this controls the z-order with respect to
		/// other elements such as 's, 
		/// objects, etc.  The order of  objects having
		/// the same  value is controlled by their order in
		/// the .  The first 
		/// in the list is drawn in front of other 
		/// objects having the same  value.
		public ZOrder ZOrder
		{
			get { return _zOrder; }
			set { _zOrder = value; }
		}
		
		/// 
		/// Gets or sets a value that determines if this  will be
		/// visible in the graph.  true displays the item, false hides it.
		/// 
		public bool IsVisible
		{
			get { return _isVisible; }
			set { _isVisible = value; }
		}
		/// 
		/// Gets or sets a value that determines whether or not the rendering of this 
		/// will be clipped to the .
		/// 
		/// true to clip the  to the  bounds,
		/// false to leave it unclipped.
		public bool IsClippedToChartRect
		{
			get { return _isClippedToChartRect; }
			set { _isClippedToChartRect = value; }
		}
		/// 
		/// Gets or sets the hyperlink information for this .
		/// 
		// /// 
		public Link Link
		{
			get { return _link; }
			set { _link = value; }
		}
		/// 
		/// true if the  of this object is set to put it in front
		/// of the  data points.
		/// 
		public bool IsInFrontOfData
		{
			get
			{
				return	_zOrder == ZOrder.A_InFront ||
							_zOrder == ZOrder.B_BehindLegend ||
							_zOrder == ZOrder.C_BehindChartBorder;
			}
		}
	#endregion
	
	#region Constructors
		/// 
		/// Constructors for the  class.
		/// 
		/// 
		/// Default constructor that sets all  properties to default
		/// values as defined in the  class.
		/// 
		public GraphObj() :
			this( 0, 0, Default.CoordFrame, Default.AlignH, Default.AlignV )
		{
		}
		/// 
		/// Constructor that sets all  properties to default
		/// values as defined in the  class.
		/// 
		/// The x position of the text.  The units
		/// of this position are specified by the
		///  property.  The text will be
		/// aligned to this position based on the 
		/// property.
		/// The y position of the text.  The units
		/// of this position are specified by the
		///  property.  The text will be
		/// aligned to this position based on the
		///  property.
		public GraphObj( double x, double y ) :
			this( x, y, Default.CoordFrame, Default.AlignH, Default.AlignV )
		{
		}
		/// 
		/// Constructor that creates a  with the specified
		/// coordinates and all other properties to defaults as specified
		/// in the  class..
		/// 
		/// 
		/// The four coordinates define the starting point and ending point for
		/// 's, or the topleft and bottomright points for
		/// 's.  For 's that only require
		/// one point, the  and  values
		/// will be ignored.  The units of the coordinates are specified by the
		///  property.
		/// 
		/// The x position of the item.
		/// The y position of the item.
		/// The x2 position of the item.
		/// The x2 position of the item.
		public GraphObj( double x, double y, double x2, double y2 ) :
			this( x, y, x2, y2, Default.CoordFrame, Default.AlignH, Default.AlignV )
		{
		}
		/// 
		/// Constructor that creates a  with the specified
		/// position and .  Other properties are set to default
		/// values as defined in the  class.
		/// 
		/// 
		/// The two coordinates define the location point for the object.
		/// The units of the coordinates are specified by the
		///  property.
		/// 
		/// The x position of the item.  The item will be
		/// aligned to this position based on the 
		/// property.
		/// The y position of the item.  The item will be
		/// aligned to this position based on the
		///  property.
		/// The  enum value that
		/// indicates what type of coordinate system the x and y parameters are
		/// referenced to.
		public GraphObj( double x, double y, CoordType coordType ) :
			this( x, y, coordType, Default.AlignH, Default.AlignV )
		{
		}
		
		/// 
		/// Constructor that creates a  with the specified
		/// position, , , and .
		/// Other properties are set to default values as defined in the  class.
		/// 
		/// 
		/// The two coordinates define the location point for the object.
		/// The units of the coordinates are specified by the
		///  property.
		/// 
		/// The x position of the item.  The item will be
		/// aligned to this position based on the 
		/// property.
		/// The y position of the text.  The units
		/// of this position are specified by the
		///  property.  The text will be
		/// aligned to this position based on the
		///  property.
		/// The  enum value that
		/// indicates what type of coordinate system the x and y parameters are
		/// referenced to.
		/// The  enum that specifies
		/// the horizontal alignment of the object with respect to the (x,y) location
		/// The  enum that specifies
		/// the vertical alignment of the object with respect to the (x,y) location
		public GraphObj( double x, double y, CoordType coordType, AlignH alignH, AlignV alignV )
		{
			_isVisible = true;
			_isClippedToChartRect = Default.IsClippedToChartRect;
			this.Tag = null;
			_zOrder = ZOrder.A_InFront;
			_location = new Location( x, y, coordType, alignH, alignV );
			_link = new Link();
		}
		/// 
		/// Constructor that creates a  with the specified
		/// position, , , and .
		/// Other properties are set to default values as defined in the  class.
		/// 
		/// 
		/// The four coordinates define the starting point and ending point for
		/// 's, or the topleft and bottomright points for
		/// 's.  For 's that only require
		/// one point, the  and  values
		/// will be ignored.  The units of the coordinates are specified by the
		///  property.
		/// 
		/// The x position of the item.
		/// The y position of the item.
		/// The x2 position of the item.
		/// The x2 position of the item.
		/// The  enum value that
		/// indicates what type of coordinate system the x and y parameters are
		/// referenced to.
		/// The  enum that specifies
		/// the horizontal alignment of the object with respect to the (x,y) location
		/// The  enum that specifies
		/// the vertical alignment of the object with respect to the (x,y) location
		public GraphObj( double x, double y, double x2, double y2, CoordType coordType,
					AlignH alignH, AlignV alignV )
		{
			_isVisible = true;
			_isClippedToChartRect = Default.IsClippedToChartRect;
			this.Tag = null;
			_zOrder = ZOrder.A_InFront;
			_location = new Location( x, y, x2, y2, coordType, alignH, alignV );
			_link = new Link();
		}
		/// 
		/// The Copy Constructor
		/// 
		/// The  object from which to copy
		public GraphObj( GraphObj rhs )
		{
			// Copy value types
			_isVisible = rhs.IsVisible;
			_isClippedToChartRect = rhs._isClippedToChartRect;
			_zOrder = rhs.ZOrder;
			// copy reference types by cloning
			if ( rhs.Tag is ICloneable )
				this.Tag = ((ICloneable) rhs.Tag).Clone();
			else
				this.Tag = rhs.Tag;
			_location = rhs.Location.Clone();
			_link = rhs._link.Clone();
		}
		/// 
		/// Implement the  interface in a typesafe manner by just
		/// calling the typed version of Clone.
		/// 
		/// 
		/// Note that this method must be called with an explicit cast to ICloneable, and
		/// that it is inherently virtual.  For example:
		/// 
		/// ParentClass foo = new ChildClass();
		/// ChildClass bar = (ChildClass) ((ICloneable)foo).Clone();
		/// 
		/// Assume that ChildClass is inherited from ParentClass.  Even though foo is declared with
		/// ParentClass, it is actually an instance of ChildClass.  Calling the ICloneable implementation
		/// of Clone() on foo actually calls ChildClass.Clone() as if it were a virtual function.
		/// 
		/// A deep copy of this object
		object ICloneable.Clone()
		{
			throw new NotImplementedException( "Can't clone an abstract base type -- child types must implement ICloneable" );
			//return new PaneBase( this );
		}
	#endregion
	#region Serialization
		/// 
		/// Current schema value that defines the version of the serialized file
		/// 
		/// 
		/// schema changed to 2 when isClippedToChartRect was added.
		/// 
		public const int schema = 10;
		/// 
		/// Constructor for deserializing objects
		/// 
		/// A  instance that defines the serialized data
		/// 
		/// A  instance that contains the serialized data
		/// 
		protected GraphObj( SerializationInfo info, StreamingContext context )
		{
			// The schema value is just a file version parameter.  You can use it to make future versions
			// backwards compatible as new member variables are added to classes
			int sch = info.GetInt32( "schema" );
			_location = (Location) info.GetValue( "location", typeof(Location) );
			_isVisible = info.GetBoolean( "isVisible" );
			Tag = info.GetValue( "Tag", typeof(object) );
			_zOrder = (ZOrder) info.GetValue( "zOrder", typeof(ZOrder) );
			_isClippedToChartRect = info.GetBoolean( "isClippedToChartRect" );
			_link = (Link) info.GetValue( "link", typeof( Link ) );
		}
		/// 
		/// Populates a  instance with the data needed to serialize the target object
		/// 
		/// A  instance that defines the serialized data
		/// A  instance that contains the serialized data
		[SecurityPermissionAttribute(SecurityAction.Demand,SerializationFormatter=true)]
		public virtual void GetObjectData( SerializationInfo info, StreamingContext context )
		{
			info.AddValue( "schema", schema );
			info.AddValue( "location", _location );
			info.AddValue( "isVisible", _isVisible );
			info.AddValue( "Tag", Tag );
			info.AddValue( "zOrder", _zOrder );
			info.AddValue( "isClippedToChartRect", _isClippedToChartRect );
			info.AddValue( "link", _link );
		}
	#endregion
	#region Rendering Methods
		/// 
		/// Render this  object to the specified  device.
		/// 
		/// 
		/// This method is normally only called by the Draw method
		/// of the parent  collection object.
		/// 
		/// 
		/// A graphic device object to be drawn into.  This is normally e.Graphics from the
		/// PaintEventArgs argument to the Paint() method.
		/// 
		/// 
		/// A reference to the  object that is the parent or
		/// owner of this object.
		/// 
		/// 
		/// The scaling factor to be used for rendering objects.  This is calculated and
		/// passed down by the parent  object using the
		///  method, and is used to proportionally adjust
		/// font sizes, etc. according to the actual size of the graph.
		/// 
		abstract public void Draw( Graphics g, PaneBase pane, float scaleFactor );
		
		/// 
		/// Determine if the specified screen point lies inside the bounding box of this
		/// .
		/// 
		/// The screen point, in pixels
		/// 
		/// A reference to the  object that is the parent or
		/// owner of this object.
		/// 
		/// 
		/// A graphic device object to be drawn into.  This is normally e.Graphics from the
		/// PaintEventArgs argument to the Paint() method.
		/// 
		/// 
		/// The scaling factor to be used for rendering objects.  This is calculated and
		/// passed down by the parent  object using the
		///  method, and is used to proportionally adjust
		/// font sizes, etc. according to the actual size of the graph.
		/// 
		/// true if the point lies in the bounding box, false otherwise
		virtual public bool PointInBox( PointF pt, PaneBase pane, Graphics g, float scaleFactor )
		{
			GraphPane gPane = pane as GraphPane;
			if ( gPane != null && _isClippedToChartRect && !gPane.Chart.Rect.Contains( pt ) )
				return false;
			return true;
		}
		/// 
		/// Determines the shape type and Coords values for this GraphObj
		/// 
		abstract public void GetCoords( PaneBase pane, Graphics g, float scaleFactor,
				out string shape, out string coords );
	#endregion
	
	}
}