using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace SJ.Controls
{
    [StyleTypedProperty(Property = "Style", StyleTargetType = typeof(BTextBox))]
    public class BTextBox : TextBox
    {
        #region Property

        private bool IsResponseChange;
        private StringBuilder PasswordBuilder;
        private int lastOffset;

        #endregion

        #region DependencyProperty

        public static readonly DependencyProperty WaterRemarkProperty = DependencyProperty.Register("WaterRemark", typeof(string), typeof(BTextBox));
        public static readonly DependencyProperty WaterRemarkFontColorProperty = DependencyProperty.Register("WaterRemarkFontColor", typeof(Brush), typeof(BTextBox));
        public static readonly DependencyProperty BorderCornerRadiusProperty = DependencyProperty.Register("BorderCornerRadius", typeof(CornerRadius), typeof(BTextBox));
        public static readonly DependencyProperty IsPasswordBoxProperty = DependencyProperty.Register("IsPasswordBox", typeof(bool), typeof(BTextBox), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnIsPasswordBoxChnage)));
        public static readonly DependencyProperty IsNumberBoxProperty = DependencyProperty.Register("IsNumberBox", typeof(bool), typeof(BTextBox), new PropertyMetadata(false, new PropertyChangedCallback(OnIsNumberBoxChnage)));
        public static readonly DependencyProperty DisableBgColorProperty = DependencyProperty.Register("DisableBgColor", typeof(Brush), typeof(BTextBox));
        public static readonly DependencyProperty PasswordCharProperty = DependencyProperty.Register("PasswordChar", typeof(char), typeof(BTextBox), new FrameworkPropertyMetadata('●'));
        public static readonly DependencyProperty PasswordStrProperty = DependencyProperty.Register("PasswordStr", typeof(string), typeof(BTextBox), new FrameworkPropertyMetadata(string.Empty, new PropertyChangedCallback(OnPasswordStrChanged)));

        /// <summary>
        /// 水印文字 
        /// </summary>
        public string WaterRemark
        {
            get { return GetValue(WaterRemarkProperty).ToString(); }
            set { SetValue(WaterRemarkProperty, value); }
        }

        public Brush WaterRemarkFontColor
        {
            get { return GetValue(WaterRemarkFontColorProperty) as Brush; }
            set { SetValue(WaterRemarkFontColorProperty, value); }
        }

        /// <summary>
        /// 边框角度
        /// </summary>
        public CornerRadius BorderCornerRadius
        {
            get { return (CornerRadius)GetValue(BorderCornerRadiusProperty); }
            set { SetValue(BorderCornerRadiusProperty, value); }
        }

        /// <summary>
        /// 是否为密码框
        /// </summary>
        public bool IsPasswordBox
        {
            get { return (bool)GetValue(IsPasswordBoxProperty); }
            set { SetValue(IsPasswordBoxProperty, value); }
        }

        /// <summary>
        /// 是否为数字框
        /// </summary>
        public bool IsNumberBox
        {
            get { return (bool)GetValue(IsNumberBoxProperty); }
            set { SetValue(IsNumberBoxProperty, value); }
        }

        /// <summary>
        /// 替换明文的密码字符
        /// </summary>
        public char PasswordChar
        {
            get { return (char)GetValue(PasswordCharProperty); }
            set { SetValue(PasswordCharProperty, value); }
        }

        /// <summary>
        /// 密码字符串
        /// </summary>
        public string PasswordStr
        {
            get
            {
                var value = GetValue(PasswordStrProperty);
                return value == null ? string.Empty : value.ToString();
            }
            set { SetValue(PasswordStrProperty, value); }
        }

        /// <summary>                                                                                                                                     
        /// 按钮被禁用时的背景颜色
        /// </summary>
        public Brush DisableBgColor
        {
            get { return GetValue(DisableBgColorProperty) as Brush; }
            set { SetValue(DisableBgColorProperty, value); }
        }
        #endregion


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

        public BTextBox()
        {
            IsResponseChange = true;
            PasswordBuilder = new StringBuilder();
            this.Loaded += QLTextBox_Loaded;
        }

        private void QLTextBox_Loaded(object sender, RoutedEventArgs e)
        {
            if (IsPasswordBox && !string.IsNullOrEmpty(PasswordStr) && PasswordStr.Length > 0)
            {
                OnPasswordStrChanged();
            }
        }

        private static void OnPasswordStrChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
        {
            (d as BTextBox).OnPasswordStrChanged();
        }

        private void OnPasswordStrChanged()
        {
            if (!IsResponseChange)
                return;
            IsResponseChange = false;
            this.Text = ConvertToPasswordChar(PasswordStr.Length);
            IsResponseChange = true;
        }

        private static void OnIsPasswordBoxChnage(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            (sender as BTextBox).SetPwdEvent();
        }

        private static void OnIsNumberBoxChnage(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            (sender as BTextBox).SetValidationNumberEvent();
        }

        /// <summary>
        /// 定义TextChange事件
        /// </summary>
        private void SetPwdEvent()
        {
            if (IsPasswordBox)
                this.TextChanged += QLTextBox_TextChanged;
            else
                this.TextChanged -= QLTextBox_TextChanged;
        }

        private void SetValidationNumberEvent()
        {
            if (IsNumberBox)
                this.PreviewTextInput += QLTextBox_PreviewTextInput;
            else
                this.PreviewTextInput -= QLTextBox_PreviewTextInput;
        }

        private void QLTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (!IsResponseChange)
                return;
            IsResponseChange = false;
            foreach (TextChange c in e.Changes)
            {
                PasswordStr = PasswordStr.Remove(c.Offset, c.RemovedLength);
                PasswordStr = PasswordStr.Insert(c.Offset, Text.Substring(c.Offset, c.AddedLength));
                lastOffset = c.Offset;
            }
            /*将文本转换为密码字符*/
            this.Text = ConvertToPasswordChar(Text.Length);
            IsResponseChange = true;
            this.SelectionStart = lastOffset + 1;
        }

        private void QLTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            Regex re = new Regex("[^0-9.]+");
            e.Handled = re.IsMatch(e.Text);
        }


        /// <summary>
        /// 按照指定的长度生成密码字符
        /// </summary>
        /// <param name="length"></param>
        /// <returns></returns>
        private string ConvertToPasswordChar(int length)
        {
            if (PasswordBuilder != null)
                PasswordBuilder.Clear();
            else
                PasswordBuilder = new StringBuilder();
            for (var i = 0; i < length; i++)
                PasswordBuilder.Append(PasswordChar);
            return PasswordBuilder.ToString();
        }
    }
}