﻿// --------------------------------------------------------------------------------------------------------
//      Utility Functions
// --------------------------------------------------------------------------------------------------------


//  NOTES: 1. GetUrlWithParams and CallActionWithParams are designed to allow app devel on IIS5 
//            (requires .mvc extension on controller name)
//         2. siteRoot and controllerExtension set in header script of master page

// build full urls
function GetUrl(controller, action){
    return siteRoot + controller + controllerExtension + "/" + action;
}

function GetUrlWithParams(controller, action, params) {
    return siteRoot + controller + controllerExtension + "/" + action + "?" + params;
}

// redirect page
function Redirect(controller, action) {
	window.location = GetUrl(controller, action);
}

function RedirectWithParams(controller, action, params)
{
    window.location = GetUrlWithParams(controller, action, params);
}

function RedirectWithID(controller, action, id)
{
    window.location = GetUrlWithParams(controller, action, "id=" + id);
}

function RedirectToURL(url) {
    window.location = url;
}

function RefreshWindow() {
    window.location.reload();
}

function ShowSpinner() { $('#spinner').css('visibility', 'visible'); }
function HideSpinner() { $('#spinner').css('visibility', 'hidden'); }

function ReturnToDirectory(controller) {
    Redirect(controller, "Index");
}

function RemoveElement(elementID) {
    $('#' + elementID).remove();
}

// --------------------------------------------------------------------------------------------------------
//      Ajax Utility Functions
// --------------------------------------------------------------------------------------------------------


function CallAction(controller, action)
{
    CallActionWithParams(controller, action, null);
}

function CallActionWithParams(controller, action, params)
{
    DoSimpleAjaxPost(controller, action, params);
}

function CallActionWithID(controller, action, id)
{
    DoSimpleAjaxPost(controller, action, 'id=' + id);
}

// for internal use only
function DoSimpleAjaxPost(controller, action, params) {
    DoAjaxPost(controller, action, params, null);
}

function DoAjaxPost(controller, action, params, containerID) {
    // set defaults
    if(containerID == null) containerID = "scriptExecution";  // hidden in master page; runs any scripts
    params = AppendReturnUrl(params);  // Note: FF needs non-null params
    var url = GetUrl(controller, action);

    ClearMessage();
    ShowSpinner();
    $.post(url, params, function(data, textStatus) { 
                                                      HideSpinner(); 
                                                      $("#" + containerID).html(data);  // will also run any return scripts   
                                                   }, "html");
}

// intended for internal use, but can be used outside of core libraries.
// NOTE:  callbackFunction provided must call HideSpinner()
function DoAjaxPostWithCallBack(controller, action, params, callbackFunction) {
    // set defaults
    if(callbackFunction == null) callbackFunction = ProcessReturnScripts;
    params = AppendReturnUrl(params);  // Note: FF needs non-null params
    var url = GetUrl(controller, action);
    
    ClearMessage();
    ShowSpinner();
    $.post(url, params, callbackFunction, "html");
}

// for interal use only
function ProcessReturnScripts(data, textStatus) {
    HideSpinner(); 
    $("#scriptExecution").html(data);  // run any return scripts   
}

function RefreshContent(controller, action, params, containerID) {
    DoAjaxPost(controller, action, params, containerID);
}


// for internal use only (feeds returnUrl to ajax posts to maintain Close link hrefs)
function AppendReturnUrl(params) {

    if (params == null) params = '';  // FF needs non-null params

    if (params.indexOf('returnUrl', 0) > 0) // don't duplicate returnUrl param specified in params
        return params;
        
    var regexS = "[\\?&]returnUrl=([^&#]*)";  
    var regex = new RegExp(regexS);  
    var results = regex.exec(window.location.href);  
    if (!results) {
        return params;
    }
    else {
        if(params == '')
            return "returnUrl=" + results[1];
        else
            return params + "&returnUrl=" + results[1];
    }
}

// --------------------------------------------------------------------------------------------------------
//      Messaging Functions
// --------------------------------------------------------------------------------------------------------

var imgSrc = siteRoot + "Content/images/error.jpg";
var imgInMsgSrc = siteRoot + "Content/images/error_msg.gif";
var errorImage = "<img class=\"errorImage\" src=\"" + imgSrc + "\" style=\"background-color: inherit;\" />"
var errorImageMsg = "<img src=\"" + imgInMsgSrc + "\" title=\"Hold pointer over icon next to invalid field\" style=\"background-color: inherit;\" />"

// display message on page
function ShowInfo(msg){ ShowMessage(msg, "infoMsg", false); }
function ShowSuccess(msg){ ShowMessage(msg, "successMsg", false); }
function ShowWarning(msg){ ShowMessage(msg, "warningMsg", false); }
function ShowFail(msg){ ShowMessage(msg, "failMsg", false); }

// display message on dialog
function ShowInfoOnDialog(msg){ ShowMessage(msg, "infoMsg", true); }
function ShowSuccessOnDialog(msg){ ShowMessage(msg, "successMsg", true); }
function ShowWarningOnDialog(msg){ ShowMessage(msg, "warningMsg", true); }
function ShowFailOnDialog(msg) {
    EnableDialogSubmitButton();
    ShowMessage(msg, "failMsg", true);
    }

// for internal use only
function ShowMessage(msg, msgClass, onDialog){
    if(typeof(onDialog) == 'undefined') onDialog = false;
    var mcs; 
    mcs = onDialog ? $("#dialogMessage") : $(".message");
    mcs.each(function() {
        mc = $(this);
        mc.html(msg);
        if(!mc.hasClass(msgClass)) {
            mc.hide();
            mc.attr("class", msgClass);
            mc.addClass("message");
            mc.fadeIn(300);
        }
    });


    
}

// clear page or dialog msgs where present
function ClearMessage(){ 
    var mcs = $(".message, #dialogMessage");
    if(mcs != null) {
        mcs.each(function() {
            mc = $(this);
            mc.removeClass("infoMsg successMsg warningMsg failMsg");
            mc.addClass("message");
            mc.html("");
            mc.fadeOut(300);
        });
    }
}


// --------------------------------------------------------------------------------------------------------
//      Core Dialog Display Functions
// --------------------------------------------------------------------------------------------------------

function LoadInputForm(controller, action, params, containerID, submitAction)
{
    LoadForm(controller, action, params, containerID, 'Input', submitAction);
}

function LoadSearchForm(controller, action, params, containerID, submitAction)
{
    LoadForm(controller, action, params, containerID, 'Search', submitAction);
}

function LoadContinueForm(controller, action, params, containerID, submitAction)
{
    LoadForm(controller, action, params, containerID, 'Continue', submitAction);
}


// interal use only
function LoadForm(controller, action, params, containerID, dialogType, submitAction) 
{
    var container = $("#" + containerID);
    DoAjaxPostWithCallBack(controller, action, params, function (data) {
                                                           container.html(data);
                                                           ShowDialog(controller, container, dialogType, submitAction);
                                                           if (submitAction == null) {
                                                               DisableForm(containerID + ' form:first');
                                                           }
                                                           HideSpinner();
                                                        });
}

function ShowDialog(controller, container, dialogType, submitAction) {
    
    var dialogWidth = 450;
    if(container.width())
        dialogWidth = container.width() + 30;

   
    container.dialog({ 
        modal: true, 
        resizable: false, 
        draggable: true,
        width: dialogWidth,
        minHeight: 50,
        dialogClass: "dialog",
        close: function(event, ui) { $(this).dialog('destroy'); $(container).html(''); }  // must destroy when X clicked to restore container
    });

    var submitActionButtonText = '';
    switch(dialogType) {
        case "Search":
            AddMessageContainer(container);
            container.dialog("option", "buttons",
                {
                    "Cancel": function() { $(this).dialog('destroy'); $(container).html(''); },
                    "Search": function() {
                        DisableDialogSubmitButton();
                        submitAction(controller);
                    }
                });
            submitActionButtonText = "Search";
            break;

        case "Input":
            if (submitAction == null) {
                container.dialog("option", "buttons",
                {
                    "Close": function() { $(this).dialog('destroy'); $(container).html(''); }
                });
                submitActionButtonText = "Close";
            }
            else {
                AddMessageContainer(container);
                container.dialog("option", "buttons",
                {
                    "Cancel": function() { $(this).dialog('destroy'); $(container).html(''); },
                    "Submit": function() {
                        DisableDialogSubmitButton();
                        submitAction();
                    } // destroy using CloseDialog() via ajax response text
                });
                submitActionButtonText = "Submit";
            }
            break;

        case "Continue":
            AddMessageContainer(container);
            container.dialog("option", "buttons",
            {
                "Continue": function() {
                    DisableDialogSubmitButton();
                    submitAction();
                } // destroy using CloseDialog() via ajax response text
            });
            submitActionButtonText = "Continue";
            break;
        
        default:
            alert("The dialog type was not recognized.")
            break;
    }

    
    // Capture Enter key
    $(container).keypress(function(event) {
        
        var selector = ".ui-dialog-buttonpane button:contains('" + submitActionButtonText + "')"
        var submitActionButton = $(selector);

        if (submitActionButton.size() == 1 && event.keyCode == 13 && 
            event.target.type != "button" && event.target.type != "textarea") {
            submitActionButton[0].click();
        }
    });
}

function DisableDialogSubmitButton() {
    $(".ui-dialog-buttonpane button").attr("disabled", "true");
}

function EnableDialogSubmitButton() {
    $('.ui-dialog-buttonpane button').removeAttr('disabled');
}


// internal use only
function AddMessageContainer(dialogContainer) {
    // add message container at top of dialog (clear from any other previously opened dialogs)
    if($("#dialogMessageContainer").length > 0)
        $("#dialogMessageContainer").remove();
    dialogContainer.prepend('<div id="dialogMessageContainer"><div id="dialogMessage"></div></div>');
}

function SubmitDialogForm(formName, controller, saveAction, containerToRefresh){
    var form = $("#" + formName);
    try { 
        form.validate(); 
    } 
    catch (e) { 
        alert("You tried to validate a form that has not been set up for validation." ); 
        return false;
    }
    if (form.valid()) {
        DoAjaxPost(controller, saveAction, form.serialize(), containerToRefresh);
    }
}

function SubmitNonValidatedDialogForm(formName, controller, saveAction, containerToRefresh){
    var form = $("#" + formName);
    DoAjaxPost(controller, saveAction, form.serialize(), containerToRefresh);
}

function ShowSimpleDialog(containerID, content) {
    var container = $("#" + containerID);
    container.html('<fieldset style="margin:10px;padding:10px;">' + content + '</fieldset>')
    ShowDialog(null, container, "Input", null);
}

function CloseDialog(){
    $(".ui-dialog-titlebar-close").trigger("click"); 
}




// --------------------------------------------------------------------------------------------------------
//      Validation Functions
// --------------------------------------------------------------------------------------------------------

$.validator.setDefaults({
     errorElement:"span",
     ignoreTitle: true,
     //debug:true,             
     errorPlacement: function(error, element) {
        //$(error).attr({ style: "background-image: url(" + imgSrc + ");" });
        $(error).addClass("errorFlag");
        $(error).html(errorImage);
        $(error).attr({ id: "error_" + $(element).attr("id") });
        $(element).after(error);
     },
     showErrors: function(errorMap, errorList) {
        this.defaultShowErrors();
        if(this.numberOfInvalids() > 0) {
            if($("#dialogMessage").length > 0)
                ShowFailOnDialog("<span>Invalid values found (see </span>" + errorImageMsg + "<span> icon for info)</span>");
            else
                ShowFail("<span>One or more fields is invalid.  Please hold your mouse pointer over the </span>" + errorImageMsg + "<span> icon for more information.</span>");
        }
	    for ( var i = 0; this.errorList[i]; i++ ) {
		    var error = this.errorList[i];
		    var errorID = "#error_" + error.element.id;
		    $(errorID).attr( { title: error.message } );
		    //$(errorID).text("");
            $(errorID).html(errorImage);
            $(errorID).addClass("errorFlag");
	    }
      },
     highlight: function(element, errorClass) {
         $(element).addClass(errorClass);
         $(element.form).find("label[for=" + element.id + "]")
                        .addClass(errorClass);
      },
     unhighlight: function(element, errorClass) {
         $(element).removeClass(errorClass);
         $(element.form).find("label[for=" + element.id + "]")
                        .removeClass(errorClass);        
      }
});




// --------------------------------------------------------------------------------------------------------
//      Form Input Event Functions
// --------------------------------------------------------------------------------------------------------

// check/uncheck all checkboxes in tablerows
function ToggleAllCheckBoxes(element, selector) {
    var orders = $(selector);
    for (var i = 0; i < orders.length; i++) {
        orders[i].checked = element.checked;
    }
}


// assign to onkeydown handler to limit textarea input to maxlength attribute
function EnforceMaxLength(event)
{ 
	var code = event.charCode;
	if (!code) code = event.keyCode;
 
	switch(code) {
		case 9:  //TAB:
        case 37: //KEY_LEFT:
        case 39: //KEY_RIGHT:
        case 38: //KEY_UP:
        case 40: //KEY_DOWN:
        case 8:  //KEY_BACKSPACE:
        case 36: //KEY_HOME:
        case 46: //KEY_DELETE:
        case 35: //KEY_END:
        case 33: //KEY_PAGEUP:
        case 34: //KEY_PAGEDOWN:
        return true;
    }

    var max = parseInt($(this).attr('maxlength')); 
    if($(this).val().length >= max)
    { 
        return false;
    }
} 

// assign to onchange handler to limit textarea input to maxlength attribute
function EnforceMaxLengthAndWarn() {
    var max = parseInt($(this).attr('maxlength')); 
    var txt = $(this).val();
	if(txt.length > max)
	{
        $(this).val(txt.substring(0, max));
        alert('The information you have just entered was longer than the maximum limit of ' + max + ' characters and has been automatically shortened.');
    }    
}


// --------------------------------------------------------------------------------------------------------
//      List Add/Remove Rows Functions
// --------------------------------------------------------------------------------------------------------

// updates a single or appends to top of container if row is not found.
function RefreshListRowItem(controller, itemId, itemType) {
    var action = "RefreshDirectoryRowItem";
    var params = "itemID=" + itemId.toLowerCase();

    DoAjaxPostWithCallBack(controller, action, params, function(data, textStatus) {
        CloseDialog();
        HideSpinner();
        var rowId = "#Row-" + itemId;
        if ($(rowId).length > 0) {
            $(rowId).replaceWith(data);
            RefreshRowColor();
            $(rowId).css("background-color", "lightyellow");
        }
        else {
            $("#" + itemType + "List").prepend(data);
            RefreshRowColor();
            $(rowId).css("background-color", "lightyellow");
        }
    });

}

// removes a single row form a list container.
function RemoveListRowItem(id) {
    var rowID = "#Row-" + id;
    $(rowID).remove();
    RefreshRowColor();
}

function RefreshRowColor() {
    $("table.list tr").css("background-color", "white"); // clear all
    $("table.list tr:odd").css("background-color", "#eee"); // reset shade
}

// --------------------------------------------------------------------------------------------------------
//      List Add/Remove Sublist Row Functions
// --------------------------------------------------------------------------------------------------------

// updates a single or appends to top of container if row is not found.
function RefreshSublistRowItem(controller, itemId, itemType) {
    var action = "Refresh" + itemType + "SublistItem";
    var params = $.param({ "itemID": itemId.toLowerCase() });

    DoAjaxPostWithCallBack(controller, action, params, function(data, textStatus) {
        var rowId = "#Row-" + itemId;
        $("table.sublistItems tr").css("background-color", "white"); // clear all
        if ($(rowId).length > 0) {
            $(rowId).replaceWith(data);
            $(rowId).css("background-color", "lightyellow");
        }
        else {
            $("#" + itemType + "List").prepend(data);
            $(rowId).css("background-color", "lightyellow");
        }
        HideSpinner();
    });

}

// removes a single sublist row form a list container.
function RemoveSublistRowItem(id) {
    var rowID = "#Row-" + id;
    $(rowID).remove();
}


// --------------------------------------------------------------------------------------------------------
//      Form Control Manipulation
// --------------------------------------------------------------------------------------------------------

function ClearDropdownList(listID, showLoading) {
    var selector = '#' + listID + ' option'
    $(selector).each(function (i, option) { $(option).remove(); });
    if (showLoading) {
        $('#' + listID).append($('<option></option>').val('').html('Loading...'));
    }
}