using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using MECF.Framework.UI.Client.Core;

namespace MECF.Framework.UI.Client.Ctrlib.Controls
{
    /// <summary>
    /// Interaction logic for ModuleStatusIndicator.xaml
    /// </summary>
    public partial class ModuleStatusIndicator : UserControl
    {
        public ModuleStatusIndicator()
        {
            InitializeComponent();
        }

        #region Dependency Properties

        #region DP - Caption

        public static readonly DependencyProperty CaptionProperty = DependencyProperty.Register(
            nameof(Caption), typeof(string), typeof(ModuleStatusIndicator), new PropertyMetadata(default(string)));

        /// <summary>
        /// 设置或返回标题
        /// </summary>
        public string Caption
        {
            get => (string)GetValue(CaptionProperty);
            set => SetValue(CaptionProperty, value);
        }

        #endregion

        #region DP - Caption Width

        public static readonly DependencyProperty CaptionWidthProperty = DependencyProperty.Register(
            nameof(CaptionWidth), typeof(double), typeof(ModuleStatusIndicator), new PropertyMetadata(100.0d));

        public double CaptionWidth
        {
            get => (double)GetValue(CaptionWidthProperty);
            set => SetValue(CaptionWidthProperty, value);
        }

        #endregion

        #region DP - Status

        public static readonly DependencyProperty StatusProperty = DependencyProperty.Register(
            nameof(Status), typeof(string), typeof(ModuleStatusIndicator), new PropertyMetadata(default(string)));

        public string Status
        {
            get => (string)GetValue(StatusProperty);
            set => SetValue(StatusProperty, value);
        }

        #endregion

        #region DP - IsOnline

        public static readonly DependencyProperty IsOnlineProperty = DependencyProperty.Register(
            nameof(IsOnline), typeof(bool), typeof(ModuleStatusIndicator), new PropertyMetadata(default(bool)));

        public bool IsOnline
        {
            get => (bool)GetValue(IsOnlineProperty);
            set => SetValue(IsOnlineProperty, value);
        }

        #endregion

        #region DP - ModuleName

        public static readonly DependencyProperty ModuleNameProperty = DependencyProperty.Register(
            nameof(ModuleName), typeof(string), typeof(ModuleStatusIndicator), new PropertyMetadata(default(string)));

        public string ModuleName
        {
            get => (string)GetValue(ModuleNameProperty);
            set => SetValue(ModuleNameProperty, value);
        }

        #endregion

        #region DP - Module Description

        public static readonly DependencyProperty ModuleDescriptionProperty = DependencyProperty.Register(
            nameof(ModuleDescription), typeof(string), typeof(ModuleStatusIndicator), new PropertyMetadata(default(string)));

        public string ModuleDescription
        {
            get => (string)GetValue(ModuleDescriptionProperty);
            set => SetValue(ModuleDescriptionProperty, value);
        }

        #endregion

        #region DP - HasWarning

        public static readonly DependencyProperty HasWarningProperty = DependencyProperty.Register(
            nameof(HasWarning), typeof(bool), typeof(ModuleStatusIndicator), new PropertyMetadata(default(bool)));

        public bool HasWarning
        {
            get => (bool)GetValue(HasWarningProperty);
            set => SetValue(HasWarningProperty, value);
        }

        #endregion

        #region DP - WarningTips

        public static readonly DependencyProperty WarningTipProperty = DependencyProperty.Register(
            nameof(WarningTip), typeof(string), typeof(ModuleStatusIndicator), new PropertyMetadata(default(string)));

        public string WarningTip
        {
            get => (string)GetValue(WarningTipProperty);
            set => SetValue(WarningTipProperty, value);
        }

        #endregion

        #region DP - SetOnline Command

        public static readonly DependencyProperty SetOnlineCommandProperty = DependencyProperty.Register(
            nameof(SetOnlineCommand), typeof(ICommand), typeof(ModuleStatusIndicator), new PropertyMetadata(default(ICommand)));

        public ICommand SetOnlineCommand
        {
            get => (ICommand)GetValue(SetOnlineCommandProperty);
            set => SetValue(SetOnlineCommandProperty, value);
        }

        #endregion

        #region DP - SetOffline Command

        public static readonly DependencyProperty SetOfflineCommandProperty = DependencyProperty.Register(
            nameof(SetOfflineCommand), typeof(ICommand), typeof(ModuleStatusIndicator), new PropertyMetadata(default(ICommand)));

        public ICommand SetOfflineCommand
        {
            get => (ICommand)GetValue(SetOfflineCommandProperty);
            set => SetValue(SetOfflineCommandProperty, value);
        }

        #endregion

        #endregion

        #region Event Handler

        private void CmSetOnline_OnClick(object sender, RoutedEventArgs e)
        {
            RaiseEvent(new RoutedEventArgs(SetOnlineEvent));
        }

        private void CmSetOffline_OnClick(object sender, RoutedEventArgs e)
        {
            RaiseEvent(new RoutedEventArgs(SetOfflineEvent));
        }

        #endregion

        #region Routed Events

        public static readonly RoutedEvent SetOnlineEvent = EventManager.RegisterRoutedEvent(nameof(SetOnline), RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(UserControl));

        public event RoutedEventHandler SetOnline
        {
            add => AddHandler(SetOnlineEvent, value);
            remove => RemoveHandler(SetOnlineEvent, value);
        }

        public static readonly RoutedEvent SetOfflineEvent = EventManager.RegisterRoutedEvent(nameof(SetOffline), RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(UserControl));

        public event RoutedEventHandler SetOffline
        {
            add => AddHandler(SetOfflineEvent, value);
            remove => RemoveHandler(SetOfflineEvent, value);
        }

        #endregion
    }

    internal class ModuleIsOnlineToBgColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is bool isOnline)
            {
                return isOnline
                    ? Helper.FindSkinResource("TopFrame_TableBG_Highligh", new SolidColorBrush(Colors.LawnGreen))
                    : Helper.FindSkinResource("TopFrame_TableBD_Highlight", new SolidColorBrush(Colors.Gray));
            }

            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    internal class ModuleStatusToBackgroundColorConverter : IValueConverter
    {
        private static SolidColorBrush GetStatusBackground(string status)
        {
            SolidColorBrush brush;

            if (status != null)
                status = status.Trim().ToLower();

            switch (status)
            {
                case "error":
                    brush = Helper.FindSkinResource("TopFrame_TableBG_Error", new SolidColorBrush(Colors.OrangeRed));
                    break;
                case "processidle":
                case "vacidle":
                case "idle":
                case "manual":
                    brush = Helper.FindSkinResource("TopFrame_TableBG_Common", new SolidColorBrush(Colors.White));
                    break;
                case "notconnect":
                case "init":
                    brush = Helper.FindSkinResource("TopFrame_TableBG_Init", new SolidColorBrush(Colors.Yellow));
                    break;
                case "offline":
                case "notinstall":
                    brush = Helper.FindSkinResource("TopFrame_TableBG_Lowlight", new SolidColorBrush(Colors.Gray));
                    break;

                default:
                    brush = Helper.FindSkinResource("TopFrame_TableBG_Highlight", new SolidColorBrush(Colors.LawnGreen));
                    break;
            }

            return brush;
        }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is string status)
            {
                return GetStatusBackground(status);
            }

            return Colors.BlanchedAlmond;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}
