﻿/// <reference path="jquery/jquery-1.4.1-vsdoc.js" />

/*
 * Footsteps
 * Copyright(c) 2010, ARI Network Services, Inc.
 * http://www.arinet.com
 *
 */

if (!FS) {
    var FS = {};
}

$(function () {
    // Ensure we don't have any lingering overlays
    FS.Overlay.hide(document);
    FS.Footsteps.init();

    $('#quick-search', $('#csearch')).submit(function (e) {


        if ($('#quick-customer-search').val().length) {

            var strJson = JSON.stringify(
                    { "Filters": [
                            { "Name": "LastName", "Operator": "5", "Value": [$('#quick-customer-search').val()] }
                        ]
                    }
                );

            $('input[name="customFilters"]', $('#csearch')).val(strJson);
            $('#quick-search').submit();
        } else {
            return false;
        }


    });
    // Rig up key monitoring, which is needed for IE7 with hidden submit button
    $('#quick-customer-search').keydown(function (e) {
        if ((e.keyCode || e.which) == 13) {
            // Enter key was pressed
            $('#quick-search', $('#csearch')).submit();
            return false;
        }
    });

    $.ajaxSetup({ cache: false });
    $('#sys').ajaxError(function (e, jqxhr, settings, exception) {
        // Hide all overlays
        FS.Overlay.hide(document);
        // Show message (this also shows when you're changing tabs, which will cancel the earlier request, so we don't want to do it for that)
        //FS.Messaging.error('Your last request did not complete, please try again.');
    });

    // Setup session timeout warning
    if (!FS.Timeout) {
        FS.Timeout = { Period: 20, StartTime: new Date(), IsTimedOut: false, TimeoutStart: null };
        FS.Timeout.init = function () {
            // Initialize the pending timeout dialog
            var pendingTimeoutDialog = $('#session-pending-timeout-dialog');
            if (pendingTimeoutDialog.length == 0) { return; }
            var timeout = parseInt(pendingTimeoutDialog.data('timeout'), 10);
            if (!isNaN(timeout)) {
                if (timeout == 0) {
                    // If they can't timeout, we don't need to continue processing
                    return;
                }
                // Update the timeout period
                FS.Timeout.Period = timeout;
            }

            pendingTimeoutDialog.dialog({
                autoOpen: false,
                resizable: false,
                modal: true,
                height: 170,
                width: 280,
                buttons: {
                    'Continue Working': function () {
                        pendingTimeoutDialog.dialog('close');
                    },
                    'Logout': function () {
                        window.location.assign('/Account/LogOff');
                        FS.Overlay.show(pendingTimeoutDialog.dialog('widget'));
                    }
                },
                close: function (sourceEvent, ui) {
                    if (!FS.Timeout.IsTimedOut) {
                        // Extend the timeout period (when they cancel, we'll assume they want to keep working)
                        $.getJSON('/Account/ExtendTimeout');
                    }
                }
            });

            // Initialize the session timed out dialog
            var timedOutDialog = $('#session-timeout-dialog');
            timedOutDialog.dialog({
                autoOpen: false,
                resizable: false,
                modal: true,
                height: 233,
                width: 300,
                buttons: {
                    'Login': function () {
                        // Validity check
                        var widgetContainer = timedOutDialog.dialog('widget');
                        $('#session-timeout-invalid-login').addClass('hide');
                        if (!Validate(widgetContainer, true)) { return; }

                        FS.Overlay.show(widgetContainer);

                        // Perform the logon
                        $.post('/Account/LogOnAjax', { 'credentials.UserName': $('#session-timeout-username').val(), 'credentials.Password': $('#session-timeout-password').val() }, function (response) {
                            FS.Overlay.hide(widgetContainer);

                            if (response) {
                                FS.Timeout.IsTimedOut = false;
                                FS.Timeout.TimeoutStart = null;
                                FS.Timeout.StartTime = new Date();
                                timedOutDialog.dialog('close');
                            } else {
                                $('#session-timeout-invalid-login').removeClass('hide').delay(7000).addClass('hide');
                            }
                        }, 'json');
                    },
                    'Cancel': function () {
                        FS.Overlay.show(timedOutDialog.dialog('widget'));

                        // Check if they're cancelling because they've logged in elsewhere
                        $.getJSON('/Account/ExtendTimeout', null, function (response) {
                            if (response) {
                                FS.Overlay.hide(timedOutDialog.dialog('widget'));
                                FS.Timeout.IsTimedOut = false;
                                FS.Timeout.TimeoutStart = null;
                                FS.Timeout.StartTime = new Date();
                                timedOutDialog.dialog('close');
                            } else {
                                // Redirect to login screen if they cancel and aren't authenticated
                                window.location.assign('/Account/LogOn');
                            }
                        });
                    }
                },
                beforeClose: function (sourceEvent, ui) {
                    if (FS.Timeout.IsTimedOut) {
                        FS.Overlay.show(timedOutDialog.dialog('widget'));

                        // Check if they're cancelling because they've logged in elsewhere
                        $.getJSON('/Account/ExtendTimeout', null, function (response) {
                            if (response) {
                                FS.Overlay.hide(timedOutDialog.dialog('widget'));
                                FS.Timeout.IsTimedOut = false;
                                FS.Timeout.TimeoutStart = null;
                                FS.Timeout.StartTime = new Date();
                                timedOutDialog.dialog('close');
                            } else {
                                // Redirect to login screen if they cancel and aren't authenticated
                                window.location.assign('/Account/LogOn');
                            }
                        });

                        // Prevent the dialog from closing while the above check is being performed
                        return false;
                    } else {
                        // Reset the dialog
                        $('#session-timeout-password').val('');
                    }
                }
            });

            var periodInMilliseconds = FS.Timeout.Period * 1000 * 60;
            var showWarningIMilliseconds = 2.5 * 1000 * 60; // number of milliseconds before the period expires to show the warning
            if (showWarningIMilliseconds > periodInMilliseconds) { showWarningIMilliseconds = 0; }

            // Create function to check if we've timed out
            var checkTimeoutStatusFunction = function () {
                // Determine how long it's been
                var currentTime = new Date();

                // Check if we've already timed out
                if (FS.Timeout.IsTimedOut) {
                    // Check if we've logged in elsewhere
                    var timedOutDurationInMillseconds = currentTime.getTime() - FS.Timeout.TimeoutStart.getTime();

                    // Only perform the check once every 2 minutes
                    if (timedOutDurationInMillseconds > 120000) {
                        $.getJSON('/Account/ExtendTimeout', null, function (response) {
                            if (response) {
                                FS.Timeout.IsTimedOut = false;
                                FS.Timeout.TimeoutStart = null;
                                FS.Timeout.StartTime = new Date();
                                if (timedOutDialog.dialog('isOpen')) {
                                    timedOutDialog.dialog('close');
                                }
                            }
                        });

                        FS.Timeout.TimeoutStart = new Date();
                    }

                    // We've already timed out, nothing else to show here
                    return;
                }

                // Check if we've expired our timeout
                var timeSpanInMilliseconds = currentTime.getTime() - FS.Timeout.StartTime.getTime();
                if (periodInMilliseconds <= timeSpanInMilliseconds) {
                    FS.Timeout.IsTimedOut = true;
                    FS.Timeout.TimeoutStart = new Date();
                    timedOutDialog.dialog('open');

                    // Ensure the pending time out dialog is not open
                    if (pendingTimeoutDialog.dialog('isOpen')) {
                        pendingTimeoutDialog.dialog('close');
                    }
                } else if (showWarningIMilliseconds >= 0 && periodInMilliseconds > showWarningIMilliseconds && (periodInMilliseconds - showWarningIMilliseconds) <= timeSpanInMilliseconds) {
                    // Show the pending timeout dialog

                    // Ensure the timed out dialog is not open
                    if (timedOutDialog.dialog('isOpen')) {
                        timedOutDialog.dialog('close');
                    }

                    // Get the countdown time remaining
                    var countdownElements = $('.session-timeout-remaining-time span');

                    // Start the countdown and show the remaining time
                    var remainingMilliseconds = Math.ceil(periodInMilliseconds - timeSpanInMilliseconds);
                    var remainingMinutes = Math.floor(remainingMilliseconds / (1000 * 60));
                    var remainingSeconds = Math.floor((remainingMilliseconds - (remainingMinutes * 1000 * 60)) / 1000);

                    if (remainingMinutes < 0) { remainingMinutes = 0; }
                    if (remainingSeconds < 0) { remainingSeconds = 0; }
                    if (remainingMinutes < 10) { remainingMinutes = '0' + remainingMinutes; }
                    if (remainingSeconds < 10) { remainingSeconds = '0' + remainingSeconds; }

                    // Update the amount of time remaining
                    countdownElements.text(remainingMinutes + ':' + remainingSeconds);

                    // Show the pending timeout dialog
                    if (!pendingTimeoutDialog.dialog('isOpen')) {
                        pendingTimeoutDialog.dialog('open');
                    }
                } else {
                    // Ensure no dialogs are open
                    if (pendingTimeoutDialog.dialog('isOpen')) {
                        pendingTimeoutDialog.dialog('close');
                    }
                    if (timedOutDialog.dialog('isOpen')) {
                        timedOutDialog.dialog('close');
                    }
                }
            };

            // Set the initial timeout window
            setInterval(checkTimeoutStatusFunction, 500);

            // Setup AJAX calls to facilitate the timeout
            $.ajaxSetup({
                beforeSend: function (xhr, settings) {
                    if (FS.Timeout.IsTimedOut) {
                        // Only allow requests to the account controller when the user is timed out
                        var validControllers = ['\/Account\/'];
                        for (var i = 0; i < validControllers.length; i++) {
                            var checkValidControllerRegex = new RegExp(validControllers[i], 'i');
                            var validResult = checkValidControllerRegex.test(settings.url);
                            if (!validResult) {
                                return false;
                            }
                        }
                    }
                }
            });
            $(document).ajaxComplete(function () {
                // They've extended their timeout period through the AJAX call
                if (!FS.Timeout.IsTimedOut) {
                    FS.Timeout.StartTime = new Date();
                }
            });
        };

        // Initialize the timeout engine
        FS.Timeout.init();
    }

    $('a.saved-search').click(function () {

        var searchitem = $(this).siblings('input.saved-search');
        var searchType = searchitem.data('searchtype');
        var url = searchType == 'Customer' ? '/Report/Customer' : '/Report/Lead';
        var filterEl = $('<input type="hidden" name="customFilters" />');
        filterEl.val(searchitem.val());

        var typeEl = $('<input type="hidden" />');
        typeEl.attr('name', searchType == 'Customer' ? 'allCustomers' : 'leadSearch').val('true');

        var frm = $('<form />')
            .attr('action', url)
            .attr('method', 'POST')
            .append(filterEl)
            .append(typeEl);

        if (searchitem.data('sort') != '') {
            frm.append($('<input type="hidden" name="orderBy" />').val(searchitem.data('sort')));
        }

        frm.appendTo(document.body)
            .submit();

        return false;
    });

    // Setup title casing on known elements
    var titlecasing = $('input[type="text"][data-titlecase]');
    if (titlecasing.length > 0) {
        titlecasing.titleCase();
    }

    if ($.telerik != null && $.telerik.grid != undefined) {

        var checkedRows = {
            checkSelector: '[name="row-id"]:checkbox',
            checkAll: function () {
                $(this.checkSelector, this.element).prop('checked', true);
                this.SelectAll = true;
                this.SelectedKeys = [];
            },
            uncheckAll: function () {
                $(this.checkSelector, this.element).prop('checked', false);
                this.SelectAll = false;
                this.SelectedKeys = [];
            },
            SelectAll: false,
            SelectedKeys: [],
            onChecked: function (sender) {
                var grid = $(sender).closest('.t-grid').data('tGrid');
                var rowEntityId = $(sender).val();
                var addEntity = (!grid.SelectAll && $(sender).is(':checked')) || (grid.SelectAll && !$(sender).is(':checked'));

                if (addEntity) {
                    grid.SelectedKeys.push(rowEntityId);
                } else {
                    var existingEntity = $.inArray($(sender).val(), grid.SelectedKeys) >= 0;
                    grid.SelectedKeys = $.grep(grid.SelectedKeys, function (val) {
                        return val != rowEntityId;
                    });
                }

                // this can be moved out later to the inbox_rev1.js file once we wire up strapable/callable events
                if (currCustomerID != undefined && currCustomerID != null && currCustomerID > 0) {
                    if (grid.SelectedKeys.length > 0)
                        $('.trash-selected', $('#cust-' + currCustomerID)).show();
                    else
                        $('.trash-selected', $('#cust-' + currCustomerID)).hide();
                } else {
                    if (grid.SelectedKeys.length > 0)
                        $('.trash-selected').show();
                    else
                        $('.trash-selected').hide();
                }
            }
        };

        $(checkedRows.checkSelector, $('.t-grid')).live('click', function () {
            checkedRows.onChecked(this);
        });

        $('.t-grid').each(function (i, el) {
            $(el).ajaxSuccess(function (e, req, settings) {
                var g = $(el).data('tGrid');
                // rebind all the selected keys in the grid
                $.each(g.SelectedKeys, function (i, val) {
                    $(checkedRows.checkSelector + '[value="' + val + '"]').prop('checked', true);
                });
            });
        });

        $.extend(true, $.telerik.grid.prototype, checkedRows);

    }


    $.fn.placeholder = function () {
        if (typeof document.createElement("input").placeholder == 'undefined') {
            $('input[placeholder]').focus(function () {
                var input = $(this);
                if (input.val() == input.attr('placeholder')) {
                    input.val('');
                    input.removeClass('placeholder');
                }
            }).blur(function () {
                var input = $(this);
                if (input.val() == '' || input.val() == input.attr('placeholder')) {
                    input.addClass('placeholder');
                    input.val(input.attr('placeholder'));
                }
            }).blur().parents('form').submit(function () {
                $(this).find('[placeholder]').each(function () {
                    var input = $(this);
                    if (input.val() == input.attr('placeholder')) {
                        input.val('');
                    }
                })
            });
        }
    }

    $.fn.placeholder();

});

FS.Utils = (function ($) {
    return {
        pad: function (value, length, padding) {

            if (typeof value == 'undefined' || value.toString() == '')
                return value;
            if (typeof length == 'undefined' || parseInt(length) <= 0)
                length = 2;
            else
                length = parseInt(length);
            if (typeof padding == 'undefined')
                padding = '0';

            var str = '';
            for (var i = 0; i < length - value.toString().length; i++) {
                str += padding;
            }

            return str + value.toString();

        }
    };
})(jQuery);

FS.Footsteps = (function($) {
    return {
        init: function() {
            // TODO: Why do we need this?
            $('ul.primary li').hover(
                function() {
                    $(this).addClass('over');
                },
                function() {
                    $(this).removeClass('over');
            });

            FS.UI.init(document);
            //FS.Console.init();
        }
    };
})(jQuery);

FS.UI = (function ($) {
    return {
        init: function (jqueryContext) {
            this.initUIButtons(jqueryContext);
        },
        initUIButtons: function (jqueryContext) {
            var template = '<div id="{ID}" class="fs-button-click{defaultButton}"><div class="ib inline-block">' +
                '<div class="inline-block ib-outer">' +
                    '<div class="inline-block ib-inner">' +
                        '<div class="ib-pos">' +
                            '<div class="ib-top-shadow">&nbsp;</div>' +
                            '<div class="ib-content">{VALUE}</div>' +
                        '</div>' +
                    '</div>' +
                '</div>' +
            '</div></div>';

            $(":submit[class*='fs-button']:not(.fs-replace),:button[class*='fs-button']:not(.fs-replace)", arguments.length < 1 || !jqueryContext ? document : jqueryContext).each(function () {
                var originalButton = $(this).css("visibility", "hidden").css({ display: 'none !important', position: 'absolute', top: '-5000px', left: '-5000px' }).addClass('fs-replace');

                var newTemplate = template.replace("{ID}", originalButton.attr('id') || "button-" + (new Date()).getTime())
                                          .replace("{VALUE}", originalButton.val())
                                          .replace("{defaultButton}", originalButton.hasClass('default-button') ? ' default-button' : '');

                originalButton.attr('id', 'original:' + (originalButton.attr('id') || "button-" + (new Date()).getTime())).removeClass('default-button');
                var newButton = $(newTemplate);
                newButton.insertAfter(originalButton);

                // Ensure this button calls the original
                newButton.click(function () {
                    return originalButton.click();
                });
            });
        },
        removeAssignSalesPersonDialog: function (customerID) {
            /// <summary>Removes any existing Assign Salesperson dialogs from the DOM</summary>
            /// <param name="customerID">Unique identifier for the Customer to remove the dialog for</param>

            // Validity check
            if (!customerID || customerID < 1 || isNaN(parseInt(customerID, 10))) { return; }

            // Find the dialog form
            var objDialog = $('#assignSalesPerson' + customerID).closest('.assignSalesPersonDialog');
            if (objDialog.length == 0) { return; }

            // Remove the dialog
            objDialog.dialog('destroy');
            objDialog.remove();
        },
        prepareAssignSalesPersonDialog: function (customerID, closeCallback) {
            /// <summary>Transforms the corresponding Assign Salesperson markup into a jQuery dialog for a Customer. This is a separate function because it only needs to be executed once, as opposed to showAssignSalespersonDialog() which can be executed multiple times.</summary>
            /// <param name="customerID">Unique identifier for the Customer to prepare the dialog for</param>

            // Validity check
            if (!customerID || customerID < 1 || isNaN(parseInt(customerID, 10))) { return; }

            // Find the dialog form
            var objDialog = $('#assignSalesPerson' + customerID).closest('.assignSalesPersonDialog');

            // Update the Employee dropdown to auto-select the currently assigned Employee when it loads
            var fSetAutoSelectEmployee = function () {
                // Get the input object (because the dialog is configured after this function is created,
                //      the object gets moved inside the DOM, so we always retrieve it "fresh")
                var objAutoSelectEmployee = $('select[name="EmployeeID"]', objDialog.dialog('widget'));

                var nUserEmployeeID = $('input[name="hfEmployeeID"]', objDialog.dialog('widget')).val();
                if (nUserEmployeeID && !isNaN(parseInt(nUserEmployeeID, 10))) {
                    if (objAutoSelectEmployee.find('option[value="' + nUserEmployeeID + '"]').length == 0) {
                        objAutoSelectEmployee.data('selectedemployeeid', nUserEmployeeID);
                    } else {
                        objAutoSelectEmployee.val(nUserEmployeeID);
                        objAutoSelectEmployee.removeAttr('disabled');
                    }
                }
            };

            // Update the Location dropdown to auto-select the currently assigned Location whenever the dialog is closed
            var fSetAutoSelectLocation = function () {
                // Reset the default selection for the Location
                var nLocationID = $('input[name="hfLocationID"]', objDialog.dialog('widget')).val();
                if (nLocationID && !isNaN(parseInt(nLocationID, 10))) {
                    $('select[name="LocationID"]', objDialog.dialog('widget')).val(nLocationID).change(); // trigger a change event when making the selection
                }
            };

            // Auto-update the Location dropdown when the masterpage Location dropdown changes
            $('#ddlOrganizationList').change(function () {

                //                if ($('#isDirtyMain').val() == "true") {
                //                    if (confirm('Are you sure you want to leave this org? (Data you have entered may be lost by leaving)')) {
                //                        isDirty = false;
                //                        $('isDirtyMain').val('false');
                //                    } else {
                //                        $(this).val($.data(this));
                //                        return false;
                //                    }
                //                }

                // Only perform the Update if the EmployeeID value is not yet assigned (if it is, then we always use the Employee's Location)
                var nUserEmployeeID = parseInt($('input[name="hfEmployeeID"]', objDialog.dialog('widget')).val(), 10);
                if (!nUserEmployeeID || isNaN(nUserEmployeeID)) {
                    if ($('select[name="LocationID"] option[value="' + $(this).val() + '"]', objDialog.dialog('widget')).length > 0) {
                        // Automatically select the location in the Assign Employee dialog
                        $('input[name="hfLocationID"]', objDialog.dialog('widget')).val($(this).val());
                        fSetAutoSelectLocation();
                    }
                }
            });

            // Create the close function
            var fCloseDialog = function () {
                var objCloseWidget = objDialog.dialog('widget');
                $('input[type!="checkbox"][type!="radio"][name!="hfEmployeeID"][name!="hfLocationID"],select[name!="LocationID"][name!="EmployeeID"][type!="hidden"]', objCloseWidget).val('');
                $('select[name="EmployeeID"]', objWidget).val($('input[name="hfEmployeeID"]', objCloseWidget).val());
                ValidateHideMessage(objCloseWidget, true);

                // Reset the auto select employee value
                fSetAutoSelectEmployee();

                // Reset the default selection for the Location
                fSetAutoSelectLocation();

                if (closeCallback != null) {
                    closeCallback((objDialog.data('updating') == true) ? 'refresh' : null);
                }

            };

            // Prepare the dialog
            objDialog.dialog({
                bgiframe: true,
                autoOpen: false,
                modal: true,
                width: 500,
                buttons: {
                    'Save': function () {
                        // Working variables
                        var objSaveDialog = $(this);
                        var objSaveWidget = objSaveDialog.dialog('widget');

                        // Validate the inputs
                        if (!Validate(objSaveWidget, true)) { return false; }

                        // Get the input values
                        var 
                            nLocationID = $('select[name="LocationID"]', objSaveWidget).val(),
                            nEmployeeID = $('select[name="EmployeeID"]', objSaveWidget).val(),
                            nExistingEmployeeID = $('input[name="hfEmployeeID"]', objSaveWidget).val();

                        // Check if an update is not required
                        if (nEmployeeID == nExistingEmployeeID) {
                            objSaveDialog.dialog('close');
                            return;
                        }

                        // Update the dialog to indicate it is being updated
                        FS.Overlay.show(objSaveWidget);
                        objSaveDialog.data('updating', true);
                        // Post the changes to the controller
                        $.post('/Customer/AssignEmployee', { customerID: customerID, locationID: nLocationID, employeeID: nEmployeeID }, function (saveResponse) {
                            // Ensure the save was successful
                            if (saveResponse) {
                                // Update the inputs
                                $('input[name="hfEmployeeID"]', objSaveWidget).val(nEmployeeID);
                                $('input[name="hfLocationID"]', objSaveWidget).val(nLocationID);

                                // Get rid of the overlay message
                                FS.Overlay.hide(objSaveWidget);

                                // Show the confirmation message                           
                                FS.Messaging.info('Assigned customer to new Sales Person');

                                // Close the dialog
                                objSaveDialog.dialog('close');

                                //                                if (closeCallback == null) {
                                //                                    // Reload the tab
                                //                                    loadContentIntoTab(customerID, 'Summary');
                                //                                }
                            } else {
                                // Get rid of the overlay message
                                FS.Overlay.hide(objSaveWidget);

                                FS.Messaging.error('Could not assign Customer to Sales Person. Please try again later.');
                            }
                        });
                    },
                    'Cancel': function () {
                        $(this).dialog('close');
                    }
                },
                close: fCloseDialog
            });

            // Register the change event for the locations dropdown
            var objWidget = objDialog.dialog('widget');

            var objLocationsDropdown = $('select[name="LocationID"]', objWidget);

            objLocationsDropdown.change(function () {
                // Get the corresponding Employee dropdown
                var objEmployeeDropdown = $('select[name="EmployeeID"]', objWidget);

                var nLocationID = $(this).val();
                if (nLocationID && !isNaN(parseInt(nLocationID, 10))) {
                    // Show a loading message
                    $('option:gt(0)', objEmployeeDropdown).remove();
                    $('<option>').val('-99').text('Loading...').prependTo(objEmployeeDropdown.attr('disabled', 'disabled'));
                    objEmployeeDropdown.val('-99');

                    // Always auto-select the current User/Employee when changing locations
                    fSetAutoSelectEmployee();

                    // Get the employees from the database
                    $.getJSON('/Customer/GetEmployeeList', { locationID: nLocationID }, function (dataResponse) {
                        // Remove the loading message
                        $('option:first', objEmployeeDropdown).remove();
                        objEmployeeDropdown.val('');

                        // Process the data response
                        if (dataResponse) {
                            objEmployeeDropdown.removeAttr('disabled');
                            $(dataResponse).each(function (dataIndex, dataItem) {
                                $('<option>').val(dataItem.EmployeeID).text(dataItem.LastName + ', ' + dataItem.FirstName).appendTo(objEmployeeDropdown);
                            });

                            // Pre-select any stored employee
                            var nEmployeeID = objEmployeeDropdown.data('selectedemployeeid');
                            if (nEmployeeID) {
                                if (nEmployeeID == 0)
                                    objEmployeeDropdown.val('').removeData('selectedemployeeid');
                                else
                                    objEmployeeDropdown.val(nEmployeeID).removeData('selectedemployeeid');
                            }
                        } else {
                            objEmployeeDropdown.val('');
                            objEmployeeDropdown.attr('disabled', 'disabled');
                        }
                    });
                } else {
                    objEmployeeDropdown.val('');
                    objEmployeeDropdown.attr('disabled', 'disabled');
                }
            });

            // Automatically trigger the location change if only one location is available
            if ($('option:gt(0)', objLocationsDropdown).length == 1) {
                objLocationsDropdown.each(function () {
                    this.selectedIndex = 1;
                    $(this).closest('tr').hide();
                });

                // Auto fire the change event for all dropdowns where the value is not the default one
                //      - We do this seperately from changing the selectedIndex property in case the HTML was rendered with a pre-selected Location
                objLocationsDropdown.each(function () {
                    if (this.selectedIndex > 0) {
                        $(this).change();
                    }
                });
            } else {
                // Reset the default selection for the Location
                fSetAutoSelectLocation();
            }
        },
        showAssignSalesPersonDialog: function (customerID, sender) {
            /// <summary>Shows an Assign Salesperson dialog for a Customer</summary>
            /// <param name="customerID">Unique identifier for the Customer to assign to a salesperson</param>
            /// <param name="sender">The link/button used to call this method.</param>

            // Validity check
            if (!customerID || customerID < 1 || isNaN(parseInt(customerID, 10))) { return; }

            // Find the dialog form
            var objDialog = $('#assignSalesPerson' + customerID).closest('.assignSalesPersonDialog');

            // Show the dialog
            objDialog.dialog('open');
        }
    };
})(jQuery);

FS.Core = (function ($) {
    return {
        System: (function () {
            return {
                redirect: function (url) {
                    window.location = url;
                },
                wait: function (delay, fn) {
                    setTimeout(fn, delay);
                },
                debug: function (message) {
                    if (typeof (console) != 'undefined' &&
                    typeof (console.debug) != 'undefined') {
                        console.debug(message);
                    }
                }
            };
        })(),

        CommandManager: (function () {
            return {
                createCommand: function (execute, undo) {
                    return {
                        Execute: execute,
                        Undo: undo
                    };
                }
            };
        })(),

        UrlParser: (function () {
            var _protocol, _host, _port, _params, _base;
            return {
                parse: function (url) {
                    _params = {};
                    _protocol = url.match(/^.[^:]+/)[0];
                    _host = (url.match(/:\/\/(.[^:]+)/) || ['', ''])[1];
                    _port = (url.match(/:(\d[^\/]+)/) || ['', ''])[1];
                    _base = url.substring(0, url.indexOf("?") > 0 ? url.indexOf("?") : url.length);
                    var seg = (url.match(/[?](.+)/) || ['', ''])[1].split('&');
                    $.each(seg, function (i) {
                        var kvPair = this.split('=');
                        if (!_params[kvPair[0]]) {
                            _params[kvPair[0]] = kvPair[1] || "";
                        }
                    });
                    return this;
                },
                protocol: function () {
                    return _protocol;
                },
                port: function () {
                    return _port;
                },
                host: function () {
                    return _host;
                },
                params: function () {
                    return _params;
                },
                base: function () {
                    return _base;
                }
            };
        })(),

        UrlBuilder: (function () {
            var _url, _baseUrl, _paramMap = {};
            return {
                getParam: function (key) {
                    return _paramMap[key] || "";
                },
                getParams: function () {
                    var params = [];

                    if (_paramMap) {
                        $.each(_paramMap, function (key, val) {
                            params.push(val);
                        });
                    }

                    return params;
                },
                getParamMap: function () {
                    return _paramMap;
                },
                setParams: function (params, clearAll) {
                    var oThis = this;
                    if (typeof (clearAll) != 'undefined' && clearAll) {
                        this.removeParams();
                    }

                    if ($.isArray(params)) {
                        $.each(params, function (i) {
                            oThis.setParam(this.Key, this.Value);
                        });
                    }
                    else {
                        // Map objects
                        var single = (function () {
                            var list = [], count = 0;
                            $.each(params, function (k, v) {
                                list.push([k,v]);
                                if (++count == 2) return;
                            });
                            return list[0][0] === "Key" && list[1][0] === "Value";
                        })();

                        if (single) {
                            this.setParam(params.Key, params.Value);
                        }
                        else {
                            $.each(params, function (k, v) {
                                oThis.setParam(k, v);
                            });
                        }
                    }

                    return this;
                },
                setParam: function (key, value) {
                    if (typeof (key) == 'undefined' || !key) return;
                    _paramMap[key] = { 'Key': key, 'Value': value };
                    return this;
                },

                removeParam: function (key) {
                    delete _paramMap[key];
                    return this;
                },
                removeParams: function () {
                    _paramMap = {};
                },
                getBaseUrl: function () {
                    return _baseUrl;
                },
                setBaseUrl: function (url) {
                    _baseUrl = url;
                    return this;
                },
                build: function (url) {
                    var parser = FS.Core.UrlParser.parse(url);
                    this.setBaseUrl(parser.base());

                    var kvParams = [];
                    $.each(parser.params(), function (key, val) {
                        kvParams.push({ Key: key, Value: val });
                    });
                    this.setParams(kvParams, true);

                    return this;
                },
                getUrl: function () {
                    var baseUrl = this.getBaseUrl();
                    var params = this.serialize(this.getParamMap());
                    return params ? [baseUrl, params].join("?") : baseUrl;
                },
                serialize: function (paramMap) {
                    var list = [];
                    $.each(paramMap, function (key, val) {
                        list.push(val.Key + "=" + val.Value);
                    });
                    return list.join("&");
                }
            };
        })()
    };
})(jQuery);

FS.Console = (function($) {
    return {
        init: function() {
            if (typeof (console) == 'undefined' || 
                typeof(console.debug) == 'undefined') {
                //this.initFBLite();
            }
        },
        initFBLite: function(callback) {
            // TODO: Get this working!!
            $.getScript("/Scripts/firebug/firebug-lite-compressed.js");
        },
        debug: function(message) {
            if (typeof (console) != 'undefined' &&
                typeof (console.debug) != 'undefined') {
                console.debug(message);
            }
            else {
                if (typeof (firebug) != 'undefined') {
                    firebug.d.console.cmd.debug(msg);
                }
            }
        },
        log: function(message) {
            if (typeof (console) != 'undefined' &&
                typeof (console.log) != 'undefined') {
                console.log(message);
            }
            else {
                if (typeof (firebug) != 'undefined') {
                    firebug.d.console.cmd.log(message);
                }
            }
        }
    };
})(jQuery);

FS.Messaging = (function($) {
    var messageType = {
        Error: 'error',
        Info: 'info'
    };
    var defaults = {
        type: messageType.Info
    };
    return {
        info: function(msg) {
            this.send(msg, { type: messageType.Info });
        },
        error: function(msg) {
            this.send(msg, { type: messageType.Error });
        },
        send: function(msg, options) {
            var settings = $.extend({}, defaults, options || {});
            var spanMsgType = settings.type || "";
            var rn = Math.floor(Math.random() * 101010101);
            var spanMsgCls = 'msg-' + rn;
            $('#sys').find('div.messaging').html('<span class="' + spanMsgCls + " " + spanMsgType + '">' + msg + '</span>');
            setTimeout(function() {
                $('span.' + spanMsgCls + '').fadeOut('slow');
            }, 5000);
        }
    };
})(jQuery);

FS.Window = (function($) {
    return {
        alert: function(msg) {
            alert(msg);
        }
    };
})(jQuery);

FS.Overlay = (function ($) {
    return {
        show: function (elementSelector) {
            /// <summary>Shows an overlay over the supplied object</summary>
            /// <param name="elementSelector">A jQuery selector or object used to determince which elements to modify</param>

            // Validity check
            if (!elementSelector) { return; }

            // Process each element
            $(elementSelector).each(function (elemIndex, elemObject) {
                var objElement = $(elemObject);

                // Remove any existing overlay
                FS.Overlay.hide(objElement);

                // Get the element offsets relative to the document
                var objPosition = objElement.position();
                var objOffset = objElement.offset();

                // Create the overlay element
                var objOverlay = $('<div>').addClass('overlay').prependTo(objElement);
                objOverlay.css({ 'top': objPosition.top, 'left': objPosition.left, 'width': objElement.outerWidth(), 'height': objElement.outerHeight() });
                // Check if we're dealing with JQuery UI dialogs, which are positioned in such a way that we don't need to set absolute values for the overlay
                if (objElement.is('.ui-dialog')) {
                    objOverlay.css({ 'top': 0, 'left': 0 });
                }

                var objImg = $('<img>').attr('src', '/content/images/loading.gif').attr('alt', 'Processing ... Please Wait').attr('height', '60').attr('width', '160');
                var objContent = $('<div>').addClass('content').appendTo(objOverlay).append(objImg).css({ 'width': objImg.width() });
                $('<div>').addClass('bg').appendTo(objOverlay);

                // Position the content in the center of the overlay
                var 
                nOverlayHeight = objOverlay.height(),
                nOverlayWidth = objOverlay.width(),
                nContentHeight = objImg.height(),
                nContentWidth = objImg.width();
                var nHeightCenter = (nOverlayHeight - nContentHeight) / 2;
                var nWidthCenter = (nOverlayWidth - nContentWidth) / 2;
                // Check if centering the element on the screen is necessary (i.e. the Height Center is off the screen)
                var 
                nScreenTop = $(window).scrollTop(),
                nScreenHeight = $(window).height();
                var nScreenCenter = nScreenTop + ((nScreenHeight - nContentHeight) / 2) - objOffset.top;
                if (nHeightCenter < nScreenTop || nHeightCenter > (nScreenTop + nScreenHeight))
                    nHeightCenter = nScreenCenter;

                // Center the content within the overlay/screen
                objContent.css({ 'top': nHeightCenter, 'left': nWidthCenter });
            });
        },
        hide: function (elementSelector) {
            /// <summary>Removes any existing overlays over the supplied object</param>
            /// <param name="elementSelector">A jQuery selector or object used to determince which elements to modify</param>

            // Validity check
            if (!elementSelector) { return; }

            // Process each element
            $(elementSelector).each(function (elemIndex, elemObject) {
                var objElement = $(elemObject);

                // Remove any existing offset elements
                $('.overlay', objElement).remove();
            });
        }
    };
})(jQuery);

function Forms_AddHandlers(parent) {
    /// <summary>Adds formfield and validate event handlers to a form</summary>
    /// <param name="parent">the jQuery selector/object to use to find elements to add handlers to</param>

    // Validity check
    if (!parent) { return; }

    // Add formfield handlers
    var objParent = $(parent);

    // Handle 'Enter' key presses by clicking the first button
    objParent.find('input[type="text"],input[type="password"]').keydown(function (event) {
        // track enter key
        var keycode = (event.keyCode ? event.keyCode : (event.which ? event.which : event.charCode));
        if (keycode == 13) { // keycode for enter key
            // force the 'Enter Key' to implicitly click the default button
            var objThis = $(this), objButton = [], nTries = 0;

            // Check if we have a default button defined in the form
            var parentForm = objThis.closest('form');
            if (parentForm.length == 0) {
                objButton = $('.default-button');
            } else {
                objButton = $('.default-button', parentForm);
            }

            while (objButton.length == 0 && nTries < 4 && objThis.is(':not(.ui-dialog)'))
            {
                objButton = objThis.find('input[type="button"],input[type="submit"],input[type="image"],.fs-button-click').filter(':visible');
                objThis = objThis.parent();
            }
            if (objButton.length > 0) {
                objButton.trigger('click');
            }
            return false;
        } else {
            return true;
        }
    });

    // Remove unwanted focus lines when links are clicked
    objParent.find("a").each(function () {
        var fCallback = function () {
            // Remove the focus outline
            if (this.blur) { this.blur(); } // most browsers 
            if (this.hideFocus) { this.hideFocus = true; } // internet explorer
            if (this.style) { this.style.outline = 'none'; }  // mozilla
        }
        var objThis = $(this);
        objThis.mouseup(fCallback);
        objThis.mousedown(fCallback);
    });

    // Add validate event handlers
    objParent.find('select.validate').change(function () { Validate(this); });
    objParent.find('input.validate').filter('[type="checkbox"]').change(function () { Validate(this); });
    objParent.find('input.validate').filter('[type!="checkbox"]').blur(function () { Validate(this); });
}

// Disables a form button
function Forms_DisableButton(sender) {
    /// <summary>Disables a link/button used for a form. Returns FALSE if the button was successfully disabled, and TRUE if the button is already disabled (i.e. the calling method should stop processing)</summary>
    /// <param name="sender">The link/button to disable</param>

    if (!sender) { return false; }
    var objSender = $(sender);
    if (objSender.length == 0) { return false; }
    if (objSender.is(':disabled') || objSender.attr('disabled') == 'disabled') { return true; }

    objSender.attr('disabled', 'disabled');
    return false;
}
// Enables a form button
function Forms_EnableButton(sender) {
    /// <summary>Enables a link/button used for a form</summary>
    /// <param name="sender">The link/button to enable</param>

    if (!sender) { return sender; }
    var objSender = $(sender);
    if (objSender.length == 0) { return sender; }

    objSender.removeAttr('disabled');
    return sender;
}
// -------------- Validation Functions ------------- //
function Validate(object, validateChildren) {
    /// <summary>Validates an object, and optionally its children as well</summary>
    /// <param name="object">The jQuery selector for the object to validate</param>
    /// <param name="validateChildren">Indicates if child input fields should also be validated</param>

    // Validity check
    if (!object) { return true; }

    // Ensure the object is valid
    var objToValidate = $(object);
    if (objToValidate.length == 0) { return false; }

    // Check if we are validiting a single item
    if (arguments.length < 2 || !arguments[1]) {
        var bReturn = true; // return value

        objToValidate.each(function () {
            var bSubValid = true; // checks if the object in the each function is valid
            var bIsValidType = true; // indicates if the element is one that we will process for validation
            var objSub = $(this);

            // Validate the single item
            switch (this.tagName.toUpperCase()) {
                case 'SELECT':
                    bSubValid = this.selectedIndex > 0;
                    break;
                case 'INPUT':
                    if (objSub.attr('type').toUpperCase() == 'CHECKBOX') {
                        bSubValid = objSub.is(':checked');
                    } else {
                        var szVal = objSub.val();
                        if (objSub.is('.formfield') && objSub.attr('title')) {
                            szVal = szVal.replace(objSub.attr('title'), '');
                        }
                        if (objSub.is('.integer')) {
                            if (!parseInt(szVal, 10) || parseInt(szVal, 10) < 1) { bSubValid = false; }
                            else { bSubValid = true; }
                        } else if (objSub.is('.number')) {
                            if (!parseFloat(szVal) || parseFloat(szVal) < 1) { bSubValid = false; }
                            else { bSubValid = true; }
                        } else { bSubValid = szVal && szVal.length > 0; }
                    }
                    break;
                case 'TEXTAREA':
                    // Normal text area
                    if (objSub.is(':not(.tinymce)') || !tinyMCE) {
                        bSubValid = objSub.val().length > 0;
                    } else {
                        // TinyMCE text area
                        var objTinyMCE = tinyMCE.get(objSub.attr('id'));
                        if (!objTinyMCE) {
                            bSubValid = objSub.is(':not(:empty)');
                        } else {
                            var szMceContent = objTinyMCE.getContent();
                            bSubValid = szMceContent && szMceContent.length > 0;

                            // We do not get a blur event from tinyMCE, so add a keypress
                            //      event handle to remove the validation message
                            var fKeyPress = function (ed, e) {
                                objTinyMCE.onKeyUp.remove(fKeyPress);
                                setTimeout(function () { Validate(objSub); }, 100);
                            };
                            if (!bSubValid) {
                                objTinyMCE.onKeyUp.add(fKeyPress);
                            }
                        }
                    }
                    break;
                default:
                    bSubValid = true;
                    bIsValidType = false;
                    break;
            }

            // Hide/show the element
            if (bIsValidType) {
                if (bSubValid) {
                    objSub.each(function () {
                        var objErrorMessage = $('#' + this.id + '-rfv');
                        if (objErrorMessage.length == 0) {
                            objErrorMessage = $('.' + $(this).attr('name') + '-rfv', $(this).parent().parent());
                        }
                        objErrorMessage.addClass('none');
                    });
                } else {
                    objSub.each(function () {
                        var objErrorMessage = $('#' + this.id + '-rfv');
                        if (objErrorMessage.length == 0) {
                            objErrorMessage = $('.' + $(this).attr('name') + '-rfv', $(this).parent().parent());
                        }
                        objErrorMessage.removeClass('none');
                    });
                    bReturn = false;
                }
            }
        });

        // All set
        return bReturn;
    } else {
        // Get all the child input fields
        var objFormInputs = objToValidate.find('.validate:visible:not(.none),.validate.tinymce:not(.none)');
        var bValid = true;
        objFormInputs.each(function () {
            if (!Validate(this)) {
                bValid = false;
                // we don't return false because we always want to validate the entire form
            }
        });

        return bValid;
    }
}
function ValidateHideMessage(object, hideChidlren) {
    /// <summary>Resets all validation messages back to a hidden state for an object, and optionally its children as well</summary>
    /// <param name="object">The jQuery selector for the object to validate</param>
    /// <param name="hideChildren">Indicates if child input fields should also have validation messages hidden</param>

    // Validity check
    if (!object) { return; }

    // Ensure the object is valid
    var objToValidate = $(object);
    if (objToValidate.length == 0) { return; }

    // Check if we are validiting a single item
    if (arguments.length < 2 || !arguments[1]) {
        objToValidate.each(function () {
            var objSub = $(this);

            // Reset all corresponding messages
            objSub.each(function () {
                var objErrorMessage = $('#' + this.id + '-rfv');
                if (objErrorMessage.length == 0) {
                    objErrorMessage = $('.' + $(this).attr('name') + '-rfv', $(this).parent().parent());
                }
                objErrorMessage.addClass('none').removeAttr('style');
            });
        });
    } else {
        // Get all the child input fields
        var objFormInputs = objToValidate.find('.validate');
        objFormInputs.each(function () {
            ValidateHideMessage(this);
        });
    }
}

// This function cancels an event (it's called from the switchNavMode function
function cancelEvent(e) {
    // Parameters:
    //      e = the event to cancel


    // Make sure we have the event
    if (!e) {
        e = window.event;
        // Make sure we could get the event
        if (!e) { return; }
    }


    // Stop the event
    if (e.stopPropagation) { e.stopPropagation(); }
    if (e.preventDefault) { e.preventDefault(); }
    e.cancelBubble = true;
    e.cancel = true;
    e.returnValue = false;


    // All done
    return false;
}

jQuery(document).ready(function ($) {
    // Add form handlers
    Forms_AddHandlers(document);

    // Bind a handler for changing Organization/Location
    $('#ddlOrganizationList').change(SetOrganization);

    // Add functionality for Language selection in the footer
    jQuery('select#localization').change(function (changeEvent) {
        // Ensure the current value is valid
        if (this.selectedIndex < 1) { return; }

        // Create the callback function
        var funcCultureCallback = function (response) {
            if (response) {
                //alert('%%Resources:/, Language%% changed');
                location.reload(true);
            }
        };

        // Set the culture using AJAX
        $.getJSON("/Account/SetCulture", { cultureLCID: $(this).val() }, funcCultureCallback);
        return false;
    });

    // Check for empty grids
    GridCheckNoData();

    // Setup form submission links
    $('.form-submit-link[data-form-id]').live('click', function (e) {
        // Ensure the target form exists
        var targetForm = $($(this).data('formId'));
        if (targetForm.length > 0) {
            e.preventDefault();

            targetForm.submit();
        }
    });
});

function ResetDialog(dialog) {
    /// <summary>Removes a dialog from the page</summary>
    /// <param name="dialog">The dialog to remove from the page</param>

    // Validity check
    if (!dialog) { return; }

    // Reset the dialog
    var objThis = $(dialog);
    objThis.dialog('close');
    objThis.dialog('destroy');
    objThis.remove();
};

// Generates a random string of characters and numbers
function GetRandomString(lengthCount) {
    /// <summary>Generates a random string of characters and numbers</summary>
    /// <param name="lengthCount">The number of characters for the random string</param>

    // Make sure the parameter is valid
    lengthCount = parseInt(lengthCount, 10);
    if (!lengthCount || lengthCount < 1) { return ''; }

    // Create the random string
    var szRandomString = '';
    var aCharacterValues = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
    var nLength = aCharacterValues.length;
    var nRandomNum = 0;

    for (var i = 0; i < lengthCount; i++) {
        nRandomNum = Math.floor(Math.random() * nLength);
        szRandomString = szRandomString + aCharacterValues[nRandomNum];
    }

    // Return the random string
    return szRandomString;
}

// Transforms a CustomerMatch list from the server into a <ul> populated element
function LoadCustomerMatches(elementSelector, dataResponse, buttonID, buttonText) {
    /// <summary>Transforms a CustomerMatch list from the server into a UL populated element</summary>
    /// <param name="elementSelector">A jQuery selector or jQuery object containing a reference to the UL element to populate with matches</param>
    /// <param name="dataResponse">A server response of CustomerMatch objects to use when populating the UL element</param>
    /// <param name="buttonID">The prefix for the match button, e.g. "btnChooseCustomer-"</param>
    /// <param name="buttonText">The value/display text for the match button, e.g. "Update Customer"</param>

    // Validity check
    if (!elementSelector || !dataResponse) { return; }

    // Get optional parameters
    var szButtonID = arguments.length > 2 ? buttonID : null;
    var szButtonText = arguments.length > 3 ? buttonText : null;

    // Get the match list
    var objMatchList = $(elementSelector).empty();
    
    // Process the CustomerMatch list
    $(dataResponse).each(function (matchIndex, matchCustomer) {
        var objMatchItem = $('<li>').appendTo(objMatchList);
        if (matchIndex % 2 == 1) { objMatchItem.addClass('alt'); }
        objMatchItem.data('customer', matchCustomer);

        if (szButtonID && szButtonText && !matchCustomer.ReadOnly) {
            var objMatchButton =
                $('<input>').attr('type', 'button').attr('name', buttonID + matchCustomer.CustomerID).attr('id', buttonID + matchCustomer.CustomerID).addClass('fs-button button').val(buttonText);
            $('<div>').addClass('customer-list-content checkarea').appendTo(objMatchItem).append(objMatchButton);
        }

        var objContent = $('<div>').addClass('customer-list-content').appendTo(objMatchItem);
        $('<label>').text(matchCustomer.FullName).appendTo(objContent);
        $('<span>').text(matchCustomer.EmailAddress).appendTo(objContent);

        var szAddress = matchCustomer.Address.Address1;
        if (szAddress && szAddress.length > 0) { szAddress += ', '; }
        else { szAddress = ''; }
        szAddress += matchCustomer.Address.PostalCode;
        $('<span>').text(szAddress).appendTo(objContent);

        objContent = $('<div>').addClass('customer-list-content customer-list-lastcontent').appendTo(objMatchItem);
        $('<strong>').text('Home: ').prependTo($('<span>').text(matchCustomer.HomePhone).appendTo(objContent));
        $('<strong>').text('Work: ').prependTo($('<span>').text(matchCustomer.WorkPhone).appendTo(objContent));
        $('<strong>').text('Mobile: ').prependTo($('<span>').text(matchCustomer.MobilePhone).appendTo(objContent));

        // Add the currently assigned salesperson's (if any) name to the results
        var employee = 'Currently UNASSIGNED';
        if (matchCustomer.Employee && matchCustomer.Employee.ID > 0) {
            employee = 'Currently assigned to: ' + matchCustomer.Employee.FullName;
        }
        objContent = $('<div>').addClass('customer-list-assigned-employee').appendTo(objMatchItem);
        $('<strong>').text(employee).appendTo(objContent);
    });
}

// Toggles the visibility of the printout of matching customers
function ToggleCustomerMatchPrintout(customerList, showPrintout) {
    /// <summary>Function to hide the printout for similar customers based on Last Name</summary>
    /// <param name="customerList">A jQuery selector or jQuery object containing a reference to the UL element to populate with matches</param>
    /// <param name="showPrintout">Optional: Indicates if the printout should be shown, otherwise it will be hidden</param>

    // Validity check
    if (!customerList) { return; }
    var objCustomerList = $(customerList);

    // Hide a visible printout
    if (!arguments || arguments.length < 1 || !showPrintout) {
        if (objCustomerList.is(':visible')) {
            objCustomerList.slideUp(700, function () {
                objCustomerList.addClass('hide').removeAttr('style');
                if (objCustomerList.is('.customer-list')) {
                    objCustomerList.empty();
                } else {
                    $('.customer-list', objCustomerList).empty();
                }
            });
        } else {
            objCustomerList.addClass('hide').removeAttr('style');
            if (objCustomerList.is('.customer-list')) {
                objCustomerList.empty();
            } else {
                $('.customer-list', objCustomerList).empty();
            }
        }
    } else {
        // Show a hidden printout
        if (!objCustomerList.is(':visible')) {
            objCustomerList.slideDown(700, function () {
                objCustomerList.removeClass('hide').removeAttr('style');
            });
        }
    }
}

var g_arrOrganizationChangedFunctions = [];
function SetOrganization() {
    /// <summary>Handles the change event for a select element and changes the working organization/location for this session. The "this" object should refer to the select element containing available organization/location values.</summary>

    if ($('#isDirtyMain').val() == "true") {
        if (confirm('Are you sure you want to leave this organization? (Data you have entered will be lost by leaving)')) {
            // Reset flags & leave
            isDirty = false;
            $('isDirtyMain').val('false');

            // Cancel the edit of the profile
            loadContentIntoTab($('#currCustomerID').val(), "Profile");

            // Get the dropdown
            var objThis = $(this).attr('disabled', 'disabled');

            // Get the new location value
            var nOrganizationID = parseInt(objThis.val(), 10);
            if (isNaN(nOrganizationID) || !nOrganizationID) { return; }

            // Update the location
            $.getJSON("/Account/SetOrganization", { organizationID: nOrganizationID }, function (response) {
                objThis.removeAttr('disabled', 'disabled');
                if (response) {
                    FS.Messaging.info('Successfully changed location.');
                    for (var i = 0; i < g_arrOrganizationChangedFunctions.length; i++) {
                        var fChangedFunction = g_arrOrganizationChangedFunctions[i];
                        if ($.isFunction(fChangedFunction)) { fChangedFunction(); }
                    }
                } else {
                    FS.Messaging.error('Could not change location. Please refresh and try again.');
                }
            });
        } else {
            // Don't want to leave
            // -------------------
            // Reset the dialog back to the original
            $(this).val($.data(this));

            return false;
        }
    } 

    // Get the dropdown
    var objThis = $(this).attr('disabled', 'disabled');

    // Get the new location value
    var nOrganizationID = parseInt(objThis.val(), 10);
    if (isNaN(nOrganizationID) || !nOrganizationID) { return; }

    // Update the location
    $.getJSON("/Account/SetOrganization", { organizationID: nOrganizationID }, function (response) {
        objThis.removeAttr('disabled', 'disabled');
        if (response) {
            FS.Messaging.info('Successfully changed location.');
            for (var i = 0; i < g_arrOrganizationChangedFunctions.length; i++) {
                var fChangedFunction = g_arrOrganizationChangedFunctions[i];
                if ($.isFunction(fChangedFunction)) { fChangedFunction(); }
            }
        } else {
            FS.Messaging.error('Could not change location. Please refresh and try again.');
        }
    });
}

function GridCheckNoData() {
    /// <summary>Checks grids to see if an empty result message should be shown.</summary>

    $('.t-grid .t-no-data td').each(function (cellIndex, cellObject) {
        var objGrid = $(cellObject).closest('.t-grid');
        var objEmptyMessage = $('#' + objGrid.attr('id') + '-nodata');

        if (objEmptyMessage.length > 0) {
            $(cellObject).empty().append(objEmptyMessage.clone().removeAttr('id'));
        }
    });
}

jQuery.fn.serializeObject = function (prefix, excludeEmpty) {
    var formDomNode = this;
    var namePrefix = prefix || '';
    var skipEmptyFields = arguments.length < 2 || !excludeEmpty;

    var arrayData = this.serializeArray();
    var objectData = {};

    // Transform the serialized array into an object
    jQuery.each(arrayData, function () {

        // Get the key for the property
        var key = this.name;
        // Check if we should apply the prefix to this key
        if (jQuery('input[name="' + key + '"][data-noprefix]', formDomNode).size() == 0) {
            key = namePrefix + key;
        }

        // Get the value for the property
        var value;
        if (this.value != null) { value = this.value; } else { value = ''; }
        if (!skipEmptyFields || value) {
            // Update the object
            if (objectData[key] != null) {
                if (!objectData[key].push) {
                    objectData[key] = [objectData[key]];
                }
                objectData[key].push(value);
            } else {
                objectData[key] = value;
            }
        }
    });
    return objectData;
};

// Title casing serialization
jQuery.fn.titleCase = function () {
    var _dataKey = 'titlecasedisabled';

    // Setup title casing on all textboxes
    jQuery(this).filter('input[type="text"]').each(function () {
        $(this).keyup(function (e) {
            // Check if we have a value
            var val = $(this).val();
            if (!val || val.length == 1) {
                $(this).removeData(_dataKey);
            }

            // Get the key entered
            var keyCode = (e.keyCode ? e.keyCode : e.which);
            switch (keyCode) {
                case 8: // back space
                case 127: // delete
                    // Don't perform any more title casing on this element
                    $(this).data(_dataKey, true);
                default:
                    break;
            }

            // Keep upper casing the first character in the value
            //      and lowercasing the rest unless they use backspace
            var casingDisabled = $(this).data(_dataKey);
            if (!casingDisabled) {
                $(this).val(val.charAt(0).toUpperCase() + val.substr(1).toLowerCase());
                // Do not continue to lowercase additional values,
                //      maybe we don't want to do this b/c of caps lock
                $(this).data(_dataKey, true);
            }
        });
    });

    // Fluent
    return this;
};
