﻿using System;

namespace Trigon.UI
{
    /// <summary>
    /// Check box.
    /// </summary>
    public class CheckBox : ToggleElement
    {
        /// <summary>
        /// The check mark size property.
        /// </summary>
        public static readonly Property<int> CheckMarkSizeProperty = new Property<int>(24);

        /// <summary>
        /// The check mark margin property.
        /// </summary>
        public static readonly Property<int> CheckMarkMarginProperty = new Property<int>(5);

        /// <summary>
        /// Gets or sets the check mark size.
        /// </summary>
        /// <value>The check mark size.</value>
        public int CheckMarkSize
        {
            get { return this.Get(CheckMarkSizeProperty); }
            set { this.Set(CheckMarkSizeProperty, value); }
        }

        /// <summary>
        /// Gets or sets the margin width between the check mark and content.
        /// </summary>
        /// <value>The margin width between the check mark and content.</value>
        public int CheckMarkMargin
        {
            get { return this.Get(CheckMarkMarginProperty); }
            set { this.Set(CheckMarkMarginProperty, value); }
        }

        /// <summary>
        /// Gets the default value for the property.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <returns>The default value for the property.</returns>
        protected override object GetDefaultValue(Property property)
        {
            if (property == PaddingProperty)
            {
                return new Thickness(5, 0);
            }

            if (property == BorderColorProperty)
            {
                return Color.Black;
            }

            return base.GetDefaultValue(property);
        }

        /// <summary>
        /// Gets the override value for the property.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <returns>The override value for the property.</returns>
        protected override object GetOverrideValue(Property property)
        {
            if (property == BackgroundProperty)
            {
                if (this.IsEnabled)
                {
                    if (this.IsPressed)
                    {
                        return Color.LightGray;
                    }
                    else if (this.IsHighlighted)
                    {
                        return Color.White;
                    }
                    else if (this.IsFocused)
                    {
                        return new Color(230, 230, 230);
                    }
                }
            }

            if (property == ForegroundProperty)
            {
                if (!this.IsEnabled)
                {
                    return Color.Gray;
                }
            }

            return base.GetOverrideValue(property);
        }

        /// <summary>
        /// Measures the desired size for the element content.
        /// </summary>
        /// <param name="maximumSize">The maximum size.</param>
        /// <returns>The desired size for the element content.</returns>
        protected override Size MeasureContent(Size maximumSize)
        {
            var checkMarkSize = this.CheckMarkSize;
            var checkMarkMargin = this.CheckMarkMargin;
            var size = base.MeasureContent(maximumSize - new Size(checkMarkSize + checkMarkMargin, 0));

            size.Width += checkMarkSize + checkMarkMargin;
            size.Height = Math.Max(size.Height, checkMarkSize);

            return size;
        }

        /// <summary>
        /// Arranges the element content bounds.
        /// </summary>
        /// <param name="bounds">The proposed content layout rectangle.</param>
        /// <returns>The final content layout rectangle.</returns>
        protected override Rectangle ArrangeContent(Rectangle bounds)
        {
            return base.ArrangeContent(bounds - new Thickness(this.CheckMarkSize + this.CheckMarkMargin, 0, 0, 0));
        }

        /// <summary>
        /// Composes the element.
        /// </summary>
        /// <param name="canvas">The canvas.</param>
        protected override void ComposeElement(Canvas canvas)
        {
            base.ComposeElement(canvas);

            var checkMarkSize = this.CheckMarkSize;
            var checkMarkMargin = this.CheckMarkMargin;

            var checkMark = new Rectangle(this.ContentBounds.X - checkMarkSize - checkMarkMargin, this.ContentBounds.Y, checkMarkSize, checkMarkSize);
            checkMark.Height = Math.Min(checkMark.Height, this.ContentBounds.Height);
            checkMark.Y += (this.ContentBounds.Height - checkMark.Height) / 2;

            if (this.IsChecked)
            {
                canvas.DrawRectangle(checkMark - new Thickness(6), this.BorderColor);
            }

            canvas.DrawRectangle(checkMark, this.BorderColor, new Thickness(2));
        }
    }
}
