﻿
Type.registerNamespace("Bondgate");

Bondgate.NumericInputBehaviour = Class.register();

/// <summary>
/// Attaches numeric edit behaviour to a text input.
/// </summary>
Bondgate.NumericInputBehaviour.prototype =
{
    /// <summary>
    /// Initializes a new instance of the class.
    /// </summary>
    construct: function(element, properties)
    {
        if (properties == null)
            properties = { "originalValue": "", "decimalPrecision": 0, "prefix": "", "suffix": "", "autoHighlight": true };

        var m_input = $extend(element);
        var m_decimals = properties.decimalPrecision;
        var m_prefix = properties.prefix;
        var m_suffix = properties.suffix;
        var m_autoHighlight = properties.autoHighlight;
        var m_originalValue = properties.originalValue;

        this.changed = new EventObject();

        this.format = function(value)
        {
            var number = new Number();
            var result = "";

            if (value.length > 0) 
            {
                if (m_prefix.length > 0)
                    value = value.replace(m_prefix, "");

                if (m_suffix.length > 0)
                    value = value.replace(m_suffix, "");
            
                if (value == ".")
                    value += "0".duplicate(m_decimals);

                if (this.validate(value))
                {
                    number = new Number(value);
                    result = m_prefix + number.toFixed(m_decimals).toString() + m_suffix
                }
            }

            return result;
        };

        this.unformat = function(value)
        {
            if ((m_prefix != null) && (m_prefix.length > 0))
            {
                if (value.indexOf(m_prefix) == 0)
                    value = value.substr(m_prefix.length, value.length - m_prefix.length);
            }

            if ((m_suffix != null) && (m_suffix.length > 0))
            {
                if (value.indexOf(m_suffix) > 0)
                    value = value.substr(0, value.length - m_suffix.length);
            }

            return value.trim();
        };

        this.validate = function(value)
        {
            var regex = /^((-?\d*\.?\d+)|(-?\d+\.?\d*))?$/;
            return regex.test(value);
        };

        _init.call(this); // Invokes the _init() method when an instance is constructed.

        function _init()
        {
            m_input.get_formattedValue = function() { return _format.call(this); };

            if (m_prefix == null) m_prefix = "";
            if (m_suffix == null) m_suffix = "";
            if (m_decimals == null) m_decimals = 0;
            if (m_autoHighlight == null) m_autoHighlight = true;

            m_input.originalValue = m_originalValue;
            m_input.value = this.format(m_input.value);

            _dispose.call(this);

            window.events.addHandler(window, "unload", this, _onBlur);
            window.events.addHandler(m_input, "focus", this, _onFocus);
            window.events.addHandler(m_input, "blur", this, _onBlur);
            window.events.addHandler(m_input, "keypress", this, _onKeyPress);
            window.events.addHandler(m_input, "dragstart", this, _onDragStart);
            window.events.addHandler(m_input, "dragend", this, _onDragEnd);
            window.events.addHandler(m_input, "paste", this, _onPaste);
        }

        function _dispose()
        {
            window.events.removeHandler(m_input, "paste", this, _onPaste);
            window.events.removeHandler(m_input, "dragend", this, _onDragEnd);
            window.events.removeHandler(m_input, "dragstart", this, _onDragStart);
            window.events.removeHandler(m_input, "keypress", this, _onKeyPress);
            window.events.removeHandler(m_input, "blur", this, _onBlur);
            window.events.removeHandler(m_input, "focus", this, _onFocus);
            window.events.removeHandler(window, "unload", this, _onBlur);
        }

        function _change(value)
        {
            m_input.value = value;
            this.changed.raise(this, new EventArgs(value));
        }

        function _onBlur(e)
        {
            if (m_input.value.length > 0)
                _change.call(this, this.format(m_input.value));
        }

        function _onDragStart(e)
        {
            return false;
        }

        function _onDragEnd(e)
        {
            return false;
        }

        function _onFocus(e)
        {
            if (m_input.value.length > 0)
            {
                var value = this.unformat(m_input.value);

                if (m_input.value != value)
                    _change.call(this, value);

                if (m_autoHighlight)
                    m_input.select();
            }
        }

        function _onKeyPress(e)
        {
            var result = false;

            if (e.character == "-")
            {
                result = _onMinusKeyDown.call(this, e);
            }
            else if (e.character == ".")
            {
                result = _onPeriodKeyDown.call(this, e);
            }
            else
            {
                switch (true)
                {
                    case e.numeric:
                    case e.enter:
                    case e.tab:
                    case e.backspace:
                    case e.escape:
                    case e.navigation:
                    case e.fn:
                        result = true;
                        break;
                }
            }

            e.returnValue = result;
            e.cancelBubble = !result;

            return result;
        }

        function _onMinusKeyDown(e)
        {
            return (m_input.getCursorPosition() == 0);
        }

        function _onPeriodKeyDown(e)
        {
            var result = false;

            if (m_decimals > 0)
            {
                var charIndex = m_input.value.indexOf(".");

                if (charIndex < 0)
                {
                    result = true;
                }
                else
                {
                    var selStart = m_input.getCursorPosition();
                    var selEnd = m_input.getSelectionEnd();
                    var selection = "";

                    if (selStart > selEnd)
                    {
                        selStart = selEnd;
                        selEnd = selStart;
                    }

                    selection = m_input.value.substring(selStart, selEnd);

                    if (selection.length == m_input.value.length)
                    {
                        m_input.value = "0.";
                        m_input.setSelection(2);
                    }
                    else if (selection.length == 0)
                    {
                        if (charIndex == selStart)
                        {
                            m_input.value = m_input.value.substr(0, charIndex + 1);
                            m_input.setSelection(charIndex + 1);
                        }
                    }
                    else
                    {
                        charIndex = selection.indexOf(".");

                        if (charIndex >= 0)
                        {
                            if (selStart == 0)
                                m_input.value = "0.";
                            else
                                m_input.value = m_input.value.substr(0, selStart) + ".";

                            m_input.setSelection(m_input.value.length);
                        }
                    }
                }
            }

            return result;
        }

        function _onPaste(e)
        {
            if (clipboardData.getData)
            {
                if (m_input.getSelection() == m_input.value)
                {
                    var result = false;
                    var text = window.clipboardData.getData("Text")

                    // TODO: Test this thoroughly with dodgy values, could go horribly wrong
                    text = this.unformat(text);

                    if (this.validate(text))
                    {
                        _change.call(this, text);
                        m_input.select();
                    }
                }
            }

            return false;
        }
    }
};
if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();