﻿Type.registerNamespace('Pacem.UI');

Pacem.UI.MaxCharsBehavior = function(element) {

    Pacem.UI.MaxCharsBehavior.initializeBase(this, [element]);

    this._keyup_handler = null;
    this._keydown_handler = null;
    this._deny_handler = null;
    this._focus_handler = null;
    this._blur_handler = null;
    this._applicationLoadDelegate = null;
    //
    this._cwf = "{0} out of {1} chars written.";
    this._maxChars = Number.MAX_VALUE;
    //
    this._flyOutLabel = null;
    this._flyOutLabelCssClass = null;
    //
    this._onShowJson = null;
    this._onHideJson = null;
    this._popupBehavior = null;
    //
    this._scopeValue = null;
    this._flyoutStyleInitialized = false;
}

Pacem.UI.MaxCharsBehavior.prototype = {

    initialize: function() {
        Pacem.UI.MaxCharsBehavior.callBaseMethod(this, 'initialize');

        var el = this.get_element(); // textbox
        if (this._maxChars != Number.MAX_VALUE) el.maxLength = this._maxChars;
        //
        this._keyup_handler = Function.createDelegate(this, this.keyUpHandler);
        this._keydown_handler = Function.createDelegate(this, this.keyDownHandler);
        this._focus_handler = Function.createDelegate(this, this.focusHandler);
        this._blur_handler = Function.createDelegate(this, this.blurHandler);
        this._deny_handler = Function.createDelegate(this, this.denyHandler);
        $addHandler(el, "keyup", this._keyup_handler);
        $addHandler(el, "keydown", this._keydown_handler);
        $addHandler(el, "focus", this._focus_handler);
        $addHandler(el, "blur", this._blur_handler);
        $addHandler(el, "contextmenu", this._deny_handler);
        $addHandler(el, "dragenter", this._deny_handler);

        this._applicationLoadDelegate = Function.createDelegate(this, this.onApplicationLoad);
        Sys.Application.add_load(this._applicationLoadDelegate);
    },

    dispose: function() {
        // CLEAN-UP
        var el = this.get_element();

        var flyOutLabel = this._flyOutLabel;

        if (flyOutLabel) {
            this._flyOutLabel = null;
            if (flyOutLabel.parentNode == el.parentNode)
                el.parentNode.removeChild(flyOutLabel);
        }
        this.disposePopupBehavior();

        $removeHandler(el, "keyup", this._keyup_handler);
        $removeHandler(el, "keydown", this._keydown_handler);
        $removeHandler(el, "focus", this._focus_handler);
        $removeHandler(el, "blur", this._blur_handler);
        $removeHandler(el, "contextmenu", this._deny_handler);
        $removeHandler(el, "dragenter", this._deny_handler);
        this._onShowJson = null;
        this._onHideJson = null;
        Pacem.UI.MaxCharsBehavior.callBaseMethod(this, 'dispose');
    },

    // PROPERTIES
    get_maxChars: function() {
        return this._maxChars;
    },
    set_maxChars: function(value) {
        this._maxChars = value;
    },

    get_charsWrittenFormat: function() {
        return this._cwf;
    },
    set_charsWrittenFormat: function(value) {
        this._cwf = value;
    },

    get_flyOutLabelCssClass: function() {
        return this._flyOutLabelCssClass;
    },

    set_flyOutLabelCssClass: function(value) {
        this._flyOutLabelCssClass = value;
    },

    // HANDLERS
    onApplicationLoad: function(sender, applicationLoadEventArgs) {
        var hasInitialFocus = false;

        var clientState = Pacem.UI.MaxCharsBehavior.callBaseMethod(this, 'get_ClientState');
        if (clientState != null && clientState != "") {
            hasInitialFocus = (clientState === "Focused");
            Pacem.UI.MaxCharsBehavior.callBaseMethod(this, 'set_ClientState', null);
        }

        if (hasInitialFocus) {
            this.focusHandler();
        }
    },
    keyUpHandler: function(evt) {
        var prevent = this.checkText(evt.target);
        if (prevent) {
            evt.preventDefault();
        }
        this.setText();
    },
    keyDownHandler: function(evt) {
        var el = evt.target;
        var el_txt = el.value;
        var el_txt_length = el.value.length;
        if (el_txt_length > this._maxChars) {
            evt.preventDefault();
        } else {
            this._scopeValue = el_txt;
        }
    },
    denyHandler: function(evt) {
        evt.preventDefault();
    },
    blurHandler: function(evt) {
        // last check
        this.checkText(evt.target);
        this.setText();
        //
        if (this._popupBehavior) {
            this._popupBehavior.hide();
        }
    },
    focusHandler: function(evt) {
        this.ensureFlyOutLabel();
        this.ensurePopupBehavior();
        this._popupBehavior.show();
        this._scopeValue = evt.target.value;
        this.setText();
    },
    checkText: function() {
        var el = arguments.length > 0 ? arguments[0] : this.get_element();
        var el_txt = el.value;
        var el_txt_length = el.value.length;
        if (el_txt_length > this._maxChars) {
            el.value = this._scopeValue;
            return false;
        } else return true;
    },
    setText: function() {
        this.ensurePopupBehavior();
        var el = this.get_element();
        var text = String.format(this._cwf, el.value.length, this._maxChars);
        /*
        ==== BUG TRAP: PopupExtender Behavior related with the Animation Framework  ====
        ==== the targetControl element remains hidden (even displayed 'none'!)...   ====
        */
        this._flyOutLabel.style.visibility = '';
        this._flyOutLabel.style.display = '';
        //  ================================================================================
        this._flyOutLabel.innerHTML = text;
    },
    ensurePopupBehavior: function() {
        if (!this._popupBehavior) {
            var el = this.get_element();
            this._popupBehavior = $create(AjaxControlToolkit.PopupBehavior,
                    { 'id': this.get_id() + '_PopupBehavior', 'parentElement': el, 'positioningMode': AjaxControlToolkit.PositioningMode.BottomLeft }, null, null, this._flyOutLabel);

            if (this._onShowJson) {
                this._popupBehavior.set_onShow(this._onShowJson);
            }
            if (this._onHideJson) {
                this._popupBehavior.set_onHide(this._onHideJson);
            }
        }
    },
    disposePopupBehavior: function() {
        if (this._popupBehavior) {
            this._popupBehavior.dispose();
            this._popupBehavior = null;
        }
    },
    //
    initializeFlyOutLabelStyle: function() {
        var element = this._flyOutLabel;
        var flyOutLabelStyle = element.style;
        var bounds = Sys.UI.DomElement.getBounds(this.get_element());
        flyOutLabelStyle.position = 'absolute';

        if (this._flyOutLabelCssClass) {
            flyOutLabelStyle.width = String.format("{0}px", bounds.width);
            Sys.UI.DomElement.addCssClass(element, this._flyOutLabelCssClass);
        } else {
            var _fo_padding = 4;
            flyOutLabelStyle.width = String.format("{0}px", bounds.width - 2 * _fo_padding);
            flyOutLabelStyle.textAlign = 'left';
            flyOutLabelStyle.cursor = 'default';
            flyOutLabelStyle.padding = String.format('{0}px', _fo_padding);
            flyOutLabelStyle.margin = '0px';
            if (Sys.Browser.agent === Sys.Browser.Safari) {
                flyOutLabelStyle.border = 'solid 1px gray';
                flyOutLabelStyle.backgroundColor = 'white';
                flyOutLabelStyle.color = 'black';
            } else {
                flyOutLabelStyle.border = 'solid 1px buttonshadow';
                flyOutLabelStyle.backgroundColor = 'window';
                flyOutLabelStyle.color = 'windowtext';
            }
        }
        Sys.UI.DomElement.setVisibilityMode(element, Sys.UI.VisibilityMode.collapse);
        Sys.UI.DomElement.setVisible(element, false);
        this._flyoutStyleInitialized = true;
    },
    ensureFlyOutLabel: function() {
        var el = this.get_element();
        if (!this._flyOutLabel) {
            // add flyOutLabel
            this._flyOutLabel = document.createElement('div');
            this._flyOutLabel.id = this.get_id() + '_flyOutElement';
            // Safari styles the element incorrectly if it's added to the desired location
            if (Sys.Browser.agent === Sys.Browser.Safari) {
                document.body.appendChild(this._flyOutLabel);
            } else {
                el.parentNode.insertBefore(this._flyOutLabel, el.nextSibling);
            }
        }
        if (!this._flyoutStyleInitialized && Sys.UI.DomElement.getVisible(el))
            this.initializeFlyOutLabelStyle();
    },

    // ANIMATION
    get_onShow: function() {
        return this._popupBehavior ? this._popupBehavior.get_onShow() : this._onShowJson;
    },
    set_onShow: function(value) {
        if (this._popupBehavior) {
            this._popupBehavior.set_onShow(value)
        } else {
            this._onShowJson = value;
        }
        this.raisePropertyChanged('onShow');
    },
    get_onShowBehavior: function() {
        return this._popupBehavior ? this._popupBehavior.get_onShowBehavior() : null;
    },
    onShow: function() {
        if (this._popupBehavior) {
            this._popupBehavior.onShow();
        }
    },

    get_onHide: function() {
        return this._popupBehavior ? this._popupBehavior.get_onHide() : this._onHideJson;
    },
    set_onHide: function(value) {
        if (this._popupBehavior) {
            this._popupBehavior.set_onHide(value)
        } else {
            this._onHideJson = value;
        }
        this.raisePropertyChanged('onHide');
    },
    get_onHideBehavior: function() {
        return this._popupBehavior ? this._popupBehavior.get_onHideBehavior() : null;
    },
    onHide: function() {
        if (this._popupBehavior) {
            this._popupBehavior.onHide();
        }
    }
}

Pacem.UI.MaxCharsBehavior.registerClass('Pacem.UI.MaxCharsBehavior', AjaxControlToolkit.BehaviorBase);

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();