using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Globalization;
namespace DevComponents.Tree
{
    #region Padding Class
    /// 
    /// Represents class that holds padding information for user interface elements.
    /// 
    [TypeConverter(typeof(PaddingConvertor))]
    public class Padding : INotifyPropertyChanged
    {
        #region Private variables
        /// 
        /// Gets or sets padding on left side. Default value is 0
        /// 
        private int _Left;
        /// 
        /// Gets or sets padding on right side. Default value is 0
        /// 
        private int _Right;
        /// 
        /// Gets or sets padding on top side. Default value is 0
        /// 
        private int _Top;
        /// 
        /// Gets or sets padding on bottom side. Default value is 0
        /// 
        private int _Bottom;
        #endregion
        /// 
        /// Creates new instance of the class and initializes it.
        /// 
        /// Left padding
        /// Right padding
        /// Top padding
        /// Bottom padding
        public Padding(int left, int right, int top, int bottom)
        {
            _Left = left;
            _Right = right;
            _Top = top;
            _Bottom = bottom;
        }
        #region Public properties
        /// 
        /// Gets amount of Top padding
        /// 
        [Browsable(true), DefaultValue(0)]
        [Description("Indicates the amount of Top padding.")]
        [NotifyParentProperty(true)]
        public int Top
        {
            get { return (_Top); }
            set { _Top = value; OnPropertyChanged(new PropertyChangedEventArgs("Top")); }
        }
        /// 
        /// Gets amount of Left padding
        /// 
        [Browsable(true), DefaultValue(0)]
        [Description("Indicates the amount of Left padding.")]
        [NotifyParentProperty(true)]
        public int Left
        {
            get { return (_Left); }
            set { _Left = value; OnPropertyChanged(new PropertyChangedEventArgs("Left")); }
        }
        /// 
        /// Gets amount of Bottom padding
        /// 
        [Browsable(true), DefaultValue(0)]
        [Description("Indicates the amount of Bottom padding.")]
        [NotifyParentProperty(true)]
        public int Bottom
        {
            get { return (_Bottom); }
            set { _Bottom = value; OnPropertyChanged(new PropertyChangedEventArgs("Bottom")); }
        }
        /// 
        /// Gets amount of Right padding
        /// 
        [Browsable(true), DefaultValue(0)]
        [Description("Indicates the amount of Right padding.")]
        [NotifyParentProperty(true)]
        public int Right
        {
            get { return (_Right); }
            set { _Right = value; OnPropertyChanged(new PropertyChangedEventArgs("Right")); }
        }
        /// 
        /// Gets amount of horizontal padding (Left+Right)
        /// 
        [Browsable(false)]
        public int Horizontal
        {
            get { return (_Left + _Right); }
        }
        /// 
        /// Gets amount of vertical padding (Top+Bottom)
        /// 
        [Browsable(false)]
        public int Vertical
        {
            get { return (_Top + _Bottom); }
        }
        /// 
        /// Gets whether Padding is empty.
        /// 
        [Browsable(false)]
        public bool IsEmpty
        {
            get { return (_Left == 0 && _Right == 0 && _Top == 0 && _Bottom == 0); }
        }
        #endregion
        #region INotifyPropertyChanged Members
        /// 
        /// Occurs when property value has changed.
        /// 
        public event PropertyChangedEventHandler PropertyChanged;
        /// 
        /// Raises the PropertyChanged event.
        /// 
        /// Event arguments
        protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            PropertyChangedEventHandler eh = PropertyChanged;
            if (eh != null) eh(this, e);
        }
        #endregion
    }
    #endregion
    #region PaddingConvertor
    public class PaddingConvertor : ExpandableObjectConverter
    {
        public override bool CanConvertTo(
            ITypeDescriptorContext context, Type destinationType)
        {
            if (destinationType == typeof(string))
                return (true);
            return (base.CanConvertTo(context, destinationType));
        }
        public override object ConvertTo(
            ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(string))
            {
                Padding pad = value as Padding;
                if (pad != null)
                {
                    return (String.Format("{0:D}, {1:D}, {2:D}, {3:D}",
                        pad.Bottom, pad.Left, pad.Right, pad.Top));
                }
            }
            return (base.ConvertTo(context, culture, value, destinationType));
        }
        public override bool CanConvertFrom(
            ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string))
                return (true);
            return (base.CanConvertFrom(context, sourceType));
        }
        public override object ConvertFrom(
            ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if (value is string)
            {
                string[] values = ((string)value).Split(',');
                if (values.Length != 4)
                    throw new ArgumentException("Invalid value to convert.");
                try
                {
                    int bottom = int.Parse(values[0]);
                    int left = int.Parse(values[1]);
                    int right = int.Parse(values[2]);
                    int top = int.Parse(values[3]);
                    Padding pad = new Padding(left, right, top, bottom);
                    return (pad);
                }
                catch (Exception exp)
                {
                    throw new ArgumentException("Invalid value to convert.");
                }
            }
            return base.ConvertFrom(context, culture, value);
        }
    }
    #endregion
}