﻿
Type.registerNamespace("PlainJoeStudios.Web.Controls");

/////////////////////
// CONSTRUCTORS
/////////////
PlainJoeStudios.Web.Controls.EditableLabel = function(params)
{
    // grab values
    this._JqLabel = $("#" + params["LabelId"]);
    this._JqTextBox = $("#" + params["TextBoxId"]);
    if (typeof (params["ButtonEditId"]) === "string")
    {
        this._JqButtonEdit = $("#" + params["ButtonEditId"]);
    }
    if (typeof (params["ButtonSaveId"]) === "string")
    {
        this._JqButtonSave = $("#" + params["ButtonSaveId"]);
    }
    if (typeof (params["ButtonCancelId"]) === "string")
    {
        this._JqButtonCancel = $("#" + params["ButtonCancelId"]);
    }
    if (typeof (params["AnimationSpeed"]) !== "number")
    {
        throw new Error("AnimationSpeed must be a number.");
    }
    this._AnimationSpeed = params["AnimationSpeed"];
    this._EmptyText = params["EmptyText"];
    this._Text = params["Text"];
    this._AjaxUrl = params["AjaxUrl"];
    this._AjaxExtraData = params["AjaxExtraData"];
    this._CssClassSaving = params["CssClassSaving"];
    this._CssClassSaved = params["CssClassSaved"];
    this._CssClassEditing = params["CssClassEditing"];
    this._OnClientFocus = new Function(params["OnClientFocus"]);
    this._OnClientTextChange = new Function(params["OnClientTextChange"]);
    this._IsEditing = params["InitiallyEdit"];
    this._ClearTextFieldOnEdit = params["ClearTextFieldOnEdit"];
    this._OnlySubmitChanges = params["OnlySubmitChanges"];

    this.Initialize();
};


/////////////////////
// PROTOTYPE
/////////////
PlainJoeStudios.Web.Controls.EditableLabel.prototype =
{
    /////////////////////
    // FIELDS
    /////////////
    _IsEditing: false,
    _JqLabel: null,
    _JqTextBox: null,
    _JqButtonEdit: null,
    _JqButtonSave: null,
    _JqButtonCancel: null,
    _AnimationSpeed: null,
    _EmptyText: null,
    _Text: null,
    _AjaxUrl: null,
    _AjaxExtraData: null,
    _BlurFired: false,
    _CssClassSaving: null,
    _CssClassSaved: null,
    _CssClassEditing: null,
    _OnClientFocus: null,
    _OnClientTextChange: null,
    _OnlySubmitChanges: false,
    _ClearTextFieldOnEdit: false,



    /////////////////////
    // METHODS
    /////////////
    Initialize: function()
    {
        var This = this;

        // is there already an instance of this class active on these controls?
        if (this._JqLabel.data("PlainJoeStudios.Web.Controls.EditableLabel") == true)
        {
            return;
        }

        // mark this control as active.
        this._JqLabel.data("PlainJoeStudios.Web.Controls.EditableLabel", true);

        //////
        // bind handlers
        this._JqLabel.click(function(p1, p2) { This.Label_Click(p1, p2); });
        this._JqTextBox.blur(function(p1, p2) { This.TextBox_Blur(p1, p2); });
        this._JqTextBox.keypress(function(p1, p2) { This.TextBox_KeyPress(p1, p2); });
        if (this._JqButtonEdit != null)
        {
            this._JqButtonEdit.click(function() { This.Button_Edit_Click(); });
        }
        if (this._JqButtonSave != null)
        {
            this._JqButtonSave.click(function() { This.Button_Save_Click(); });
        }
        if (this._JqButtonCancel != null)
        {
            this._JqButtonCancel.click(function() { This.Button_Cancel_Click(); });
        }

        var textBoxCurrentlyHidden = this._JqTextBox.css("display") == "none";
        this._JqTextBox.css("display", "block");
        if (textBoxCurrentlyHidden)
        {
            this._JqTextBox.hide();
        }
    },


    /////////////////////
    // EVENT HANDLERS
    /////////////
    Label_Click: function()
    {
        this.SwitchToModeEdit();
    },

    Button_Edit_Click: function()
    {
        if (this._IsEditing !== true)
        {
            this.SwitchToModeEdit();
        }
    },

    Button_Save_Click: function()
    {
        if (this._IsEditing === true)
        {
            this.SwitchToModeView();
        }
    },

    Button_Cancel_Click: function()
    {
        if (this._IsEditing === true)
        {
            this.SwitchToModeView(true);
        }
    },

    TextBox_Blur: function()
    {
        if (this._JqButtonSave != null)
        {
            return;
        }
        else
        {
            this.SwitchToModeView();
        }
    },

    TextBox_KeyPress: function(p1, p2)
    {
        var key = p1.which;
        var ctrlHeld = p1.ctrlKey;
        var tagName = this._JqTextBox[0].tagName.toLowerCase();
        if ((tagName === "input" && (key === 10 || key === 13))
            || (tagName === "textarea" && ctrlHeld && (key === 10 || key === 13)))
        {
            // stop posting
            p1.preventDefault();

            // blur the textbox
            this.SwitchToModeView();
        }
    },

    SaveData_Success: function(savedValue)
    {
        this._AjaxInProgress = false;

        // remember new value
        this._Text = savedValue;

        // face out
        this.FadeToLabel(true);
    },

    SaveData_Failure: function()
    {
        this._AjaxInProgress = false;

        this.FadeToLabel();
    },


    /////////////////////
    // METHODS
    /////////////
    SwitchToModeEdit: function()
    {
        this._IsEditing = true;
        if (this._JqButtonEdit != null)
        {
            this._JqButtonEdit.hide();
        }
        if (this._JqButtonSave != null)
        {
            this._JqButtonSave.show();
        }
        if (this._JqButtonCancel != null)
        {
            this._JqButtonCancel.show();
        }
        this.FadeToTextBox();
        if (this._ClearTextFieldOnEdit)
        {
            this._JqTextBox.val("");
        }
    },

    SwitchToModeView: function(cancelChanges)
    {
        var This = this;
        this._IsEditing = false;
        if (this._JqButtonSave != null)
        {
            this._JqButtonSave.hide();
        }
        if (this._JqButtonCancel != null)
        {
            this._JqButtonCancel.hide();
        }

        if (this._BlurFired)
        {
            return;
        }
        this._BlurFired = true;

        // store the text
        var newText;

        // cancel changes?
        if (cancelChanges === true)
        {
            this._JqTextBox.val(this._Text);
            newText = this._Text;
        }
        else
        {
            newText = this._JqTextBox.val();
        }

        //////
        // update span's value
        var labelText = newText;
        if (labelText == "")
        {
            labelText = this._EmptyText;
        }

        var labelTextEncoded
            = labelText
                .replace((/</g), "&lt;")
                .replace((/>/g), "&gt;")
                .replace((/&/g), "&amp;")
                .replace((/"/g), "&quot;")
                .replace((/\r\n/g), "<br />")
                .replace((/\n/g), "<br />");
        this._JqLabel.html(labelTextEncoded);

        // custom code?
        if (typeof (this._OnClientTextChange) === "function" && ((this._Text !== newText) || (!this._OnlySubmitChanges)))
        {
            this._OnClientTextChange(newText);
        }

        // do we need to post right away?
        if (this._AjaxUrl != null && ((this._Text !== newText) || (!this._OnlySubmitChanges)))
        {
            // enable the "saving" class
            this._JqTextBox.addClass(this._CssClassSaving);

            // post to server
            this.SaveDataToServer(newText);
        }
        else
        {
            // go back to normal
            this.FadeToLabel(false);
        }
    },

    FadeToTextBox: function()
    {
        var This = this;

        //////
        // hide the span
        this._JqLabel.hide();

        //////
        // display the input
        this._JqTextBox.animate({ opacity: "show" }, this._AnimationSpeed, null, function() { This._JqTextBox.focus(); This._JqTextBox[0].select(); });

        //////
        // ensure input style
        this._JqTextBox.addClass(This._CssClassEditing);

        //////
        // additional focus code?
        if (typeof (this._OnClientFocus) === "function")
        {
            this._OnClientFocus();
        }
    },

    FadeToLabel: function(showSavedEffect)
    {
        var This = this;

        //////
        // hide the textbox & show label
        this._JqTextBox.animate(
            {
                opacity: "hide"
            },
            this._AnimationSpeed,
            null,
            function()
            {
                This._JqTextBox.removeClass(This._CssClassSaving);
                This._JqLabel.show();
                if (showSavedEffect)
                {
                    This._JqLabel.addClass(This._CssClassSaved);
                    window.setTimeout(
                        function()
                        {
                            This._JqLabel.removeClass(This._CssClassSaved);
                            if (This._JqButtonEdit != null)
                            {
                                This._JqButtonEdit.show();
                            }
                        },
                        This._AnimationSpeed);
                }
                else
                {
                    if (This._JqButtonEdit != null)
                    {
                        This._JqButtonEdit.show();
                    }
                }

                // reset the commit tracker
                This._BlurFired = false;
            });
    },

    SaveDataToServer: function(newValue)
    {
        var This = this;

        jQuery.ajax(
        {
            cache: false,
            data: { "Value": newValue, "ExtraData": this._AjaxExtraData },
            dataType: "text",
            success: function() { This.SaveData_Success(newValue); },
            error: function() { This.SaveData_Failure(); },
            type: "POST",
            url: this._AjaxUrl
        });
    }
};

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();