using System;
using System.ComponentModel;
using System.Windows.Input;
using Windows.UI.Popups;
using Windows.UI.Xaml;

namespace ZadaniaUA
{
    public abstract class DialogBox : FrameworkElement, INotifyPropertyChanged
    {
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string nazwaWłasności)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(nazwaWłasności));
        }
        #endregion

        protected Action<object> execute = null;

        public string Caption { get; set; }

        protected ICommand show;

        public virtual ICommand Show
        {
            get
            {
                if (show == null) show = new RelayCommand(execute);
                return show;
            }
        }
    }

    public class SimpleMessageDialogBox : DialogBox
    {
        public SimpleMessageDialogBox()
        {
            execute =
                //o =>
                async o =>
                {
                    //MessageBox.Show((string)o, Caption);
                    await new MessageDialog((string)o, Caption).ShowAsync();
                };
        }
    }

    public abstract class CommandDialogBox : DialogBox
    {
        public override ICommand Show
        {
            get
            {
                if (show == null)
                    show = new RelayCommand(
                        o =>
                        {
                            ExecuteCommand(CommandBefore, CommandParameter);
                            execute(o);
                            ExecuteCommand(CommandAfter, CommandParameter);
                        });
                return show;
            }
        }

        //public static DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(CommandDialogBox));
        public static DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(CommandDialogBox), new PropertyMetadata(null));

        public object CommandParameter
        {
            get
            {
                return GetValue(CommandParameterProperty);
            }
            set
            {
                SetValue(CommandParameterProperty, value);
            }
        }

        protected static void ExecuteCommand(ICommand command, object commandParameter)
        {
            if (command != null)
                if (command.CanExecute(commandParameter))
                    command.Execute(commandParameter);
        }

        //public static DependencyProperty CommandBeforeProperty = DependencyProperty.Register("CommandBefore", typeof(ICommand), typeof(CommandDialogBox));
        public static DependencyProperty CommandBeforeProperty = DependencyProperty.Register("CommandBefore", typeof(ICommand), typeof(CommandDialogBox), new PropertyMetadata(null));

        public ICommand CommandBefore
        {
            get
            {
                return (ICommand)GetValue(CommandBeforeProperty);
            }
            set
            {
                SetValue(CommandBeforeProperty, value);
            }
        }

        //public static DependencyProperty CommandAfterProperty = DependencyProperty.Register("CommandAfter", typeof(ICommand), typeof(CommandDialogBox));
        public static DependencyProperty CommandAfterProperty = DependencyProperty.Register("CommandAfter", typeof(ICommand), typeof(CommandDialogBox), new PropertyMetadata(null));

        public ICommand CommandAfter
        {
            get
            {
                return (ICommand)GetValue(CommandAfterProperty);
            }
            set
            {
                SetValue(CommandAfterProperty, value);
            }
        }
    }

    public class NotificationDialogBox : CommandDialogBox
    {
        public NotificationDialogBox()
        {
            execute =
                //o =>
                async o =>
                {
                    //MessageBox.Show((string)o, Caption, MessageBoxButton.OK, MessageBoxImage.Information);
                    await new MessageDialog((string)o, Caption).ShowAsync();
                };
        }
    }

    public class MessageDialogBox : CommandDialogBox
    {
        public enum MessageDialogBoxResult { None = 0, OKOrClose = 1, Cancel = 2, Yes = 6, No = 7 }

        public enum MessageDialogBoxButton { Close = 0, OKCancel = 1, YesNo = 4 }

        public MessageDialogBoxResult? LastResult { get; protected set; }
        public MessageDialogBoxButton Buttons { get; set; }

        public bool IsLastResultYes
        {
            get
            {
                if (!LastResult.HasValue) return false;
                return LastResult.Value == MessageDialogBoxResult.Yes;
            }
        }

        public bool IsLastResultNo
        {
            get
            {
                if (!LastResult.HasValue) return false;
                return LastResult.Value == MessageDialogBoxResult.No;
            }
        }

        public bool IsLastResultCancel
        {
            get
            {
                if (!LastResult.HasValue) return false;
                return LastResult.Value == MessageDialogBoxResult.Cancel;
            }
        }

        public bool IsLastResultOKOrClose
        {
            get
            {
                if (!LastResult.HasValue) return false;
                return LastResult.Value == MessageDialogBoxResult.OKOrClose;
            }
        }

        public void WykonajPolecenie(IUICommand polecenieUI)
        {
            LastResult = (MessageDialogBoxResult)polecenieUI.Id;
            OnPropertyChanged("LastResult");
            switch (LastResult)
            {
                case MessageDialogBoxResult.Yes:
                    OnPropertyChanged("IsLastResultYes");
                    ExecuteCommand(CommandYes, CommandParameter);
                    break;
                case MessageDialogBoxResult.No:
                    OnPropertyChanged("IsLastResultNo");
                    ExecuteCommand(CommandNo, CommandParameter);
                    break;
                case MessageDialogBoxResult.Cancel:
                    OnPropertyChanged("IsLastResultCancel");
                    ExecuteCommand(CommandCancel, CommandParameter);
                    break;
                case MessageDialogBoxResult.OKOrClose:
                    OnPropertyChanged("IsLastResultOKOrClose");
                    ExecuteCommand(CommandOKOrClose, CommandParameter);
                    break;
            }
        }

        public MessageDialogBox()
        {
            Buttons = MessageDialogBoxButton.Close;

            execute = async o =>
            {
                //LastResult = MessageBox.Show((string)o, Caption, Buttons, Icon);
                MessageDialog messageDialog = new MessageDialog((string)o, Caption);
                switch(Buttons)
                {
                    case MessageDialogBoxButton.Close:
                        messageDialog.Commands.Add(new UICommand("OK", WykonajPolecenie, MessageDialogBoxResult.OKOrClose));
                        messageDialog.DefaultCommandIndex = 0;
                        break;
                    case MessageDialogBoxButton.OKCancel:
                        messageDialog.Commands.Add(new UICommand("OK", WykonajPolecenie, MessageDialogBoxResult.OKOrClose));
                        messageDialog.Commands.Add(new UICommand("Cancel", WykonajPolecenie, MessageDialogBoxResult.Cancel));
                        messageDialog.DefaultCommandIndex = 1;
                        messageDialog.CancelCommandIndex = 1;
                        break;
                    case MessageDialogBoxButton.YesNo:
                        messageDialog.Commands.Add(new UICommand("Yes", WykonajPolecenie, MessageDialogBoxResult.Yes));
                        messageDialog.Commands.Add(new UICommand("No", WykonajPolecenie, MessageDialogBoxResult.No));
                        messageDialog.DefaultCommandIndex = 1;
                        break;
                }
                await messageDialog.ShowAsync();                
            };
        }

        public static DependencyProperty CommandYesProperty = DependencyProperty.Register("CommandYes", typeof(ICommand), typeof(MessageDialogBox), new PropertyMetadata(null));
        public static DependencyProperty CommandNoProperty = DependencyProperty.Register("CommandNo", typeof(ICommand), typeof(MessageDialogBox), new PropertyMetadata(null));
        public static DependencyProperty CommandCancelProperty = DependencyProperty.Register("CommandCancel", typeof(ICommand), typeof(MessageDialogBox), new PropertyMetadata(null));
        public static DependencyProperty CommandOKOrCloseProperty = DependencyProperty.Register("CommandOKOrClose", typeof(ICommand), typeof(MessageDialogBox), new PropertyMetadata(null));

        public ICommand CommandYes
        {
            get
            {
                return (ICommand)GetValue(CommandYesProperty);
            }
            set
            {
                SetValue(CommandYesProperty, value);
            }
        }

        public ICommand CommandNo
        {
            get
            {
                return (ICommand)GetValue(CommandNoProperty);
            }
            set
            {
                SetValue(CommandNoProperty, value);
            }
        }

        public ICommand CommandCancel
        {
            get
            {
                return (ICommand)GetValue(CommandCancelProperty);
            }
            set
            {
                SetValue(CommandCancelProperty, value);
            }
        }

        public ICommand CommandOKOrClose
        {
            get
            {
                return (ICommand)GetValue(CommandOKOrCloseProperty);
            }
            set
            {
                SetValue(CommandOKOrCloseProperty, value);
            }
        }
    }
}
