using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using SPC.Kiosk.Base;
namespace SPC.Kiosk.Common
{
    /// <summary>
    /// NumericPad.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class NumericPad : UserControl
    {
        #region [ Members ]
        /// <summary>
        /// Noraml Bakcground 
        /// </summary>
        public static readonly DependencyProperty NormalBrushProperty =
                 DependencyProperty.Register(nameof(NormalBrush), typeof(string), typeof(NumericPad), new PropertyMetadata("White", new PropertyChangedCallback(OnNormalBrushPropertyChanged)));
        /// <summary>
        /// Touch Down Bakcground 
        /// </summary>
        public static readonly DependencyProperty DownBrushProperty =
                 DependencyProperty.Register(nameof(DownBrush), typeof(string), typeof(NumericPad), new PropertyMetadata("DarkGray"));
        /// <summary>
        /// Cancel Noraml Bakcground 
        /// </summary>
        public static readonly DependencyProperty CancelNormalBrushProperty =
                 DependencyProperty.Register(nameof(CancelNormalBrush), typeof(string), typeof(NumericPad), new PropertyMetadata("DarkRed"));
        /// <summary>
        /// Cancel Down Bakcground 
        /// </summary>
        public static readonly DependencyProperty CancelDownBrushProperty =
                 DependencyProperty.Register(nameof(CancelDownBrush), typeof(string), typeof(NumericPad), new PropertyMetadata("DarkGray"));
        /// <summary>
        /// Ok Noraml Bakcground 
        /// </summary>
        public static readonly DependencyProperty OkNormalBrushProperty =
                 DependencyProperty.Register(nameof(OkNormalBrush), typeof(string), typeof(NumericPad), new PropertyMetadata("LightBlue"));
        /// <summary>
        /// Ok Down Bakcground 
        /// </summary>
        public static readonly DependencyProperty OkDownBrushProperty =
                 DependencyProperty.Register(nameof(OkDownBrush), typeof(string), typeof(NumericPad), new PropertyMetadata("DarkRed"));
        /// <summary>
        /// Ok Disable Bakcground 
        /// </summary>
        public static readonly DependencyProperty OkDisableBrushProperty =
                 DependencyProperty.Register(nameof(OkDisableBrush), typeof(string), typeof(NumericPad), new PropertyMetadata("Gray"));
        /// <summary>
        /// Ok Switch Enable Background
        /// </summary>
        public static readonly DependencyProperty OkSwitchOnBrushProperty =
                 DependencyProperty.Register(nameof(OkSwitchOnBrush), typeof(string), typeof(NumericPad), new PropertyMetadata("LightBlue"));
        /// <summary>
        /// Click Animation Type
        /// </summary>
        public static readonly DependencyProperty ClickAnimationTypeProperty =
                 DependencyProperty.Register(nameof(ClickAnimationType), typeof(ButtonAnimationType), typeof(NumericPad), new PropertyMetadata(ButtonAnimationType.None));
        /// <summary>
        /// Button Text Foreground
        /// </summary>
        public static readonly DependencyProperty TextForegroundProperty =
                 DependencyProperty.Register(nameof(TextForeground), typeof(string), typeof(NumericPad), new PropertyMetadata("Black", new PropertyChangedCallback(OnTextForegroundPropertyChanged)));
        /// <summary>
        /// Cancel & Back Button Foreground
        /// </summary>
        public static readonly DependencyProperty CancelForegroundProperty =
                 DependencyProperty.Register(nameof(CancelForeground), typeof(string), typeof(NumericPad), new PropertyMetadata("White"));
        /// <summary>
        /// Input Text
        /// </summary>
        public static readonly DependencyProperty InputTextProperty =
                 DependencyProperty.Register(nameof(InputText), typeof(string), typeof(NumericPad), new PropertyMetadata(string.Empty, new PropertyChangedCallback(OnInputTextPropertyChanged)));
        /// <summary>
        /// Show Text With Mask
        /// </summary>
        public static readonly DependencyProperty ShowTextProperty =
                 DependencyProperty.Register(nameof(ShowText), typeof(string), typeof(NumericPad), new PropertyMetadata(string.Empty, new PropertyChangedCallback(OnShowTextPropertyChanged)));
        /// <summary>
        /// Text Area Visible
        /// </summary>
        public static readonly DependencyProperty TextVisibleProperty =
                 DependencyProperty.Register(nameof(TextVisibility), typeof(Visibility), typeof(NumericPad), new PropertyMetadata(Visibility.Visible));
        /// <summary>
        /// Guid Text (Mutil Language)
        /// </summary>
        public static readonly DependencyProperty GuidTextProperty =
                 DependencyProperty.Register(nameof(GuidText), typeof(List<M_Language>), typeof(NumericPad), new PropertyMetadata(default(List<M_Language>)));
        /// <summary>
        /// Cancel Text
        /// </summary>
        public static readonly DependencyProperty CancelTextProperty =
                 DependencyProperty.Register(nameof(CancelText), typeof(string), typeof(NumericPad), new PropertyMetadata("Cancel", new PropertyChangedCallback(OnCancelTextPropertyChanged)));
        /// <summary>
        /// Cancel Text (Mutil Language)
        /// </summary>
        public static readonly DependencyProperty CancelLanguageTextProperty =
                 DependencyProperty.Register(nameof(CancelLanguageText), typeof(List<M_Language>), typeof(NumericPad), new PropertyMetadata(default(List<M_Language>), new PropertyChangedCallback(OnCancelLanguageTextPropertyChanged)));
        /// <summary>
        /// Ok Text
        /// </summary>
        public static readonly DependencyProperty OkTextProperty =
                 DependencyProperty.Register(nameof(OkText), typeof(string), typeof(NumericPad), new PropertyMetadata("OK", new PropertyChangedCallback(OnOkTextPropertyChanged)));
        /// <summary>
        /// Ok Text (Mutil Language)
        /// </summary>
        public static readonly DependencyProperty OkLanguageTextProperty =
                 DependencyProperty.Register(nameof(OkLanguageText), typeof(List<M_Language>), typeof(NumericPad), new PropertyMetadata(default(List<M_Language>), new PropertyChangedCallback(OnOkLanguageTextPropertyChanged)));
        /// <summary>
        /// Display Language Type
        /// </summary>
        public static readonly DependencyProperty DisplayLanguagePropery =
                 DependencyProperty.Register(nameof(DisplayLanguage), typeof(SupportLanguageType), typeof(NumericPad), new PropertyMetadata(SupportLanguageType.ko, new PropertyChangedCallback(OnDisplayLanguageProperyChanged)));
        /// <summary>
        /// Ok Button Enabled
        /// </summary>
        public static readonly DependencyProperty OkEnabledProperty =
                 DependencyProperty.Register(nameof(OkEnabled), typeof(bool), typeof(NumericPad), new PropertyMetadata(false));
        /// <summary>
        /// Etc Button Text
        /// </summary>
        public static readonly DependencyProperty EtcTextProperty =
                 DependencyProperty.Register(nameof(EtcText), typeof(string), typeof(NumericPad), new PropertyMetadata("00", new PropertyChangedCallback(OnEtcTextPropertyChanged)));
        /// <summary>
        /// OkCommand (parameter this Object)
        /// </summary>
        public static readonly DependencyProperty OkCommandProperty =
                 DependencyProperty.Register(nameof(OkCommand), typeof(ICommand), typeof(NumericPad), new UIPropertyMetadata(null));
        /// <summary>
        /// Cancel Command (parameter this Object)
        /// </summary>
        public static readonly DependencyProperty CancelCommandProperty =
                 DependencyProperty.Register(nameof(CancelCommand), typeof(ICommand), typeof(NumericPad), new UIPropertyMetadata(null));
        /// <summary>
        /// OkCommand 
        /// </summary>
        public ICommand OkCommand
        {
            get { return (ICommand)GetValue(OkCommandProperty); }
            set { SetValue(OkCommandProperty, value); }
        }
        /// <summary>
        /// Cancel Command
        /// </summary>
        public ICommand CancelCommand
        {
            get { return (ICommand)GetValue(CancelCommandProperty); }
            set { SetValue(CancelCommandProperty, value); }
        }
        /// <summary>
        /// Text Area Visibility
        /// </summary>
        public Visibility TextVisibility
        {
            get { return (Visibility)GetValue(TextVisibleProperty); }
            set { SetValue(TextVisibleProperty, value); }
        }
        /// <summary>
        /// Etc Button Text
        /// </summary>
        public string EtcText
        {
            get { return (string)GetValue(EtcTextProperty); }
            set { SetValue(EtcTextProperty, value); }
        }
        /// <summary>
        /// Input Text (Real Data)
        /// </summary>
        public string InputText
        {
            get { return (string)GetValue(InputTextProperty); }
            set { SetValue(InputTextProperty, value); }
        }
        /// <summary>
        /// Show Text With Mask
        /// </summary>
        public string ShowText
        {
            get { return (string)GetValue(ShowTextProperty); }
            set { SetValue(ShowTextProperty, value); }
        }
        /// <summary>
        /// Guid Text (Multi Language)
        /// </summary>
        public List<M_Language> GuidText
        {
            get { return (List<M_Language>)GetValue(GuidTextProperty); }
            set { SetValue(GuidTextProperty, value); }
        }
        /// <summary>
        /// Display Language Type
        /// </summary>
        public SupportLanguageType DisplayLanguage
        {
            get { return (SupportLanguageType)GetValue(DisplayLanguagePropery); }
            set { SetValue(DisplayLanguagePropery, value); }
        }
        /// <summary>
        /// Ok Button Enabled
        /// </summary>
        public bool OkEnabled
        {
            get { return (bool)GetValue(OkEnabledProperty); }
            set { SetValue(OkEnabledProperty, value); }
        }
        /// <summary>
        /// Cancel Text
        /// </summary>
        public string CancelText
        {
            get { return (string)GetValue(CancelTextProperty); }
            set { SetValue(CancelTextProperty, value); }
        }
        /// <summary>
        /// Cancel Text (Multi Language) 
        /// </summary>
        public List<M_Language> CancelLanguageText
        {
            get { return (List<M_Language>)GetValue(CancelLanguageTextProperty); }
            set { SetValue(CancelLanguageTextProperty, value); }
        }
        /// <summary>
        /// Ok Text
        /// </summary>
        public string OkText
        {
            get { return (string)GetValue(OkTextProperty); }
            set { SetValue(OkTextProperty, value); }
        }
        /// <summary>
        /// Ok Text (Multi Language) 
        /// </summary>
        public List<M_Language> OkLanguageText
        {
            get { return (List<M_Language>)GetValue(OkLanguageTextProperty); }
            set { SetValue(OkLanguageTextProperty, value); }
        }
        /// <summary>
        /// Noraml Bakcground 
        /// </summary>
        public string NormalBrush
        {
            get { return (string)GetValue(NormalBrushProperty); }
            set { SetValue(NormalBrushProperty, value); }
        }
        /// <summary>
        /// Mouse/Touch Down Bakcground 
        /// </summary>
        public string DownBrush
        {
            get { return (string)GetValue(DownBrushProperty); }
            set { SetValue(DownBrushProperty, value); }
        }
        /// <summary>
        /// Cancel Button NormalBrush
        /// </summary>
        public string CancelNormalBrush
        {
            get { return (string)GetValue(CancelNormalBrushProperty); }
            set { SetValue(CancelNormalBrushProperty, value); }
        }
        /// <summary>
        /// Mouse/Touch Down Bakcground 
        /// </summary>
        public string CancelDownBrush
        {
            get { return (string)GetValue(CancelDownBrushProperty); }
            set { SetValue(CancelDownBrushProperty, value); }
        }
        /// <summary>
        /// OK Button NormalBrush
        /// </summary>
        public string OkNormalBrush
        {
            get { return (string)GetValue(OkNormalBrushProperty); }
            set { SetValue(OkNormalBrushProperty, value); }
        }
        /// <summary>
        /// Mouse/Touch Down Bakcground 
        /// </summary>
        public string OkDownBrush
        {
            get { return (string)GetValue(OkDownBrushProperty); }
            set { SetValue(OkDownBrushProperty, value); }
        }
        /// <summary>
        /// Ok Button DisableBrush
        /// </summary>
        public string OkDisableBrush
        {
            get { return (string)GetValue(OkDisableBrushProperty); }
            set { SetValue(OkDisableBrushProperty, value); }
        }
        
        /// <summary>
        /// Ok Switch Enable Background
        /// </summary>
        public string OkSwitchOnBrush
        {
            get { return (string)GetValue(OkSwitchOnBrushProperty); }
            set { SetValue(OkSwitchOnBrushProperty, value); }
        }
        /// <summary>
        /// Button Animation Type
        /// </summary>
        public ButtonAnimationType ClickAnimationType
        {
            get { return (ButtonAnimationType)GetValue(ClickAnimationTypeProperty); }
            set { SetValue(ClickAnimationTypeProperty, value); }
        }
        /// <summary>
        /// Button Text Foreground
        /// </summary>
        public string TextForeground
        {
            get { return (string)GetValue(TextForegroundProperty); }
            set { SetValue(TextForegroundProperty, value); }
        }
        /// <summary>
        /// Cancel Button Foreground
        /// </summary>
        public string CancelForeground
        {
            get { return (string)GetValue(CancelForegroundProperty); }
            set { SetValue(CancelForegroundProperty, value); }
        }
        #endregion Members

        #region [ Ctor/Etc ]
        /// <summary>
        /// Ctor
        /// </summary>
        public NumericPad()
        {
            InitializeComponent();
            
            foreach (var aElement in this.BaseGrid.Children)
            {
                if (aElement is AnimationButton aNumberButton)
                {
                    aNumberButton.MouseClicked += NumberButton_MouseClicked;
                }
            }
        }

        #endregion Ctor

        #region [ Methods ]

        private void SetShowText(string _showText)
        {
            string displayText = _showText;
            if (!string.IsNullOrEmpty(displayText))
            {
                if (displayText.Length <11)
                {
                    //pass
                }
                else if (displayText.Length.Equals(11))
                {
                    var displayChars = displayText.ToCharArray();
                    displayText = string.Empty;
                    for (int i = 0; i < displayChars.Length; i++)
                    {
                        if (i > 2 && i < 7)
                        {
                            displayText += '*';
                        }
                        else
                        {
                            displayText += displayChars[i];
                        }
                    }
                }
                else if (displayText.Length < 17)
                {
                    var displayChars = displayText.ToCharArray();
                    displayText = string.Empty;
                    for (int i = 0; i < displayChars.Length; i++)
                    {
                        if (i > 5 && i < 14)
                        {
                            displayText += '*';
                        }
                        else
                        {
                            displayText += displayChars[i];
                        }
                    }

                }
                else
                {
                    var displayChars = displayText.ToCharArray();
                    displayText = string.Empty;
                    for (int i = 0; i < displayChars.Length; i++)
                    {
                        if (i > 3 && i < 16)
                        {
                            displayText += '*';
                        }
                        else
                        {
                            displayText += displayChars[i];
                        }
                    }
                }
                string formatedString = string.Empty;

                if (displayText.Length.Equals(11))
                {
                    formatedString = string.Format("{0}-{1}-{2}"
                                            , displayText.Substring(0, 3)
                                            , displayText.Substring(3, 4)
                                            , displayText.Substring(7, 4));
                }
                else if (displayText.Length.Equals(16))
                {
                    formatedString = string.Format("{0}-{1}-{2}-{3}"
                                            , displayText.Substring(0, 4)
                                            , displayText.Substring(4, 4)
                                            , displayText.Substring(8, 4)
                                            , displayText.Substring(12, 4));
                }
                else if (displayText.Length.Equals(20))
                {
                    formatedString = string.Format("{0}-{1}-{2}-{3}-{4}"
                                            , displayText.Substring(0, 4)
                                            , displayText.Substring(4, 4)
                                            , displayText.Substring(8, 4)
                                            , displayText.Substring(12, 4)
                                            , displayText.Substring(16, 4));
                }
                if (!string.IsNullOrEmpty(formatedString)) displayText =  formatedString;
                
            }
            if (string.IsNullOrEmpty(displayText))
            {

                this.ShowText = this.GuidText.GetLanguageData(this.DisplayLanguage);
                this.OkEnabled = false;
            }
            else
            {
                this.ShowText = displayText;
                this.OkEnabled = true;
            }
        }
        private double SetEtcTextFontSize(AnimationButton _target, string _text)
        {
            double result = 20d;
            try
            {
                var textLength = string.IsNullOrEmpty(_text.Trim()) ? 1 : _text.Trim().Length;
                var fontSize = 0d;
                switch (textLength)
                {
                    case 1:
                    case 2:
                        fontSize = 0.7;
                        break;
                    case 3:
                        fontSize = 0.5;
                        break;
                    case 4:
                        fontSize = 0.45;
                        break;
                    default:
                        fontSize = 0.40;
                        break;
                }
                result = _target.ActualHeight > 0 ? _target.ActualHeight * fontSize : 20d;

            }
            catch 
            {
                result = 20d;
            }
            return result;
        }
        #endregion Methods

        #region [ Event Handlers ]
        private static void OnNormalBrushPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null )
            {
                var target = d as NumericPad;
                ResourceManager.SetBrush(target.ShowDataGrid, "Background", (string)e.NewValue);
            }
        }
        private static void OnTextForegroundPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null )
            {
                var target = d as NumericPad;
                ResourceManager.SetBrush(target.ShowData, "Foreground", (string)e.NewValue);
            }
        }
        private static void OnEtcTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null )
            {
                var target = d as NumericPad;
                var aElement = target.BaseGrid.FindName("ButtonEtc");
                if (aElement is AnimationButton aNumberButton)
                {
                    //aNumberButton.Text = (string)e.NewValue;
                    var newFontSize = target.SetEtcTextFontSize(aNumberButton, (string)e.NewValue);
                    if (!newFontSize.Equals(20)) target.ButtonEtc.TextFontSize = newFontSize;
                    
                }
            }
        }
        private static void OnCancelTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null )
            {
                var target = d as NumericPad;
                var aElement = target.BaseGrid.FindName("ButtonCancel");
                if (aElement is AnimationButton aNumberButton)
                {
                    var newFontSize = target.SetEtcTextFontSize(aNumberButton, (string)e.NewValue);
                    if (newFontSize < target.ButtonOK.TextFontSize)
                    {
                        target.ButtonOK.TextFontSize = newFontSize;
                        target.ButtonCancel.TextFontSize = newFontSize;
                    }
                }
                
            }
        }
        private static void OnCancelLanguageTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null )
            {
                var target = d as NumericPad;
                var aElement = target.BaseGrid.FindName("ButtonCancel");
                if (aElement is AnimationButton aNumberButton)
                {
                    var newFontSize = target.SetEtcTextFontSize(aNumberButton
                                                                ,((List<M_Language>)e.NewValue).GetLanguageData(target.DisplayLanguage));
                    if (newFontSize < target.ButtonOK.TextFontSize)
                    {
                        target.ButtonOK.TextFontSize = newFontSize;
                        target.ButtonCancel.TextFontSize = newFontSize;
                    }
                }
            }
        }
        private static void OnOkTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null )
            {
                var target = d as NumericPad;
                var aElement = target.BaseGrid.FindName("ButtonOK");
                if (aElement is AnimationButton aNumberButton)
                {
                    var newFontSize = target.SetEtcTextFontSize(aNumberButton, (string)e.NewValue);
                    if (newFontSize < target.ButtonCancel.TextFontSize)
                    {
                        target.ButtonOK.TextFontSize = newFontSize;
                        target.ButtonCancel.TextFontSize = newFontSize;
                    }
                }
            }
        }
        private static void OnOkLanguageTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null )
            {
                var target = d as NumericPad;
                var aElement = target.BaseGrid.FindName("ButtonOK");
                if (aElement is AnimationButton aNumberButton)
                {
                    var newFontSize = target.SetEtcTextFontSize(aNumberButton
                                                                , ((List<M_Language>)e.NewValue).GetLanguageData(target.DisplayLanguage));
                    if (newFontSize < target.ButtonCancel.TextFontSize)
                    {
                        target.ButtonOK.TextFontSize = newFontSize;
                        target.ButtonCancel.TextFontSize = newFontSize;
                    }
                }
            }
        }
        private static void OnDisplayLanguageProperyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null )
            {
                var target = d as NumericPad;
                foreach (var aElement in target.BaseGrid.Children)
                {
                    if (aElement is AnimationButton aNumberButton
                        && (aNumberButton.Name.StartsWith("ButtonOK")
                            || aNumberButton.Name.StartsWith("ButtonCancel"))
                        )
                    {
                        aNumberButton.DisplayLanguage = (SupportLanguageType)e.NewValue;
                    }
                }
                target.SetShowText(target.InputText);
            }
        }
        private static void OnInputTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var target = d as NumericPad;
            var inputText = (string)e.NewValue;
            target.SetShowText(inputText);
        }
        private static void OnShowTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var target = d as NumericPad;
            var showText = (string)e.NewValue;
            target.ShowData.Text = showText;

        }
        private void NumberButton_MouseClicked(object sender, RoutedEventArgs e)
        {
            if (sender is AnimationButton aNumberButton)
            {
                switch (aNumberButton.Name)
                {
                    case nameof(ButtonOK):
                        if (OkCommand != null && OkCommand.CanExecute(this))
                        {
                            OkCommand.Execute(this);
                        }
                        break;
                    case nameof(ButtonCancel):
                        this.InputText = string.Empty;
                        if (CancelCommand != null && CancelCommand.CanExecute(this))
                        {
                            CancelCommand.Execute(this);
                        }
                        break;
                    case nameof(ButtonBack):
                        if (this.InputText != null && this.InputText.Length > 0)
                        {
                            if (this.InputText.Equals(this.EtcText))
                            {
                                this.InputText = string.Empty;
                            }
                            else
                            {
                                this.InputText = this.InputText.Remove(this.InputText.Length - 1, 1);
                            }
                        }
                        break;
                    default:
                        this.InputText = this.InputText + aNumberButton.Text;
                        break;
                }
            }
        }

        #endregion Event Handlers
    }

}
