﻿/// <reference path="../jquery-vsdoc.js" />
// using "name*=" selector because of ID mangling

// This is some code related to editing data and navigating on maintenance pages.
// It is intended to make sure the user doesn't unintentionally navigate away from a page
// where there is unsaved data.
function NavHelper() {
    ////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Add the properties.
    // This is whether or not we need to check for changes and confirm with the user.
    this.needConfirmation = true;
    // This is the prompt that will display if the user tries to navigate away from a page without saving.
    this.dfltConfirmationPrompt = "You will lose any unsaved changes.";
    this.dfltSaveChangesPrompt = "There are unsaved changes to this information, which will be lost if you continue without saving first.\n" +
        "[OK]     Continue and lose unsaved changes.\n" +
        "[Cancel] Cancel this action in order to save changes first.";
    this.confirmationPrompt = this.dfltConfirmationPrompt;
    this.trackChanges = true;
    this._dataChangedControl = null;
    this._dataChanged = false;
    this._defaultButtonNames = null;
    this._defaultButtons = null;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Add the functions.
    this.addEvent = _addEvent;
    this.initializeDataChanged = _initializeDataChanged;
    this.registerPostBackControl = _registerPostBackControl;
    this.registerMaskedEditControl = _registerMaskedEditControl;
    this.doOnChange = _doOnChange;
    this.doOnBlur = _doOnBlur;
    this.isDataChanged = _isDataChanged;
    this.doPostBack = _doPostBack;
    this.onBeforeUnload = _onBeforeUnload;
    this.enableAll = _enableAll;
    this.enableLinks = _enableLinks;
    this.enableButtons = _enableButtons;
}

function _addEvent(obj, evType, fn) {
    if (obj.addEventListener) {
        obj.addEventListener(evType, fn, false);
        return true;
    } else if (obj.attachEvent) {
        var r = obj.attachEvent("on" + evType, fn);
        return r;
    } else {
        return false;
    }
}

// This function initializes the data changed handling.
function _initializeDataChanged(dataChangedControlID) {
    if (dataChangedControlID != null)
        this._dataChangedControl = document.getElementById(dataChangedControlID);
}

// This function registers a control that posts back to the server.  This control should NOT
// trigger the onbeforeunload functionality, and it should disable all navigation controls
// if/when the postback occurs.
function _registerPostBackControl(thisNavObject, controlName, prompt) {
    if (thisNavObject == null || typeof(thisNavObject) != "object") return;
    if (controlName == null || typeof(controlName) != "string" || controlName.length <= 0) return;

    var control = document.getElementById(controlName);
    if (control == null) return;

    if (control.onclick == null) {
        control.onclick = function (){
            return thisNavObject.doPostBack(prompt);
        };
    } else {
        var oldOnClick = control.onclick;
        control.onclick = function() {
            var rc = oldOnClick();
            if (rc == true || typeof (Page_IsValid) == "undefined" || (typeof (Page_IsValid) == "boolean" && Page_IsValid == true))
                return thisNavObject.doPostBack(prompt);
            else
                return false;
        };
    }
}

// This function registers a control that has a masked edit extender applied to it.  This control should 
// null out its value if it loses focus and has no value in it other than an empty mask.
function _registerMaskedEditControl(thisNavObject, controlName, emptyMask) {
    if (thisNavObject == null || typeof (thisNavObject) != "object") return;
    if (controlName == null || typeof (controlName) != "string" || controlName.length <= 0) return;
    if (emptyMask == null || typeof (emptyMask) != "string" || emptyMask.length <= 0) return;

    $("#" + controlName).blur(
        function() {
            return thisNavObject.doOnBlur(controlName, emptyMask);
        }
        );
    setTimeout("_doOnBlur(\"" + controlName + "\", \"" + emptyMask + "\")", 100);
}

// This function is called when a value changes.
function _doOnChange() {
    // Should we track changes yet?  Might not want to turn this on until after the page has finished loading.
    if (this.trackChanges == false) return;
    
    this._dataChanged = true;
    if (this._dataChangedControl != null) this._dataChangedControl.value = true;
}

// Call this function to determine whether data has changed.
function _isDataChanged() {
    if (this._dataChanged) return true;

    return false;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// This is called from the page's BeforeUnload event to check for any unsaved changes and
// confirm with the user if it's OK to navigate away from the page.
function _onBeforeUnload() {
    // Have we been told not to bother confirming?
    if (this.needConfirmation == false) {
        this.needConfirmation = true;
        return;
    }

    // If the data has changed then prompt the user by returning a message.
    if (this.isDataChanged()) {
        var rc = null;
        if (this.confirmationPrompt != null && this.confirmationPrompt.length > 0) {
            rc = this.confirmationPrompt;
        } else {
            rc = "You will lose any unsaved changes.";
        }
        return rc;
    }
}

// Do some pre-postback work to prompt for changes, if needed, and then disable all controls before posting back.
function _doPostBack(promptSaveChanges) {
    if (promptSaveChanges != null && typeof (promptSaveChanges) != "boolean") promptSaveChanges = null;
    if (promptSaveChanges && this.isDataChanged()) {
        var rc = false;
        if (this.dfltSaveChangesPrompt != null && this.dfltSaveChangesPrompt.length > 0)
            rc = confirm(this.dfltSaveChangesPrompt);
        else
            rc = confirm("There are unsaved changes to this information, which will be lost if you continue without saving first.\n" +
                "[OK]     Continue and lose unsaved changes.\n" +
                "[Cancel] Cancel this action in order to save changes first.");
        if (rc == false) return false;
    }
    this.needConfirmation = false;

    // Going to post back.  Disable all navigation controls first.
    if (typeof (navHelper) == "object" && typeof (navHelper.enableAll) == "function") {
        if (typeof (Page_IsValid) == "boolean") {
            if (Page_IsValid == true) {
                setTimeout("navHelper.enableAll(false)", 100);
            } else {
                this.needConfirmation = true;
            }
        }
    }

    return true;
}

function _doOnBlur(controlName, emptyMask) {
    if (controlName == null || controlName == "") return;
    if (emptyMask == null || emptyMask == "") return;

    var control = document.getElementById(controlName);
    if (control == null) return;

    if (control.value == emptyMask) control.value = "";
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// See if there are any changes to the page's data before navigating to another page.
function _navigate(name, url) {
    // Is the isDataChanged function defined on the parent page?
    if (typeof (isDataChanged) == "function") {
        // Has any data changed?
        if (isDataChanged()) {
            if (!confirm("There are unsaved changes on this page.\n\n" +
				"Select OK to continue to '" + name + "' and lose changes.\n" +
				"Select Cancel to remain on this page, then you can save changes.")) {
                // The user clicked Cancel, so stay on this page.
                return;
            }
        }
    }

    // Go to the requested url.
    this.enableAll(false);
    window.location = url;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// Enable/disable the menu, hyperlinks, and buttons.
function _enableAll(enable) {
    this.enableLinks(enable);
    this.enableButtons(enable);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// Enable/disable the hyperlinks on a page.
function _enableLinks(enable) {
    // Loop through all the links and enable/disable them.
    var links = document.getElementsByTagName("a");
    for (var i = 0; i < links.length; i++) {
        links[i].disabled = !enable;
        if (enable) {
            // Restore the old link information, if available.
            if (links[i].oldhref != null) links[i].href = links[i].href;
            if (links[i].oldonclick != null) links[i].href = links[i].onclick;
        } else {
            // Back up the old link information.
            links[i].oldhref = links[i].href;
            links[i].oldonclick = links[i].onclick;
            links[i].oldonmouseover = links[i].onmouseover;
            links[i].oldonmouseout = links[i].onmouseout;
            // Now wipe out anything that would allow the user to navigate using this link.
            links[i].href = "#";
            links[i].onclick = null;
        }
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// Enable/disable the buttons on a page.
function _enableButtons(enable) {
    // Loop through all the buttons and enable/disable them.
    var buttons = document.getElementsByTagName("input");
    for (var i = 0; i < buttons.length; i++) {
        if (buttons[i].type == "button" || buttons[i].type == "submit" || buttons[i].type == "image") {
            buttons[i].disabled = !enable;
            if (enable) {
                // Restore the old button information, if available.
                if (buttons[i].oldonclick != null) buttons[i].onclick = buttons[i].oldonclick;
            } else {
                // Back up the button link information.
                buttons[i].oldonclick = buttons[i].onclick;
                // Now wipe out anything that would allow the user to navigate using this button.
                buttons[i].onclick = null;
            }
        }
    }
}

