﻿(function() {

    var Compli = new Object(),

$$ = Compli.Config = {
    TimeoutWindowMM: 10,
    TimeoutWarningLength: 5,
    TimeoutWarningPopupID: "",
    LogoutPage: "/Managed/logout.aspx",
    Occlusion: null,
    PopupProcessingID: "",
    PopupProcessingInitiallyVisible: false,
    HyperPrintID: "",
    PopupInvalidPostbackDataID: "",
    ShowOcclusionOnPostBack: true,
    PrintView: false,
    PopupDirtyID: ""
},

__ = Compli.Privates = {
    IE6: false,
    CurrentPopup: null,
    PopupQueue: new Array(),
    PopupQueueHP: new Array(),
    PopupCount: 0,
    HiddenDropDowns: new Array()
};

    window.Compli = Compli.prototype = {
        Config: Compli.Config,

        Initialize: function() {
            var x = $(".HyperPrint").get()
            if (x != null) Compli.Config.HyperPrintID = x.id;

            jQuery.fn.extend({
                SlideDownMenu: window.Compli.Tabs.SlideDownMenu,
                SlideInlineMenu: window.Compli.Tabs.SlideInlineMenu
            });

            $(".slideDownMenu").SlideDownMenu();
            $(".slideInlineMenu").SlideInlineMenu();

            var contactTab = $(".HeaderNavMenu td:first");
            var contactDiv = $("#contactInfoDiv");
            if (contactTab.length > 0 && contactDiv.length > 0) {
                var contactClose = contactDiv.find(".contactInfoClose");
                contactDiv.css({ "top": "0", "left": contactTab.position().left + "px" });
                contactTab.add(contactClose).click(function(e) {
                    if (contactDiv.is(":hidden")) contactDiv.show();
                    else contactDiv.hide();
                    e.stopPropagation();
                });
            }

            contactDiv.click(function(e) {
                e.stopPropagation();
            });

            window.Compli.Table.Initialize();
            window.Compli.Forms.Initialize();
        },

        Table: {
            Initialize: function() {
                var tables = $(".rowUpDown");
                tables.each(function() {
                    var table = $(this);
                    var downBtns = table.find(".tableRowDown");
                    var upBtns = table.find(".tableRowUp");
                    downBtns.last().hide();
                    upBtns.first().hide();
                    downBtns.add(upBtns).each(function() {
                        var row = $(this).closest("tr");
                        var upBtn = row.find(".tableRowUp");
                        var downBtn = row.find(".tableRowDown");
                        var isUp = $(this).hasClass("tableRowUp");
                        var lastIndex = table.get(0).rows.length - 1;
                        $(this).click(function() {
                            var otherRow;
                            if (isUp) {
                                otherRow = row.prev("tr");
                                otherRow.before(row);
                            } else {
                                otherRow = row.next("tr");
                                otherRow.after(row);
                            }

                            otherRowUp = otherRow.find(".tableRowUp");
                            otherRowDown = otherRow.find(".tableRowDown");

                            if (row.get(0).rowIndex == 0) {
                                upBtn.hide();
                            } else {
                                upBtn.show();
                            }

                            if (row.get(0).rowIndex == lastIndex) {
                                downBtn.hide();
                            } else {
                                downBtn.show();
                            }

                            if (otherRow.get(0).rowIndex == 0) {
                                otherRowUp.hide();
                            } else {
                                otherRowUp.show();
                            }

                            if (otherRow.get(0).rowIndex == lastIndex) {
                                otherRowDown.hide();
                            } else {
                                otherRowDown.show();
                            }

                            window.Compli.Table.ColorTable(table);
                        });
                    });
                });
            },

            ColorTable: function(table, clickable) {
                var even;
                var odd;
                if (clickable == true) {
                    even = "even";
                    odd = "odd";
                } else {
                    even = "even_NoHover";
                    odd = "odd_NoHover";
                }

                var i = 0;
                table.find("tr").each(function() {
                    var row = $(this);
                    if (i % 2 == 0) {
                        row.removeClass(odd).addClass(even);
                    } else {
                        row.removeClass(even).addClass(odd);
                    }
                    i = 1 - i;
                });
            }
        },

        SessionManagement: {
            InitSessionTimeout: function(timeoutMinutes, popupId) {
                if (popupId) { $$.TimeoutWarningPopupID = popupId; }
                if (timeoutMinutes) $$.TimeoutWindowMM = timeoutMinutes;

                window.Compli.FauxPopups.HideFauxPopup($$.TimeoutWarningPopupID);

                if (window.Compli.SessionManagement.PendingTimeout)
                    self.clearTimeout(window.Compli.SessionManagement.PendingTimeout);
                if (window.Compli.SessionManagement.PendingTimeoutWarning)
                    self.clearTimeout(window.Compli.SessionManagement.PendingTimeoutWarning);

                window.Compli.SessionManagement.PendingTimeoutWarning =
                    self.setTimeout('Compli.SessionManagement.ShowTimeoutWarning()',
                        ($$.TimeoutWindowMM - $$.TimeoutWarningLength) * 60000);
            },

            TimeoutSession: function() {
                top.location = $$.LogoutPage;
            },

            ShowTimeoutWarning: function() {
                window.Compli.FauxPopups.ShowFauxPopup($$.TimeoutWarningPopupID, true);
                window.Compli.SessionManagement.PendingTimeout =
                    self.setTimeout('window.Compli.SessionManagement.TimeoutSession();', $$.TimeoutWarningLength * 60000);
            },

            PendingTimeout: null,
            PendingTimeoutWarning: null
        },

        Forms: {
            Dirty: false,
            IsDirtyMethods: new Array(),
            DirtyCheckDelay: 0,
            OnCleanMethod: null,
            AddDirtyCheck: function(f) {
                window.Compli.Forms.IsDirtyMethods.push(f);
            },
            IsDirty: function(f) {
                if (window.Compli.Forms.OverrideDirty) return false;

                window.Compli.Forms.OnCleanMethod = f;

                if (window.Compli.Forms.Dirty) {
                    window.Compli.Forms.ShowDirtyDialog();
                    return true;
                }

                var a = window.Compli.Forms.IsDirtyMethods;

                for (i = 0; i < a.length; ++i) {
                    if (a[i]() || window.Compli.Forms.CheckInputDirty()) {
                        window.Compli.Forms.ShowDirtyDialog();
                        return true;
                    }
                }

                if (f) { window.Compli.Forms.CallCleanMethod(); window.Compli.Forms.Dirty = false; }

                return false;
            },
            CallCleanMethod: function() {
                if (window.Compli.Forms.OnCleanMethod != null) {
                    if (window.Compli.Forms.DirtyCheckDelay > 0) {
                        setTimeout("window.Compli.Forms.OnCleanMethod();", window.Compli.Forms.DirtyCheckDelay);
                    } else {
                        window.Compli.Forms.OnCleanMethod();
                    }
                }
            },
            CheckInputDirty: function() {
                var arr = $.makeArray(
                    $(".inputDirty").map(function() {
                        if ($(this).val() != $(this).attr("orgVal")) {
                            return true;
                        } else {
                            return false;
                        }
                    })
                );
                for (var i = 0; i < arr.length; ++i) {
                    if (arr[i] == true) return true;
                }
            },
            OverrideDirty: false,
            ShowDirtyDialog: function(f) {
                window.Compli.Forms.OverrideDirty = true;
                $("#" + $$.PopupDirtyID).find('.ignoreDirty').unbind('click').click(function() {
                    window.Compli.Forms.CallCleanMethod();
                    window.Compli.Forms.OverrideDirty = false;
                    window.Compli.Forms.Dirty = false;
                });
                window.Compli.FauxPopups.ShowFauxPopup($$.PopupDirtyID, true);
            },
            Initialize: function() {
                $(".inputDirty").each(function() { $(this).attr("orgVal", $(this).val()); });
            }
        },

        TextValidation: {

            ValidateTextBox: function(e, txtBox) {

                var keycode;
                if (window.event)
                    keycode = window.event.keyCode;
                else if (e)
                    keycode = e.which;

                var e = e || window.event;

                if ((keycode == 8) || (keycode == 9) || (keycode == 35) || (keycode == 36) || (keycode == 37) || (keycode == 38) || (keycode == 46))
                    return true;

                var maxLen = txtBox.getAttribute("CompliMaxLen");
                if ((maxLen != null) || (maxLen != "")) {

                    var x = parseInt(maxLen);
                    if (txtBox.value.length >= maxLen)
                        return false;

                    return true;
                }
            }
        },

        FauxPopups: {
            ShowOcclusion: function() {
                var backgroundOcclusion = $$.Occlusion;
                backgroundOcclusion.style.display = '';

                var content1 = document.getElementById('tableContent');
                var content2 = document.getElementById('content');

                __.IE6 = getCSSRule('.IE6absolute');

                if (__.IE6) {
                    window.Compli.IE6Support.HideDropdowns();
                    var dimensions = window.Compli.Geometry.GetDocumentDimensions();

                    backgroundOcclusion.style.width = Math.max(content1.offsetWidth, content2.offsetWidth) + 'px';
                    backgroundOcclusion.style.height = (dimensions.y) + 'px';
                    return;
                }

                if (content1 && content2)
                    backgroundOcclusion.style.width = Math.max(content1.offsetWidth, content2.offsetWidth) + 'px';
            },

            HideOcclusion: function() {
                var backgroundOcclusion = $$.Occlusion;
                if (backgroundOcclusion) backgroundOcclusion.style.display = 'none';
                window.Compli.IE6Support.UnhideDropdowns();
            },

            DisplayAndCenterFauxPopup: function(popupId, highPriority) {
                window.Compli.FauxPopups.ShowFauxPopup(popupId, highPriority);
            },

            FauxPopup: function(popup, highPriority, popupInit) {
                this.id = popup.id;
                this.popup = popup;
                this.highPriority = highPriority;
                this.popupInit = popupInit;
            },

            ShowFauxPopup: function(popupId, highPriority, popupInit) {
                var popup = typeof popupId == "object" ? $(popupId).get(0) : $("#" + popupId).get(0);
                if (!popup) return;
                popup.style.margin = '0px 0px 0px 0px';
                if (highPriority == true && __.CurrentPopup && __.CurrentPopup.id != $$.PopupProcessingID) {
                    __.CurrentPopup.popup.style.display = 'none';
                    window.Compli.FauxPopups.QueuePopupForDisplay(__.CurrentPopup);
                    __.CurrentPopup = null;
                }
                if (__.CurrentPopup == null) {
                    window.Compli.FauxPopups.ShowOcclusion();
                    popup.style.display = '';
                    window.Compli.FauxPopups.CenterFauxPopup(popup);
                    if (typeof (popupInit) == 'function') popupInit();
                    __.CurrentPopup = new window.Compli.FauxPopups.FauxPopup(popup, highPriority, popupInit);
                } else {
                    window.Compli.FauxPopups.QueuePopupForDisplay(new window.Compli.FauxPopups.FauxPopup(popup, highPriority, popupInit));
                }
            },

            CenterFauxPopup: function(popup) {
                var midpoint = window.Compli.Geometry.GetWindowMidpoint();
                var x = midpoint.x;
                var y = midpoint.y;

                if (__.IE6) {
                    var scrollxy = window.Compli.Geometry.GetScrollXYOffset();
                    x += scrollxy.x;
                    y += scrollxy.y;
                }

                popup.style.left = (x - popup.offsetWidth / 2) + 'px';
                popup.style.top = (y - popup.offsetHeight / 2) + 'px';
            },

            HideFauxPopup: function(popupId) {
                var popup = typeof popupId == "object" ? $(popupId).get(0) : $("#" + popupId).get(0);
                if (popup) popup.style.display = 'none';

                if ((__.CurrentPopup != null) && (popup.id == __.CurrentPopup.id)) {
                    __.CurrentPopup = null;
                    if ((__.PopupCount != null) && (__.PopupCount > 0)) {
                        var nextPopup = window.Compli.FauxPopups.GetNextPopup();
                        window.Compli.FauxPopups.ShowFauxPopup(nextPopup.id, nextPopup.highPriority, nextPopup.popupInit);
                    } else {
                        window.Compli.FauxPopups.HideOcclusion();
                    }
                }

                if (!__.CurrentPopup) {
                    window.Compli.FauxPopups.HideOcclusion();
                }
            },

            QueuePopupForDisplay: function(fauxPopup, highPriority) {
                __.PopupCount++;
                if (highPriority) {
                    __.PopupQueueHP[__.PopupQueueHP.length] = fauxPopup;
                } else {
                    __.PopupQueue[__.PopupQueue.length] = fauxPopup;
                }
            },

            GetNextPopup: function() {
                if (__.PopupQueueHP.length > 0) {
                    __.PopupCount--;
                    return __.PopupQueueHP.shift();
                } else if (__.PopupQueue.length > 0) {
                    __.PopupCount--;
                    return __.PopupQueue.shift();
                } else {
                    return null;
                }
            },

            ShowProcessingPopup: function() {
                window.Compli.FauxPopups.ShowFauxPopup($$.PopupProcessingID, true);
                return true;
            },

            HideProcessingPopup: function() {
                eval($$.PopupProcessingID + "_PopupControl.HidePopup()");
                return true;
            },

            ProcessingHack: function(popup) {
                __.CurrentPopup = popup;
            }
        },

        Geometry: {
            Point: function(x, y) {
                this.x = x;
                this.y = y;
            },

            GetDocumentDimensions: function() {
                var x, y;
                var maxXY = document.getElementById('bottomright');

                x = maxXY.offsetLeft + maxXY.offsetWidth;

                if (typeof (window.innerWidth) == 'number') {
                    //Non-IE
                    y = window.innerHeight;
                } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
                    //IE 6+ in 'standards compliant mode'
                    y = document.documentElement.clientHeight;
                } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
                    //IE 4 compatible
                    y = document.body.clientHeight;
                } else {
                    y = 0;
                }

                y = Math.max(y, maxXY.offsetTop + maxXY.offsetHeight);

                return new window.Compli.Geometry.Point(x, y);
            },

            GetWindowDimensions: function() {
                var x, y;

                if (typeof (window.innerWidth) == 'number') {
                    //Non-IE
                    x = window.innerWidth;
                    y = window.innerHeight;
                } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
                    //IE 6+ in 'standards compliant mode'
                    x = document.documentElement.clientWidth;
                    y = document.documentElement.clientHeight;
                } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
                    //IE 4 compatible
                    x = document.body.clientWidth;
                    y = document.body.clientHeight;
                } else {
                    x = 0;
                    y = 0;
                }

                return new window.Compli.Geometry.Point(x, y);
            },

            GetWindowMidpoint: function() {
                var dimensions = window.Compli.Geometry.GetWindowDimensions();
                return new window.Compli.Geometry.Point(dimensions.x / 2, dimensions.y / 2);
            },

            GetScrollXYOffset: function() {
                var x, y;
                x = window.pageXOffset ||
                document.body.scrollLeft ||
                document.documentElement.scrollLeft;
                y = window.pageYOffset ||
                document.body.scrollTop ||
                document.documentElement.scrollTop;
                return new window.Compli.Geometry.Point(x ? x : 0, y ? y : 0);
            }
        },

        IE6Support: {
            HideDropdowns: function() {
                var elems = document.getElementsByTagName("select");
                var hiddenDropDowns = __.HiddenDropDowns;
                for (var i = 0; i < elems.length; i++) {
                    var elem = elems[i];
                    if (elem.style.display != 'none') {
                        hiddenDropDowns.push(elem);
                        elem.style.display = 'none';
                    }
                }
            },

            UnhideDropdowns: function() {
                var hiddenDropDowns = __.HiddenDropDowns;
                if (hiddenDropDowns)
                    for (var i = 0; i < hiddenDropDowns.length; i++) {
                    var elem = hiddenDropDowns[i];
                    elem.style.display = 'inline';
                }
                __.HiddenDropDowns = new Array();
            }
        },

        Printing: {
            DisableControlsForPrint: function(e) {
                window.Compli.Printing.DisableControlsForPrint_Inputs();
                window.Compli.Printing.DisableControlsForPrint_Selects();
                window.Compli.Printing.DisableControlsForPrint_TextAreas();
                window.Compli.Printing.DisableControlsForPrint_Anchors();
            },

            DisableControlsForPrint_Inputs: function() {
                var elems = document.getElementsByTagName("input");
                for (var i = 0; i < elems.length; i++) {
                    var elem = elems[i];
                    switch (elem.type) {
                        case 'submit':
                            elem.style.display = 'none';
                            break;
                        case 'checkbox':
                            window.Compli.Printing.ConvertCheckboxInputToDiv(elem);
                            break;
                        case 'text':
                            window.Compli.Printing.ConvertTextInputToDiv(elem);
                            break;
                        case 'password':
                            elem.readOnly = true;
                            break;
                        case 'radio':
                            window.Compli.Printing.ConvertCheckboxInputToDiv(elem);
                            break;
                    }
                }
            },

            ConvertCheckboxInputToDiv: function(elem) {
                if (elem.style.display != 'none') {
                    var newDiv = document.createElement("SPAN");
                    newDiv.style.textAlign = "center";
                    newDiv.style.border = "1px solid silver";
                    newDiv.style.backgroundColor = "white";
                    newDiv.style.color = "black";
                    newDiv.style.display = "inline";
                    newDiv.style.width = "10px"
                    newDiv.style.height = "10px"
                    if (elem.style.fontFamily == "") {
                        newDiv.style.fontFamily = "courier";
                    } else {
                        newDiv.style.fontFamily = elem.style.fontFamily;
                    }

                    newDiv.id = elem.uniqueID + "_div";

                    var newTxt;
                    if (elem.checked == false) {
                        newTxt = "&nbsp;";
                    } else {
                        newTxt = "<img src='/images/AssessmentAnswerCorrect.gif' height=10px width=10px/>";
                    }

                    newDiv.innerHTML = newTxt;
                    elem.parentNode.insertBefore(newDiv, elem);
                    elem.style.display = "none";
                }
            },

            ConvertTextInputToDiv: function(elem) {
                if (elem.style.display != 'none') {
                    var newTable = document.createElement("TABLE");
                    newTable.style.border = "1px solid silver";
                    newTable.style.display = "inline";
                    var newBody = document.createElement('TBODY');
                    newTable.appendChild(newBody);

                    var newRow = document.createElement("TR");
                    newBody.appendChild(newRow);
                    var newcell = document.createElement("TD");
                    newcell.style.width = elem.clientWidth + "px";
                    newcell.style.color = 'black';
                    newRow.appendChild(newcell);

                    if (elem.style.fontFamily == "") {
                        newcell.style.fontFamily = "courier";
                    } else {
                        newcell.style.fontFamily = elem.style.fontFamily;
                    }

                    newcell.id = elem.uniqueID + "_div";

                    var newTxt;
                    if (elem.value == "") {
                        newTxt = "&nbsp;";
                    } else {
                        newTxt = elem.value.replace(/\n/gi, "<BR/>");
                        newTxt = newTxt.replace(/\s\s/gi, "&#xa0;&#xa0;");
                    }

                    newcell.innerHTML = newTxt;

                    elem.parentNode.insertBefore(newTable, elem);
                    elem.style.display = "none";
                }
            },

            DisableControlsForPrint_Selects: function() {
                var elems = document.getElementsByTagName("select");
                for (var i = 0; i < elems.length; i++) {
                    var elem = elems[i];
                    window.Compli.Printing.ConvertTextInputToDiv(elem);
                }
            },

            DisableControlsForPrint_Anchors: function() {
                var elems = document.getElementsByTagName("a");
                for (var i = 0; i < elems.length; i++) {
                    var elem = elems[i];
                    elem.removeAttribute('href');
                    elem.onclick = 'return false;';
                }

                $(".HyperPrint").attr('href', 'javascript:window.print();');
            },

            DisableControlsForPrint_TextAreas: function() {
                var elems = document.getElementsByTagName("textarea");
                for (var i = 0; i < elems.length; i++) {
                    var elem = elems[i];
                    window.Compli.Printing.ConvertTextInputToDiv(elem);
                }
            }
        },

        Date: {
            toMMDDYYYY: function(date) {
                if (date.getMonth() + 1 < 10)
                    return "0" + (date.getMonth() + 1) + "/" + date.getDate() + "/" + date.getFullYear();
                else
                    return (date.getMonth() + 1) + "/" + date.getDate() + "/" + date.getFullYear();
            },

            stringToDate: function(dateString) {
                // is the string a date?
                if (/Invalid|NaN/.test(new Date(dateString))) return new Date(dateString);

                var d = dateString;

                // handle two-digit years, choosing 2029 as the pivot year
                d = d.replace(
                    new RegExp("/(\\d{2})$", ""),
                    function($0, $1) {
                        if (parseInt($1) <= 29) return ("/20" + $1);
                        else return ("/19" + $1);
                    }
                );

                // verify we have a four digit year now, return invalid date otherwise
                if (!/\/\d{4}$/.test(d)) { return new Date("..."); }

                // success, return the date
                return new Date(d);
            }
        },

        Format: {
            numberToString: function(n) {
                if (n == 0) return "-"
                return n += "";
            },
            trim: function(str) {
                return str.replace(/^\s+|\s+$/, '');
            }
        },

        Events: {
            OnWindowResize: function() {
                if ($$.Occlusion.style.display != 'none') {
                    window.Compli.FauxPopups.ShowOcclusion();
                    if (__.CurrentPopup)
                        window.Compli.FauxPopups.CenterFauxPopup(__.CurrentPopup.popup);
                }
            },

            SubmitPrePostbackValidation: function() {

                if (window.Compli.Validation.ValidateControlsForDangerousText() > 0) {
                    eval($$.PopupProcessingID + "_PopupControl.HidePopup()");
                    eval($$.PopupInvalidPostbackDataID + "_PopupControl.ShowPopup(true)");
                    return false;
                } else {
                    if ($$.ShowOcclusionOnPostBack == true)
                        window.Compli.FauxPopups.ShowProcessingPopup();
                    return true;
                }
            },

            AJAXEndRequest: function(sender, args) {
                if ($$.ShowOcclusionOnPostBack == true)
                    window.Compli.FauxPopups.HideProcessingPopup();
            }
        },

        Tabs: {
            SelectTab: function(sender) {
                $(sender).addClass("selected").closest("table").find("td.selected").not(sender).removeClass("selected");
            },

            OnClickSetup: function(sender, tabGroupClass, tabClass) {
                var tabGroup = $('.' + tabGroupClass);
                var tab = $('.' + tabClass);
                $(sender).attr('onclick', '');
                $(sender).click(function() {
                    $(sender).addClass("currentTab").siblings().removeClass("currentTab");
                    tabGroup.css('display', 'none');
                    tab.css('display', '');
                });
                $(sender).click();
                tab.find(".loadDelayed").each(function() {
                    if (this.loadDelayedHandler) this.loadDelayedHandler();
                });
            },

            ExpandableMenu: function expandableMenu(rootTab) {
                this.rootTab = rootTab;
                this.menuToShowId = parseInt(rootTab.attr("mid"));
                this.isTop = rootTab.closest("div").hasClass("topMenu");
                this.subMenuContainer = this.isTop ?
                                            rootTab.closest("div").find(".submenuContainer").first()
                                          : rootTab.closest("div.submenuContainer").first();
                this.menuToShow = this.subMenuContainer.find("div.popMenu[mid=" + this.menuToShowId + "]").first();
            },

            ExpandedMenus: new Array(),

            CheckExpanded: function(menuId) {
                var arr = window.Compli.Tabs.ExpandedMenus;
                for (var i = 0; i < arr.length; ++i) {
                    if (menuId == arr[i]) return true;
                }
                return false;
            },

            SlideInlineMenu: function slideInlineMenu() {
                var expandedMenus = $(".expandedMenuList").val();

                if (expandedMenus == undefined) return this;

                var expArr = expandedMenus.split(",");
                for (var i = 0; i < expArr.length; ++i) {
                    window.Compli.Tabs.ExpandedMenus.push(parseInt(expArr[i]));
                }

                this.each(function() {
                    var e = $(this);
                    this.base = window.Compli.Tabs.ExpandableMenu;
                    this.base(e);

                    e.data("tab", this);
                    var tab = e.data("tab");

                    tab.subMenu = e.append('<div class="subMenuHolder"></div>').
                                find('.subMenuHolder').
                                append(tab.menuToShow).
                                find(".popMenu[mid=" + this.menuToShowId + "]");

                    if (window.Compli.Tabs.CheckExpanded(tab.menuToShowId)) tab.subMenu.show();
                });

                this.each(function() {
                    var e = $(this);
                    var menu = e.data("tab");

                    var topMenu;
                    var parentMenu;
                    var siblingMenus;

                    if (menu.isTop) {
                        topMenu = parentMenu = menu.menuToShow.closest(".topMenu");
                        siblingMenus = menu.menuToShow.siblings();
                    } else {
                        topMenu = menu.menuToShow.closest(".topMenu");
                        parentMenu = menu.menuToShow.parent().closest(".popMenu");
                        siblingMenus = parentMenu.find(".popMenu").not(menu.menuToShow);
                    }

                    e.click(function(b) {
                        siblingMenus.each(function() {
                            $(this).find(".popMenu").hide();
                            $(this).hide();
                        });

                        var f = function() {
                            var str =
                            $.makeArray(topMenu.find(".popMenu").filter(":visible").map(function() {
                                return parseInt($(this).attr("mid"));
                            })).join(",");

                            var expirationDate = new Date;
                            expirationDate.setFullYear(expirationDate.getFullYear() + 3);

                            document.cookie = "MenuExpansionState=" + str + ";path=/;expires=" + expirationDate.toGMTString();
                        }

                        var isMenuVisible = menu.menuToShow.is(":visible");
                        if (!isMenuVisible) menu.menuToShow.slideDown(f);
                        else menu.menuToShow.slideUp(f);
                    });
                });

                return this;
            },

            SlideDownMenu: function slideDownMenu() {
                this.each(function() {
                    var e = $(this);
                    this.base = window.Compli.Tabs.ExpandableMenu;
                    this.base(e);
                    this.subMenuHolder = e.find(".subMenuHolder");

                    e.data("menu", this);
                    var menu = e.data("menu");

                    if (!menu.isTop) {
                        if (this.subMenuHolder.length == 0) {
                            menu.menuToShow = e.append('<div class="subMenuHolder"></div>').
                            find('.subMenuHolder').
                            append(menu.menuToShow).
                            find('.popMenu');
                        } else {
                            menu.menuToShow = this.subMenuHolder.find('.popMenu');
                            menu.menuToShow.css({ display: "block" });
                        }
                    }
                });

                this.each(function() {
                    var e = $(this);
                    var menu = e.data("menu");

                    var parentMenu;
                    var siblingMenus;

                    if (menu.isTop) {
                        parentMenu = menu.menuToShow.closest(".topMenu");
                        siblingMenus = menu.menuToShow.siblings();
                    } else {
                        parentMenu = menu.menuToShow.parent().closest(".popMenu");
                        siblingMenus = parentMenu.find(".popMenu").not(menu.menuToShow);
                    }

                    var position = $(this).position();
                    var x = position.left + 5;
                    var y = position.top + $(this).height() + 4;
                    var width = $(this).width() - 5;

                    e.click(function(b) {
                        siblingMenus.each(function() {
                            $(this).find(".popMenu").hide();
                            $(this).hide();
                        });
                        var isMenuVisible = menu.menuToShow.is(":visible");
                        var isSubContainerVisible = menu.subMenuContainer.is(":visible");

                        if (menu.isTop) {
                            menu.subMenuContainer.css({ left: x + "px", top: y + "px", width: width });
                        }
                        if (menu.isTop && isMenuVisible && isSubContainerVisible) {
                            menu.subMenuContainer.slideUp();
                            menu.subMenuContainer.find(".popMenu").hide();
                        } else if (menu.isTop && isSubContainerVisible) {
                            menu.menuToShow.slideDown();
                        } else {
                            if (!isSubContainerVisible) menu.subMenuContainer.show();
                            if (!isMenuVisible) menu.menuToShow.slideDown();
                            else menu.menuToShow.slideUp();
                        }
                    });
                });

                $(".MenuTab").click(function(b) {
                    b.stopPropagation();
                });

                $(document).click(function() {
                    $(".submenuContainer").hide();
                    $(".submenuContainer").find(".popMenu").hide();
                });

                return this;
            }
        },

        Validation: {
            MatchStrings: "input|textarea|select|script|form|body|html|head",

            ValidateControlsForDangerousText: function() {
                var controlsInError =
                window.Compli.Validation.ValidateControlTypeForDangerousText('input').concat(
                    window.Compli.Validation.ValidateControlTypeForDangerousText('textarea'));
                return controlsInError.length;
            },

            ValidateControlTypeForDangerousText: function(controlType) {
                var elems = document.getElementsByTagName(controlType);
                var regExpValidator = new RegExp(".*</?(" + window.Compli.Validation.MatchStrings + ")((\\s+\\w+(\\s*=\\s*(?:\".*?\"|'.*?'|[^'\">\\s]+))?)+\\s*|\\s*)/?>.*");
                regExpValidator.ignoreCase;

                var controlsInError = new Array();
                for (var i = 0; i < elems.length; i++) {
                    if ((elems[i].id.toLowerCase().indexOf('eventvalidation') == -1) &&
                        (elems[i].id.toLowerCase().indexOf('viewstate') == -1) &&
                        (elems[i].id.toLowerCase().indexOf('hdn') == -1)) {
                        var txtValue = elems[i].value.toLowerCase();
                        txtValue = txtValue.replace(/&lt;/i, "<").replace(/&gt;/i, ">");
                        if (regExpValidator.test(txtValue)) {
                            controlsInError.push(elems[i]);
                        }
                    }
                }
                return controlsInError;
            },

            AddValidationAfterInit: function(elem, rule) {
                elem.rules("add", rule);
            },

            Validator: {
                init: function(options) {

                    $.validator.addClassRules({
                        requiredDateRange: { required: true, date: true, dateRange: true }
                    });

                    $.validator.addMethod("dateRangeBounds", function(value, element, params) {
                        var min = new Date(params[0]);
                        var max = new Date(params[1]);
                        var val = new Date(value);
                        return this.optional(element) || (val >= min && val <= max);
                    }, "Please enter valid start and end dates.");

                    options = $.extend(window.Compli.Validation.Validator.defaults, options || {});

                    window.Compli.Validation.Validator = $(document.forms[0]).validate(options);
                },


                addOptions: function(elem, options) {
                    window.Compli.Validation.Validator.defaults =
                        $.extend(window.Compli.Validation.Validator.defaults, options || {});

                    $(elem).remove();

                    if ($('.validateMe').length == 0) {
                        window.Compli.Validation.Validator.init(window.Compli.Validation.Validator.defaults);
                    }
                },

                defaults: {
                    errorPlacement: function(error, element) {
                        error.appendTo($("span[err='" + element.attr("id") + "']"));
                    },
                    errorClass: "errorLabel",
                    onfocusout: false
                }
            }
        },

        Cookies: {
            CreateCookie: function(name, value, days) {
                if (days) {
                    var date = new Date();
                    date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
                    var expires = "; expires=" + date.toGMTString();
                }
                else var expires = "";
                document.cookie = name + "=" + value + expires + "; path=/";
            },

            ReadCookie: function(name) {
                var nameEQ = name + "=";
                var ca = document.cookie.split(';');
                for (var i = 0; i < ca.length; i++) {
                    var c = ca[i];
                    while (c.charAt(0) == ' ') c = c.substring(1, c.length);
                    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
                }
                return null;
            },

            EraseCookie: function(name) {
                window.Compli.Cookies.CreateCookie(name, "", -1);
            }
        },

        Misc: {
            SetLabelText: function(id, text) {
                var lbl = document.getElementById(id);
                if (lbl) lbl.innerHTML = text;
            }
        },

        WebService: function serviceProxy(serviceUrl) {
            var _I = this;
            this.serviceUrl = serviceUrl;

            // *** Call a wrapped object
            this.invoke = function(method, data, callback, error, bare) {
                // *** Convert input data into JSON - REQUIRES Json2.js
                var json = JSON2.stringify(data);

                // *** The service endpoint URL        
                var url = _I.serviceUrl + method;

                $.ajax({
                    url: url,
                    data: json,
                    type: "POST",
                    processData: false,
                    contentType: "application/json",
                    timeout: 10000,
                    dataType: "text",  // not "json" we'll parse
                    success: function(res) {
                        window.Compli.SessionManagement.InitSessionTimeout();

                        if (!callback) return;

                        // *** Use json library so we can fix up MS AJAX dates
                        var result = JSON2.parse(res);

                        // *** Bare message IS result
                        if (bare)
                        { callback(result); return; }

                        // *** Wrapped message contains top level object node
                        // *** strip it off
                        for (var property in result) {
                            callback(result[property]);
                            break;
                        }
                    },
                    error: function(xhr) {
                        if (!error) return;
                        if (xhr.responseText) {
                            var err = JSON2.parse(xhr.responseText);
                            if (err)
                                error(err);
                            else
                                error({ Message: "Unknown server error." })
                        }
                        return;
                    }
                });
            }
        }
    };
})();

$(document).ready(Compli.Initialize);