﻿namespace MoveTorrent
{
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    using System.Windows.Interactivity;

    /// <summary>
    ///     An attached behavior that allows forces all input to a TextBox to be numeric
    /// </summary>
    public class NumericTextBoxBehavior : Behavior<TextBox>, ICloneableBehavior
    {
        public object CloneBehavior() { return new NumericTextBoxBehavior(); }

        protected override void OnDetaching()
        {
            base.OnDetaching();
            AssociatedObject.PreviewTextInput -= OnPreviewTextInput;

            DataObject.RemovePastingHandler(AssociatedObject, OnClipboardPaste);
        }

        /// <summary>
        ///     Called when attached to a TextBox.
        /// </summary>
        protected override void OnAttached()
        {
            AssociatedObject.PreviewTextInput += OnPreviewTextInput;
            DataObject.AddPastingHandler(AssociatedObject, OnClipboardPaste);
        }

        /// <summary>
        ///     This method handles paste and drag/drop events onto the TextBox.  It restricts the character
        ///     set and ensures we have consistent behavior.
        /// </summary>
        /// <param name="sender">TextBox sender</param>
        /// <param name="e">EventArgs</param>
        private void OnClipboardPaste(object sender, DataObjectPastingEventArgs e)
        {
            var text = e.SourceDataObject.GetData(e.FormatToApply) as string;

            if (!string.IsNullOrEmpty(text) && !Validate(text))
            {
                e.CancelCommand();
            }
        }

        /// <summary>
        ///     This checks if the resulting string will match the regex expression
        /// </summary>
        private void OnPreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            if (!Validate(e.Text))
            {
                e.Handled = true;
            }
        }

        private bool Validate(string newContent)
        {
            string testString;

            // replace selection with new text.
            if (!string.IsNullOrEmpty(AssociatedObject.SelectedText))
            {
                var pre = AssociatedObject.Text.Substring(0, AssociatedObject.SelectionStart);
                var after =
                    AssociatedObject.Text.Substring(
                        AssociatedObject.SelectionStart + AssociatedObject.SelectionLength, 
                        AssociatedObject.Text.Length
                        - (AssociatedObject.SelectionStart + AssociatedObject.SelectionLength));
                testString = pre + newContent + after;
            }
            else
            {
                var pre = AssociatedObject.Text.Substring(0, AssociatedObject.CaretIndex);
                var after = AssociatedObject.Text.Substring(
                    AssociatedObject.CaretIndex, 
                    AssociatedObject.Text.Length - AssociatedObject.CaretIndex);
                testString = pre + newContent + after;
            }

            int value;
            var isInt = int.TryParse(testString, out value);

            return isInt;
        }
    }
}