using System;
using System.Linq;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using InABox.Core;
using InABox.WPF;
using Xceed.Wpf.Toolkit;

namespace InABox.DynamicGrid
{
    public class DateEditorControl : DynamicEditorControl<DateTime, DateEditor>
    {
        
        static DateEditorControl()
        {
            //DynamicEditorControlFactory.Register<DateEditorControl, DateEditor>();
        }
        
        public static readonly DependencyProperty TodayVisibleProperty =
            DependencyProperty.Register(nameof(TodayVisible), typeof(bool), typeof(DateEditorControl));

        private Button Button;

        private DateTimePicker2 Editor;

        public bool TodayVisible
        {
            get => (bool)GetValue(TodayVisibleProperty);
            set
            {
                SetValue(TodayVisibleProperty, value);
                if (Button != null)
                    Button.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
            }
        }
        public override void Configure()
        {
        }

        protected override FrameworkElement CreateEditor()
        {
            var DockPanel = new DockPanel
            {
                HorizontalAlignment = HorizontalAlignment.Stretch
            };

            Editor = new DateTimePicker2
            {
                Format = DateTimeFormat.Custom,
                FormatString = "dd MMM yyyy",
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment = VerticalAlignment.Stretch,
                VerticalContentAlignment = VerticalAlignment.Center,
                HorizontalContentAlignment = HorizontalAlignment.Center,
                Width = 150,
                CalendarDisplayMode = CalendarMode.Month,
                TimePickerVisibility = Visibility.Collapsed,
                TimePickerShowButtonSpinner = false,
                ShowButtonSpinner = false,
                AutoCloseCalendar = true,
                TextAlignment = TextAlignment.Center
            };
            Editor.GotFocus += (o, e) => { new Timer(s => { Dispatcher.Invoke(() => { Editor.SelectAll(); }); }, Editor, 100, Timeout.Infinite); };
            Editor.ValueChanged += (o, e) =>
            {
                if (e.OriginalSource != Editor) return;
                if (Editor.Value.HasValue && Editor.Value.Value.Year < 100)
                    Editor.Value = Editor.Value.Value.AddYears(2000);
                CheckChanged();
            };
            Editor.KeyUp += (o, e) =>
            {
                if (e.Key == Key.Enter || e.Key == Key.Enter)
                {
                    if (Editor.Value.HasValue && Editor.Value.Value.Year < 100)
                        Editor.Value = Editor.Value.Value.AddYears(2000);
                    CheckChanged();
                }
            };
            Editor.LostFocus += (o, e) => { };
            Editor.MouseDoubleClick += (o, e) => Editor.Value = DateTime.Today;
            Editor.SetValue(DockPanel.DockProperty, Dock.Left);

            var todayvisible = TodayVisible || (EditorDefinition is DateEditor && (EditorDefinition as DateEditor).TodayVisible);

            Button = new Button
            {
                Content = "Today",
                Width = 45,
                Margin = new Thickness(5, 0, 0, 0),
                Focusable = false,
                Visibility = todayvisible ? Visibility.Visible : Visibility.Collapsed
            };
            Button.Click += (o, e) => { Editor.Value = DateTime.Today; };
            Button.SetValue(DockPanel.DockProperty, Dock.Right);


            DockPanel.Children.Add(Button);
            DockPanel.Children.Add(Editor);

            return DockPanel;
        }

        public override int DesiredHeight()
        {
            return 25;
        }

        public override int DesiredWidth()
        {
            return 200;
        }

        protected override DateTime RetrieveValue()
        {
            if (Editor.Value.HasValue)
            {
                if (Editor.Value.Value.Date.Year < 100)
                    return Editor.Value.Value.Date.AddYears(2000);
                return Editor.Value.Value.Date;
            }

            return DateTime.MinValue;
        }

        protected override void UpdateValue(DateTime value)
        {
            if (value != DateTime.MinValue)
                Editor.Value = value;
            else
                Editor.Value = null;
        }

        public override void SetFocus()
        {
            Editor.Focus();
        }

        public override void SetColor(Color color)
        {
            Editor.Background = new SolidColorBrush(color);
        }

        private class DateTimePicker2 : DateTimePicker
        {
            private Calendar _current;

            protected override void Popup_Opened(object sender, EventArgs e)
            {
                base.Popup_Opened(sender, e);
                _current = ((Popup)sender).Child.FindVisualChildren<Calendar>().FirstOrDefault();
            }

            protected override void OnIsOpenChanged(bool oldValue, bool newValue)
            {
                base.OnIsOpenChanged(oldValue, newValue);
                if (oldValue != newValue && newValue == false && _current != null)
                    Value = _current.SelectedDate;
            }
        }
    }
}