using System;
using System.ComponentModel;
using System.Drawing.Drawing2D;
using DevComponents.DotNetBar.Charts.Primitives;
namespace DevComponents.DotNetBar.Charts.Style
{
    /// 
    /// Defines Thickness class.
    /// 
    [TypeConverter(typeof(BlankExpandableObjectConverter))]
    public class BorderPattern : IEquatable, IProcessSerialElement, INotifyPropertyChanged
    {
        #region Static data
        /// 
        /// Returns Empty instance of BorderPattern.
        /// 
        public static BorderPattern Empty
        {
            get { return (new BorderPattern()); }
        }
        #endregion
        #region Private variables
        private LinePattern _Bottom = LinePattern.NotSet;
        private LinePattern _Left = LinePattern.NotSet;
        private LinePattern _Right = LinePattern.NotSet;
        private LinePattern _Top = LinePattern.NotSet;
        #endregion
        #region Constructors
        /// 
        /// Creates new instance of the object.
        /// 
        /// Left BorderPatternStyle.
        /// Top BorderPatternStyle.
        /// Right BorderPatternStyle.
        /// Bottom BorderPatternStyle.
        public BorderPattern(LinePattern left,
            LinePattern top, LinePattern right, LinePattern bottom)
        {
            _Left = left;
            _Top = top;
            _Right = right;
            _Bottom = bottom;
            PropertyChanged = null;
        }
        /// 
        /// Creates new instance of the object.
        /// 
        /// Specifies uniform Thickness.
        public BorderPattern(LinePattern all)
            : this(all, all, all, all)
        {
        }
        ///
        /// Creates new instance of the object.
        ///
        public BorderPattern()
        {
        }
        #endregion
        #region Public properties
        #region All
        /// 
        /// Gets or sets the thickness of all sides.
        /// 
        //[Browsable(false)]
        //[EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public LinePattern All
        {
            set { _Top = _Left = _Bottom = _Right = value; }
        }
        #endregion
        #region Bottom
        /// 
        /// Gets or sets the bottom Border Pattern
        /// 
        [DefaultValue(LinePattern.NotSet)]
        [Description("Indicates the bottom Border Pattern")]
        public LinePattern Bottom
        {
            get { return (_Bottom); }
            set
            {
                if (_Bottom != value)
                {
                    _Bottom = value;
                    OnPropertyChanged(new VisualPropertyChangedEventArgs("Bottom"));
                }
            }
        }
        #endregion
        #region Left
        /// 
        /// Gets or sets the left Border Pattern
        /// 
        [DefaultValue(LinePattern.NotSet)]
        [Description("Indicates the left Border Pattern")]
        public LinePattern Left
        {
            get { return (_Left); }
            set
            {
                if (_Left != value)
                {
                    _Left = value;
                    OnPropertyChanged(new VisualPropertyChangedEventArgs("Left"));
                }
            }
        }
        #endregion
        #region Right
        /// 
        /// Gets or sets the Right Border Pattern
        /// 
        [DefaultValue(LinePattern.NotSet)]
        [Description("Indicates the Right Border Pattern")]
        public LinePattern Right
        {
            get { return (_Right); }
            set
            {
                if (_Right != value)
                {
                    _Right = value;
                    OnPropertyChanged(new VisualPropertyChangedEventArgs("Right"));
                }
            }
        }
        #endregion
        #region Top
        /// 
        /// Gets or sets the Top Border Pattern
        /// 
        [Browsable(true), DefaultValue(LinePattern.NotSet)]
        [Description("Indicates the Top Border Pattern")]
        public LinePattern Top
        {
            get { return (_Top); }
            set
            {
                if (_Top != value)
                {
                    _Top = value;
                    OnPropertyChanged(new VisualPropertyChangedEventArgs("Top"));
                }
            }
        }
        #endregion
        #region IsEmpty
        /// 
        /// Gets whether the item is empty
        /// 
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool IsEmpty
        {
            get
            {
                return (_Left == LinePattern.NotSet &&
                        _Right == LinePattern.NotSet &&
                        _Top == LinePattern.NotSet &&
                        _Bottom == LinePattern.NotSet);
            }
        }
        #endregion
        #endregion
        #region Internal properties
        #region IsUniform
        internal bool IsUniform
        {
            get
            {
                return (_Left == _Top &&
                        _Left == _Right && _Left == _Bottom);
            }
        }
        #endregion
        #endregion
        #region Equals
        /// 
        /// Gets whether two instances are equal.
        /// 
        /// Instance to compare to.
        /// true if equal otherwise false.
        public override bool Equals(object obj)
        {
            if (obj is BorderPattern)
                return (this == (BorderPattern)obj);
            return (false);
        }
        /// 
        /// Gets whether two instances are equal.
        /// 
        /// Instance to compare to
        /// true if equal otherwise false
        public bool Equals(BorderPattern borderPattern)
        {
            return (this == borderPattern);
        }
        #endregion
        #region GetHashCode
        /// 
        /// Returns hash-code.
        /// 
        /// hash-code
        public override int GetHashCode()
        {
            return (((_Left.GetHashCode() ^ _Top.GetHashCode()) ^
                     _Right.GetHashCode()) ^ _Bottom.GetHashCode());
        }
        #endregion
        #region Operators
        #region "==" operator
        /// 
        /// Implements == operator.
        /// 
        /// Object 1
        /// Object 2
        /// true if equals
        public static bool operator ==(BorderPattern t1, BorderPattern t2)
        {
            if (ReferenceEquals(t1, t2))
                return (true);
            if (((object)t1 == null) || ((object)t2 == null))
                return (false);
            return (t1._Left == t2._Left && t1._Right == t2._Right &&
                    t1._Top == t2._Top && t1._Bottom == t2._Bottom);
        }
        #endregion
        #region "!=" operator
        /// 
        /// Implements != operator
        /// 
        /// Object 1
        /// Object 2
        /// true if different
        public static bool operator !=(BorderPattern t1, BorderPattern t2)
        {
            return ((t1 == t2) == false);
        }
        #endregion
        #endregion
        #region ApplyPattern
        /// 
        /// Applies the pattern to instance of this pattern.
        /// 
        /// Pattern to apply.
        public void ApplyPattern(BorderPattern pattern)
        {
            if (pattern != null)
            {
                if (pattern.Top != LinePattern.NotSet)
                    _Top = pattern.Top;
                if (pattern.Left != LinePattern.NotSet)
                    _Left = pattern.Left;
                if (pattern.Bottom != LinePattern.NotSet)
                    _Bottom = pattern.Bottom;
                if (pattern.Right != LinePattern.NotSet)
                    _Right = pattern.Right;
            }
        }
        #endregion
        #region Copy
        /// 
        /// Creates an exact copy of the BorderPattern.
        /// 
        /// Copy of the BorderPattern.
        public BorderPattern Copy()
        {
            BorderPattern copy = new BorderPattern(_Left, _Top, _Right, _Bottom);
            return (copy);
        }
        #endregion
        #region GetSerialData
        internal SerialElementCollection GetSerialData(string serialName)
        {
            SerialElementCollection sec = new SerialElementCollection();
            if (serialName != null)
            {
                if (serialName.Equals("") == true)
                    serialName = "BorderPattern";
                sec.AddStartElement(serialName);
            }
            if (IsUniform == true)
            {
                sec.AddValue("All", Left, LinePattern.NotSet);
            }
            else
            {
                sec.AddValue("Left", Left, LinePattern.NotSet);
                sec.AddValue("Top", Top, LinePattern.NotSet);
                sec.AddValue("Right", Right, LinePattern.NotSet);
                sec.AddValue("Bottom", Bottom, LinePattern.NotSet);
            }
            if (serialName != null)
                sec.AddEndElement(serialName);
            return (sec);
        }
        #endregion
        #region PutSerialData
        #region ProcessValue
        void IProcessSerialElement.ProcessValue(SerialElement se)
        {
            switch (se.Name)
            {
                case "All":
                    All = (LinePattern)se.GetValueEnum(typeof(LinePattern));
                    break;
                case "Left":
                    Left = (LinePattern)se.GetValueEnum(typeof(LinePattern));
                    break;
                case "Top":
                    Top = (LinePattern)se.GetValueEnum(typeof(LinePattern));
                    break;
                case "Right":
                    Right = (LinePattern)se.GetValueEnum(typeof(LinePattern));
                    break;
                case "Bottom":
                    Bottom = (LinePattern)se.GetValueEnum(typeof(LinePattern));
                    break;
                default:
                    throw new Exception("Unknown Serial Value (" + se.Name + ")");
            }
        }
        #endregion
        #region ProcessCollection
        void IProcessSerialElement.ProcessCollection(SerialElement se)
        {
            throw new Exception("Unknown Serial Collection (" + se.Name + ")");
        }
        #endregion
        #endregion
        #region INotifyPropertyChanged Members
        /// 
        /// Occurs when property value has changed.
        /// 
        public event PropertyChangedEventHandler PropertyChanged;
        /// 
        /// Raises the PropertyChanged event.
        /// 
        /// Event arguments
        void OnPropertyChanged(VisualPropertyChangedEventArgs e)
        {
            PropertyChangedEventHandler eh = PropertyChanged;
            if (eh != null)
                eh(this, e);
        }
        #endregion
    }
    #region enums
    #region LinePattern
    ///
    /// LinePattern
    ///
    public enum LinePattern
    {
        ///
        /// None
        ///
        None = -2,
        ///
        /// NotSet
        ///
        NotSet = -1,
        ///
        /// Solid
        ///
        Solid = DashStyle.Solid,
        ///
        /// Dash
        ///
        Dash = DashStyle.Dash,
        ///
        /// Dot
        ///
        Dot = DashStyle.Dot,
        ///
        /// DashDot
        ///
        DashDot = DashStyle.DashDot,
        ///
        /// DashDotDot
        ///
        DashDotDot = DashStyle.DashDotDot,
    }
    #endregion
    #region ChartLineCap
    ///
    /// ChartLineCap
    ///
    public enum ChartLineCap
    {
        ///
        /// NotSet
        ///
        NotSet = -1,
        Flat = 0,
        Square = 1,
        Round = 2,
        Triangle = 3,
        NoAnchor = 16,
        SquareAnchor = 17,
        RoundAnchor = 18,
        DiamondAnchor = 19,
        ArrowAnchor = 20,
    }
    #endregion
    #endregion
}