using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Windows;
using System.Windows.Data;
using Standard;

namespace Microsoft.Windows.Shell
{
    public class WindowChrome : Freezable
    {
        public static Thickness GlassFrameCompleteThickness
        {
            get
            {
                return new Thickness(-1.0);
            }
        }

        private static void _OnChromeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (DesignerProperties.GetIsInDesignMode(d))
            {
                return;
            }
            Window window = (Window) d;
            WindowChrome windowChrome = (WindowChrome) e.NewValue;
            WindowChromeWorker windowChromeWorker = WindowChromeWorker.GetWindowChromeWorker(window);
            if (windowChromeWorker == null)
            {
                windowChromeWorker = new WindowChromeWorker();
                WindowChromeWorker.SetWindowChromeWorker(window, windowChromeWorker);
            }
            windowChromeWorker.SetWindowChrome(windowChrome);
        }

        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
        [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
        public static WindowChrome GetWindowChrome(Window window)
        {
            Verify.IsNotNull<Window>(window, "window");
            return (WindowChrome) window.GetValue(WindowChrome.WindowChromeProperty);
        }

        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
        [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
        public static void SetWindowChrome(Window window, WindowChrome chrome)
        {
            Verify.IsNotNull<Window>(window, "window");
            window.SetValue(WindowChrome.WindowChromeProperty, chrome);
        }

        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
        [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
        public static bool GetIsHitTestVisibleInChrome(IInputElement inputElement)
        {
            Verify.IsNotNull<IInputElement>(inputElement, "inputElement");
            DependencyObject dependencyObject = inputElement as DependencyObject;
            if (dependencyObject == null)
            {
                throw new ArgumentException("The element must be a DependencyObject", "inputElement");
            }
            return (bool) dependencyObject.GetValue(WindowChrome.IsHitTestVisibleInChromeProperty);
        }

        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
        [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
        public static void SetIsHitTestVisibleInChrome(IInputElement inputElement, bool hitTestVisible)
        {
            Verify.IsNotNull<IInputElement>(inputElement, "inputElement");
            DependencyObject dependencyObject = inputElement as DependencyObject;
            if (dependencyObject == null)
            {
                throw new ArgumentException("The element must be a DependencyObject", "inputElement");
            }
            dependencyObject.SetValue(WindowChrome.IsHitTestVisibleInChromeProperty, hitTestVisible);
        }

        public double CaptionHeight
        {
            get
            {
                return (double) base.GetValue(WindowChrome.CaptionHeightProperty);
            }
            set
            {
                base.SetValue(WindowChrome.CaptionHeightProperty, value);
            }
        }

        public Thickness ResizeBorderThickness
        {
            get
            {
                return (Thickness) base.GetValue(WindowChrome.ResizeBorderThicknessProperty);
            }
            set
            {
                base.SetValue(WindowChrome.ResizeBorderThicknessProperty, value);
            }
        }

        private static object _CoerceGlassFrameThickness(Thickness thickness)
        {
            if (!Utility.IsThicknessNonNegative(thickness))
            {
                return WindowChrome.GlassFrameCompleteThickness;
            }
            return thickness;
        }

        public Thickness GlassFrameThickness
        {
            get
            {
                return (Thickness) base.GetValue(WindowChrome.GlassFrameThicknessProperty);
            }
            set
            {
                base.SetValue(WindowChrome.GlassFrameThicknessProperty, value);
            }
        }

        public CornerRadius CornerRadius
        {
            get
            {
                return (CornerRadius) base.GetValue(WindowChrome.CornerRadiusProperty);
            }
            set
            {
                base.SetValue(WindowChrome.CornerRadiusProperty, value);
            }
        }

        protected override Freezable CreateInstanceCore()
        {
            return new WindowChrome();
        }

        public WindowChrome()
        {
            foreach (WindowChrome._SystemParameterBoundProperty systemParameterBoundProperty in WindowChrome._BoundProperties)
            {
                BindingOperations.SetBinding(this, systemParameterBoundProperty.DependencyProperty, new Binding
                {
                    Source = SystemParameters2.Current,
                    Path = new PropertyPath(systemParameterBoundProperty.SystemParameterPropertyName, new object[0]),
                    Mode = BindingMode.OneWay,
                    UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
                });
            }
        }

        private void _OnPropertyChangedThatRequiresRepaint()
        {
            EventHandler propertyChangedThatRequiresRepaint = this.PropertyChangedThatRequiresRepaint;
            if (propertyChangedThatRequiresRepaint != null)
            {
                propertyChangedThatRequiresRepaint(this, EventArgs.Empty);
            }
        }

        internal event EventHandler PropertyChangedThatRequiresRepaint;

        public static readonly DependencyProperty WindowChromeProperty = DependencyProperty.RegisterAttached("WindowChrome", typeof(WindowChrome), typeof(WindowChrome), new PropertyMetadata(null, new PropertyChangedCallback(WindowChrome._OnChromeChanged)));

        public static readonly DependencyProperty IsHitTestVisibleInChromeProperty = DependencyProperty.RegisterAttached("IsHitTestVisibleInChrome", typeof(bool), typeof(WindowChrome), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits));

        public static readonly DependencyProperty CaptionHeightProperty = DependencyProperty.Register("CaptionHeight", typeof(double), typeof(WindowChrome), new PropertyMetadata(0.0, delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((WindowChrome) d)._OnPropertyChangedThatRequiresRepaint();
        }), (object value) => (double) value >= 0.0);

        public static readonly DependencyProperty ResizeBorderThicknessProperty = DependencyProperty.Register("ResizeBorderThickness", typeof(Thickness), typeof(WindowChrome), new PropertyMetadata(default(Thickness)), (object value) => Utility.IsThicknessNonNegative((Thickness) value));

        public static readonly DependencyProperty GlassFrameThicknessProperty = DependencyProperty.Register("GlassFrameThickness", typeof(Thickness), typeof(WindowChrome), new PropertyMetadata(default(Thickness), delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((WindowChrome) d)._OnPropertyChangedThatRequiresRepaint();
        }, (DependencyObject d, object o) => WindowChrome._CoerceGlassFrameThickness((Thickness) o)));

        public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(WindowChrome), new PropertyMetadata(default(CornerRadius), delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((WindowChrome) d)._OnPropertyChangedThatRequiresRepaint();
        }), (object value) => Utility.IsCornerRadiusValid((CornerRadius) value));

        private static readonly List<WindowChrome._SystemParameterBoundProperty> _BoundProperties = new List<WindowChrome._SystemParameterBoundProperty>
        {
            new WindowChrome._SystemParameterBoundProperty
            {
                DependencyProperty = WindowChrome.CornerRadiusProperty,
                SystemParameterPropertyName = "WindowCornerRadius"
            },
            new WindowChrome._SystemParameterBoundProperty
            {
                DependencyProperty = WindowChrome.CaptionHeightProperty,
                SystemParameterPropertyName = "WindowCaptionHeight"
            },
            new WindowChrome._SystemParameterBoundProperty
            {
                DependencyProperty = WindowChrome.ResizeBorderThicknessProperty,
                SystemParameterPropertyName = "WindowResizeBorderThickness"
            },
            new WindowChrome._SystemParameterBoundProperty
            {
                DependencyProperty = WindowChrome.GlassFrameThicknessProperty,
                SystemParameterPropertyName = "WindowNonClientFrameThickness"
            }
        };

        private struct _SystemParameterBoundProperty
        {
            public string SystemParameterPropertyName { get; set; }

            public DependencyProperty DependencyProperty { get; set; }
        }
    }
}
