using System.ComponentModel;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shell;

namespace BBWY.Controls
{
    [StyleTypedProperty(Property = "Style", StyleTargetType = typeof(BWindow))]
    public class BWindow : Window, INotifyPropertyChanged
    {
        public static readonly DependencyProperty CornerRadiusProperty =
            DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(BWindow), new PropertyMetadata(new CornerRadius(0)));

        public static readonly DependencyProperty RightButtonGroupMarginProperty =
            DependencyProperty.Register("RightButtonGroupMargin", typeof(Thickness), typeof(BWindow), new PropertyMetadata(new Thickness(0, 16, 16, 0)));

        public static readonly DependencyProperty CloseButtonVisibilityProperty =
            DependencyProperty.Register("CloseButtonVisibility", typeof(Visibility), typeof(BWindow), new PropertyMetadata(Visibility.Visible));

        public static readonly DependencyProperty MinButtonVisibilityProperty =
            DependencyProperty.Register("MinButtonVisibility", typeof(Visibility), typeof(BWindow), new PropertyMetadata(Visibility.Visible));

        public static readonly DependencyProperty MaxButtonVisibilityProperty =
            DependencyProperty.Register("MaxButtonVisibility", typeof(Visibility), typeof(BWindow), new PropertyMetadata(Visibility.Visible));

        public static readonly DependencyProperty CloseButtonColorProperty =
            DependencyProperty.Register("CloseButtonColor", typeof(Brush), typeof(BWindow), new PropertyMetadata(new SolidColorBrush(Colors.White)));

        public static readonly DependencyProperty MinButtonColorProperty =
            DependencyProperty.Register("MinButtonColor", typeof(Brush), typeof(BWindow), new PropertyMetadata(new SolidColorBrush(Colors.White)));

        public static readonly DependencyProperty MaxButtonColorProperty =
            DependencyProperty.Register("MaxButtonColor", typeof(Brush), typeof(BWindow), new PropertyMetadata(new SolidColorBrush(Colors.White)));

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

        public Thickness RightButtonGroupMargin
        {
            get { return (Thickness)GetValue(RightButtonGroupMarginProperty); }
            set { SetValue(RightButtonGroupMarginProperty, value); }
        }

        public Visibility CloseButtonVisibility
        {
            get { return (Visibility)GetValue(CloseButtonVisibilityProperty); }
            set { SetValue(CloseButtonVisibilityProperty, value); }
        }

        public Visibility MinButtonVisibility
        {
            get { return (Visibility)GetValue(MinButtonVisibilityProperty); }
            set { SetValue(MinButtonVisibilityProperty, value); }
        }

        public Visibility MaxButtonVisibility
        {
            get { return (Visibility)GetValue(MaxButtonVisibilityProperty); }
            set { SetValue(MaxButtonVisibilityProperty, value); }
        }

        public Brush CloseButtonColor
        {
            get { return (Brush)GetValue(CloseButtonColorProperty); }
            set { SetValue(CloseButtonColorProperty, value); }
        }

        public Brush MinButtonColor
        {
            get { return (Brush)GetValue(MinButtonColorProperty); }
            set { SetValue(MinButtonColorProperty, value); }
        }

        public Brush MaxButtonColor
        {
            get { return (Brush)GetValue(MaxButtonColorProperty); }
            set { SetValue(MaxButtonColorProperty, value); }
        }

        static BWindow()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(BWindow), new FrameworkPropertyMetadata(typeof(BWindow)));
        }

        public BWindow()
        {
            WindowStartupLocation = WindowStartupLocation.CenterScreen;
            var chrome = new WindowChrome
            {
                CornerRadius = new CornerRadius(),
                GlassFrameThickness = new Thickness(1),
                UseAeroCaptionButtons = false,
                NonClientFrameEdges = NonClientFrameEdges.None,
                ResizeBorderThickness = new Thickness(2),
                CaptionHeight = 30
            };
            WindowChrome.SetWindowChrome(this, chrome);
        }

        public override void OnApplyTemplate()
        {
            Button PART_MIN = null;
            Button PART_MAX = null;
            Button PART_RESTORE = null;
            Button PART_CLOSE = null;

            PART_MIN = GetTemplateChild("PART_MIN") as Button;
            PART_MAX = GetTemplateChild("PART_MAX") as Button;
            PART_RESTORE = GetTemplateChild("PART_RESTORE") as Button;
            PART_CLOSE = GetTemplateChild("PART_CLOSE") as Button;

            if (PART_RESTORE != null)
                PART_RESTORE.Click += PART_RESTORE_Click;
            if (PART_MAX != null)
                PART_MAX.Click += PART_MAX_Click;
            if (PART_MIN != null)
                PART_MIN.Click += PART_MIN_Click;
            if (PART_CLOSE != null)
                PART_CLOSE.Click += PART_CLOSE_Click;

            base.OnApplyTemplate();
        }

        private void PART_CLOSE_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void PART_MIN_Click(object sender, RoutedEventArgs e)
        {
            WindowState = WindowState.Minimized;
        }

        private void PART_MAX_Click(object sender, RoutedEventArgs e)
        {
            WindowState = WindowState.Maximized;
        }

        private void PART_RESTORE_Click(object sender, RoutedEventArgs e)
        {
            WindowState = WindowState.Normal;
        }

        /// <summary>
        /// 判断是否为模态窗口
        /// </summary>
        /// <returns></returns>
        public bool IsModal()
        {
            var filedInfo = typeof(Window).GetField("_showingAsDialog", BindingFlags.Instance | BindingFlags.NonPublic);
            return filedInfo != null && (bool)filedInfo.GetValue(this);
        }


        #region PropertyNotify
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        protected bool Set<T>(ref T oldValue, T newValue, [CallerMemberName] string propertyName = "")
        {
            if (Equals(oldValue, newValue))
                return false;
            oldValue = newValue;
            OnPropertyChanged(propertyName);
            return true;
        }
        #endregion
    }
}