/* functions.js: 
------------------------------------------------------------------------------*/
var left_menu_node_count = 7;
var left_menu_node_prefix = 'left_menu_item_';
var selected_menu_item;
var selected_menu_item_sub;

function highlight_selection() {
    var page_location = String(this.location).split("?")[0]; //Querystring may contain /
    page_location = page_location.split("/");
    page_location = page_location[page_location.length - 1];
    var params_index = page_location.indexOf(".aspx");
    if (params_index != -1) {
        page_location = page_location.substring(0, params_index);
    }
    switch (page_location) {
        case "ManageUsers":
        case "EditUser":
            set_selection('left_menu_item_1_sub_1');
            break;
        case "ManageNetworks":
        case "EditNetwork":
            set_selection('left_menu_item_1_sub_2');
            break;
        case "ManageFacilities":
        case "EditFacility":
            set_selection('left_menu_item_1_sub_3');
            break;
        case "CancerTypes":
        case "EditCancerType":
            set_selection('left_menu_item_1_sub_4');
            break;
        case "Drugs":
        case "EditDrug":
            set_selection('left_menu_item_1_sub_5');
            break;
        case "Overheads":
        case "EditOverhead":
            set_selection('left_menu_item_1_sub_8');
            break;
        case "ManageTariffs":
        case "EditHrg4Pt0TariffDetails":
            set_selection('left_menu_item_1_sub_9');
            break;
        case "BatchingProtocols":
        case "BatchingProtocolDetails":
        case "BatchingProtocolTasks":
            set_selection('left_menu_item_1_sub_6');
            break;
        case "ResourceTypes":
        case "EditResourceType":
            set_selection('left_menu_item_1_sub_7');
            break;
        case "PatientForecast":
        case "PatientForecastDetails":
        case "PatientForecastAnnualDistribution":
        case "PatientForecastEditProbabilities":
        case "PatientForecastRegimens":
            set_selection('left_menu_item_2_sub_1');
            break;
        case "SchedulingDistributionsPage":
        case "SchedulingDistributionDetailsPage":
            set_selection('left_menu_item_2_sub_2');
            break;
        case "ResourceList":
        case "ManageResources":
        case "EditResource":
            set_selection('left_menu_item_2_sub_3');
            break;
        case "CapacityModifier":
        case "CapacityModifierDetails":
        case "CapacityModifierEditDetail":
            set_selection('left_menu_item_2_sub_4');
            break;
        case "RegimenOverrides":
        case "RegimenOverridesDetails":
        case "RegimenOverridesEditRegimen":
        case "RegimenOverridesAddRegimens":
            set_selection('left_menu_item_2_sub_5');
            break;
        case "CycleOverrides":
        case "CycleOverridesDetails":
        case "CycleOverridesAddCycles":
        case "CycleOverridesEditCycle":
            set_selection('left_menu_item_2_sub_6');
            break;
        case "TaskRequirement":
        case "TaskRequirementsTasks":
        case "TaskRequirementsEditTask":
        case "TaskRequirementsTaskResources":
        case "TaskRequirementsEditTaskResource":
            set_selection('left_menu_item_2_sub_7');
            break;
        case "PharmacyBatching":
        case "PharmacyBatchingProtocolTasks":
        case "PharmacyBatchingProtocols":
        case "PharmacyBatchingEditProtocol":
            set_selection('left_menu_item_2_sub_8');
            break;
        case "ManageRegimens":
        case "EditRegimen":
        case "RegimensMassUpdate":
        case "ViewRegimen":
        case "RegimenTree":
        case "RegimenWizard":
            set_selection('left_menu_item_3_sub_1');
            break;
        case "ManageStandardRegimens":
        case "ManageStandardRegimenRequests":
        case "EditStandardRegimen":
        case "ViewStandardRegimen":
            set_selection('left_menu_item_3_sub_6');
            break;
        case "AssignStandardRegimen":
            set_selection('left_menu_item_3_sub_7');
            break;
        case "ManageCycles":
        case "EditCycle":
        case "CyclesMassUpdate":
        case "ViewCycle":
            set_selection('left_menu_item_3_sub_2');
            break;
        case "ManageTasks":
        case "EditTask":
        case "ManageTaskResources":
            set_selection('left_menu_item_3_sub_3');
            break;
        case "StandardRegimens":
            set_selection('left_menu_item_3_sub_4');
            break;
        case "ManageSimulations":
        case "AddSimulation":
        case "SimulationReports":
            set_selection('left_menu_item_4_sub_1');
            break;
        case "AggregatedReports":
            set_selection('left_menu_item_6_sub_1');
            break;
        case "Forum":
            set_selection('left_menu_item_5_sub_1');
            break;
        case "Support":
            set_selection('left_menu_item_5_sub_2');
            break;
        case "Documentation":
            set_selection('left_menu_item_5_sub_3');
            break;
        case "Broadcast":
            set_selection('left_menu_item_5_sub_4');
            break;
        case "UpdateProfile":
            document.getElementById("update_profile_menu_item_bg").className = "top_item_act maxw";
            break;
        case "TariffManagement":
        case "EditHrg3Pt5Tariff":
        case "EditHrg4Pt0Tariff":
        case "ViewHrg3Pt5Tariff":
        case "ViewHrg4Pt0Tariff":
            set_selection('left_menu_item_7_sub_1');
            break;
        case "ManageResourceTypeListCosts":
        case "ManageMedicineListCosts":
        case "ManageOverheadListCosts":
        case "ViewResourceTypeListCosts":
        case "EditResourceTypeListCosts":
        case "ViewMedicineListCosts":
        case "EditMedicineListCosts":
        case "ManageOverheadListCosts":
        case "ViewOverheadListCosts":
        case "EditOverheadListCosts":
            set_selection('left_menu_item_7_sub_2');
            break;
        case "FinanceSimulationAlignmentManagement":
        case "EditFinanceSimulationAlignment":
        case "ViewFinanceSimulationAlignment":
            set_selection('left_menu_item_7_sub_3');
            break;
    }
    if (selected_menu_item != null) {
        change_node_status(selected_menu_item);
    }
    if (selected_menu_item_sub != null) {
        document.getElementById(selected_menu_item_sub.id + '_bg').className = 'sub_item_over maxw';
    }
}

function set_selection(selected_item) {
    selected_menu_item_sub = document.getElementById(selected_item);
    selected_menu_item = document.getElementById(selected_item.substring(0, selected_item.indexOf("_sub")));
}

function change_node_status(obj) {
    var ch_status = document.getElementById(obj.id + '_sub').style.display == 'block' ? 'none' : 'block';
    var itemid = selected_menu_item != null ? selected_menu_item.id : '';
    try {
        for (var i = 1; i <= left_menu_node_count; i++) {
            if (String(left_menu_node_prefix + i) != itemid) {
                if (document.getElementById(left_menu_node_prefix + i + '_bg') != null) {
                    document.getElementById(left_menu_node_prefix + i + '_bg').className = 'top_item maxw';
                    document.getElementById(left_menu_node_prefix + i + '_sub').style.display = 'none';
                }
            }
        }
    }
    catch (e)
	{ }
    if (document.getElementById(obj.id + '_bg').className != 'top_item_act maxw') {
        document.getElementById(obj.id + '_sub').style.display = ch_status;
        document.getElementById(obj.id + '_bg').className = ch_status == 'block' ? 'top_item_act maxw' : 'top_item maxw';
    }
}

function buttonact(obj, clss) {
    if (document.getElementById(obj.id + '_sub').style.display != 'block') {
        document.getElementById(obj.id + '_bg').className = clss;
    }
}

function subbuttonact(obj, clss) {
    var itemid = null;
    if (selected_menu_item_sub != null) {
        itemid = selected_menu_item_sub.id;
    }
    if (obj.id != itemid) {
        document.getElementById(obj.id + '_bg').className = clss;
    }
}

function go(url) {
    if (url == '#') {
        location.reload();
    }
    else {
        location.href = url;
    }
}

function goNewWindow(url) {
    if (url == '#') {
        location.reload();
    }
    else {
        window.open('' + url, 'mywin', 'toolbar=0,resizable=1,scrollbars=1');
    }
}

function clickControl(keyCode, controlID) {
    if (event.keyCode == keyCode) {
        var c = document.getElementById(controlID);
        if (c != null && c != "undefined" && c.click) {
            event.returnValue = false;
            c.click();
            return false;
        }
    }
}

function submitClick(ctrl, ctrlid) {
    if (typeof (Page_ClientValidate) == 'function') {
        if (Page_ClientValidate() == false) {
            return;
        }
    }
    setTimeout("disableControl('" + ctrl.id + "')", 100);
    if (ctrlid != undefined) {
        setTimeout("disableControl('" + ctrlid + "')", 100);
    }
}

function disableControl(ctrlid) {
    document.getElementById(ctrlid).disabled = true;
}

function showGridPopup(item, div) {
    if (trim(div.innerHTML) == '')
        div.innerHTML = 'n/a';
    else
        div.style.display = 'block';
}

function hideGridPopup(div) {
    div.style.display = 'none';
}

function trim(s) {
    var m = s.match(/^\s*(\S+(\s+\S+)*)\s*$/);
    return (m == null) ? "" : m[1];
}
/* from Common.js
------------------------------------------------------------------------------*/
function selectAllCheckedChanged(sender) {
    var parentTable = sender.parentNode.parentNode.parentNode.parentNode;
    for (i = 1; i < parentTable.rows.length; i++) {
        var checkBox = getCheckBox(parentTable.rows[i]);
        if (checkBox != null) {
            checkBox.checked = sender.checked;
        }
    }
}

function checkOneSelected(gridId, zeroMessage, multipleMessage, confirmationMessage) {
    if (!checkNoZeroSelected(gridId, zeroMessage)) {
        return false;
    }
    var selectedRows = getSelectedRows(gridId);

    if (selectedRows.length == 1) {
        if (confirmationMessage != undefined) {
            return confirm(confirmationMessage);
        }
        return true;
    }
    else {
        if (multipleMessage != undefined) {
            alert(multipleMessage);
        }
        return false;
    }
}

function checkNoZeroSelected(gridId, zeroMessage, confirmationMessage) {
    //var selectedRows = getSelectedRows(gridId);
    var selectedRows = $find(gridId).get_selectedItemsInternal();

    if (selectedRows.length == 0) {
        if (zeroMessage != undefined) {
            alert(zeroMessage);
        }
        return false;
    }
    else {
        if (confirmationMessage != undefined) {
            return confirm(confirmationMessage);
        }
        else {
            return true;
        }
    }
}

function getSelectedRow(gridId) {
    return getSelectedRows(gridId)[0];
}

function getSelectedRows(gridId) {
    var selectedRows = new Array();
    var gridControl = document.getElementById(gridId);

    if (gridControl == null)
        return selectedRows;

    for (i = 1; i < gridControl.rows.length; i++) {
        if (isRowSelected(gridControl.rows[i])) {
            selectedRows.push(gridControl.rows[i]);
        }
    }

    return selectedRows;
}

function isRowSelected(row) {
    var checkBox = getCheckBox(row);
    if (checkBox == null) {
        return false;
    }

    return checkBox.checked;
}

function getCheckBox(row) {
    var node = row.cells[0].childNodes[0];
    if (node.type == "checkbox") {
        return node;
    }

    return null;
}
/*
Re-usable utility functions used by Attendances and Regimens UI:
------------------------------------------------------------------------------*/
function NewID(array) {
    var minimum = 0;
    for (var index = 0; index < array.length; index++) {
        var id = array[index].ID;
        if (id < minimum) {
            minimum = id;
        }
    }
    return (minimum - 1);
}

function ResetChildIDs(entity) {
    for (var p in entity) {
        var propertyValue = entity[p];
        if (classOf(propertyValue) == "Array") {
            var counter = -1;
            $(propertyValue).each(function(i, item) {
                if (item.ID) {
                    item.ID = counter--;
                    ResetChildIDs(item);
                }
            });
        }
    }
}


function CopyArrayProperty(source, destination, matchBy, arrayName, propertyName) {
    /*CopyArrayProperty(cycleAttendance.Attendance,
    updatedAttendance,
    "ID",
    "Tasks",
    "CycleAttendanceTask");*/

    $(source[arrayName]).each(
        function(i1, sourceItem) {
            $(destination[arrayName]).each(function(i2, destinationItem) {
                if (sourceItem[matchBy] == destinationItem[matchBy]) {
                    destinationItem[propertyName] = sourceItem[propertyName];
                }
            })
        }
    );
}

function classOf(o) {
    if (undefined === o) return "Undefined";
    if (null === o) return "Null";
    return {}.toString.call(o).slice(8, -1);
}

function DropDownList(id, options, selectedValue, includePleaseSelect) {
    var list = $("<select></select>");
    list.attr("id", id);
    if (options) {
        AppendOptions(list, options, selectedValue, includePleaseSelect);
    }
    return list;
}

function AppendOptions(list, options, selectedValue, includePleaseSelect) {
    if (selectedValue == undefined) {
        selectedValue = false;
    }
    if (includePleaseSelect == undefined) {
        includePleaseSelect = true;
    }

    if (includePleaseSelect) {
        list.append("<option value=\"-1\">Please select...</option>");
    }
    for (var index = 0; index < options.length; index++) {
        var option = $("<option></option>");
        option.attr("value", options[index].Value);
        if (selectedValue != null && options[index].Value == selectedValue) {
            option.attr("selected", "selected");
        }
        option.html(options[index].Text);
        list.append(option);
    }
}

function formatJson(json, newLineString, indentString) {
    if (newLineString == undefined) {
        newLineString = "<br />";
    }
    if (indentString == undefined) {
        indentString = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
    }

    var sb = new StringBuilder();
    var indent = 0;

    for (index = 0; index < json.length; index++) {
        var ch = json.charAt(index);

        if (ch == "[") {
            indent++;
        }
        else if (ch == "]") {
            indent--;
        }
        else if (ch == "{") {
            sb.append(newLineString);
            for (var i = 0; i < indent; i++) {
                sb.append(indentString);
            }
        }

        sb.append(ch);
    }
    return sb.toString();
}

String.prototype.offsets = function(str) {
    var offsets = new Array();

    var index = 0;
    while (index < this.length) {
        var indexOf = this.indexOf(str, index);
        if (indexOf == -1) {
            index = this.length;
        } else {
            index = (indexOf + str.length);
            offsets.push(indexOf);
        }
    }
    return offsets;
}

String.prototype.countOf = function(str) {
    var count = 0;
    var index = 0;
    while (index < this.length) {
        var indexOf = this.indexOf(str, index);
        if (indexOf == -1) {
            index = this.length;
        } else {
            index = (indexOf + str.length);
            count++;
        }
    }
    return count;
}

String.prototype.trim = function() {
    return (this.replace(/^[\s\xA0]+/, "").replace(/[\s\xA0]+$/, ""));
}

String.prototype.startsWith = function(str) {
    return (this.match("^" + str) == str);
}

String.prototype.endsWith = function(str) {
    return (this.match(str + "$") == str);
}

function StringBuilder() {
    this.buffer = [];
};
var p = StringBuilder.prototype;
p.append = function(src) {
    this.buffer[this.buffer.length] = src;
};
p.flush = function() {
    this.buffer.length = 0;
};
p.getLength = function() {
    return this.buffer.join('').length;
};
p.toString = function(delim) {
    return this.buffer.join(delim || '');
};

function removeItems(array, itemsToRemove) {
    if (!/Array/.test(itemsToRemove.constructor)) {
        itemsToRemove = [itemsToRemove];
    }
    var j;
    for (var i = 0; i < itemsToRemove.length; i++) {
        j = 0;
        while (j < array.length) {
            if (array[j] == itemsToRemove[i]) {
                array.splice(j, 1);
            } else {
                j++;
            }
        }
    }
}
function removeAt(array, index) {
    var part1 = array.slice(0, index);
    var part2 = array.slice(index + 1);
    return (part1.concat(part2));
}
function exists(array, predicate) {
    for (var i = 0; i < array.length; i++) {
        if (predicate(array[i]))
        { return true; }
    } return false;
}
(function($) {
    $.fn.extend({
        exists: function(predicate) {
            for (var i = 0; i < this.length; i++) {
                if (predicate(this[i]))
                { return true; }
            } return false;
        },
        max: function(predicate) {
            var max = null;
            for (var i = 0; i < this.length; i++) {
                var val = predicate(this[i]);
                if (max == null) {
                    max = val;
                }
                else {
                    if (val != null && val > max)
                    { max = val; }
                }
            }
            return max;
        },
        contains: function(element) {
            for (var i = 0; i < this.length; i++) {
                if (this[i] == element)
                { return true; }
            } return false;
        },
        findByProperty: function(propertyName, value) {
            for (var i = 0; i < this.length; i++) {
                if (this[i][propertyName] == value)
                { return this[i]; }
            } return null;
        },
        indexOfID: function(id) {
            for (var i = 0; i < this.length; i++) {
                if (this[i].ID == id)
                { return i; }
            } return -1;
        },
        findByID: function(id) {
            for (var i = 0; i < this.length; i++) {
                if (this[i].ID == id) { return this[i]; }
            } return null;
        },
        findByValue: function(value) {
            var matches = $.grep(this, function(element) { return element.Value == value; })
            return matches.length == 0 ? { Value: -1, Text: ""} : matches[0];
        },
        firstOrDefault: function(match) {
            for (var i = 0; i < this.length; i++) {
                if (match(this[i]))
                { return this[i]; }
            } return null;
        },
        findAll: function(match) {
            var matchArray = new Array();
            for (var i = 0; i < this.length; i++) {
                if (match(this[i]))
                { matchArray.push(this[i]); }
            } return matchArray;
        },
        copy: function() {
            var newArray = new Array();
            for (var i = 0; i < this.length; i++) {
                newArray.push(this[i]);
            }
            return newArray;
        }
    });
})(jQuery);

String.prototype.format = function() {
    var pattern = /\{\d+\}/g;
    var args = arguments;
    return this.replace(pattern, function(capture) { return args[capture.match(/\d+/)]; });
}

function deepObjCopy(dupeObj) {
    if (dupeObj === null) {
        return null;
    } else {
        var retObj = new Object();
        if (typeof (dupeObj) == 'object') {
            if (dupeObj != null && typeof (dupeObj.length) != 'undefined')
                var retObj = new Array();
            for (var objInd in dupeObj) {
                if (typeof (dupeObj[objInd]) == 'object') {
                    retObj[objInd] = deepObjCopy(dupeObj[objInd]);
                } else if (typeof (dupeObj[objInd]) == 'string') {
                    retObj[objInd] = dupeObj[objInd];
                } else if (typeof (dupeObj[objInd]) == 'number') {
                    retObj[objInd] = dupeObj[objInd];
                } else if (typeof (dupeObj[objInd]) == 'boolean') {
                    ((dupeObj[objInd] == true) ? retObj[objInd] = true : retObj[objInd] = false);
                }
            }
        }
        return retObj;
    }
}
function ApplySortOrder(array) {
    array.sort(function(x, y) {
        return (x.SortOrder == y.SortOrder) ? x.ID - y.ID : x.SortOrder - y.SortOrder;
    });

    for (var index = 0; index < array.length; index++) {
        array[index].SortOrder = (index + 1);
    }
}

function BindToggle(element, target) {
    element.mouseover(function() { target.toggle(); });
    element.mouseout(function() { target.toggle(); });
}

function WindowWidth() {
    var width;
    if (typeof (window.innerWidth) == 'number') {
        //Non-IE
        width = window.innerWidth;
    } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
        //IE 6+ in 'standards compliant mode'
        width = document.documentElement.clientWidth;
    } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
        //IE 4 compatible
        width = document.body.clientWidth;
    }
    return width;
}
function WindowHeight() {
    var height = 0;
    if (typeof (window.innerWidth) == 'number') {
        //Non-IE
        height = window.innerHeight;
    } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
        //IE 6+ in 'standards compliant mode'
        height = document.documentElement.clientHeight;
    } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
        //IE 4 compatible
        height = document.body.clientHeight;
    }
    return height;
}

function EnsurePrompt() {
    //This is just to get input boxes started in IE7 - who deems them unsecure.
    Opera = (navigator.userAgent.toLowerCase().indexOf("opera") != -1);
    Safari = (navigator.userAgent.toLowerCase().indexOf("safari") != -1);
    Explorer = (document.all && (!(Opera || Safari)));
    Explorer7 = (Explorer && (navigator.userAgent.indexOf("MSIE 7.0") >= 0));

    if (Explorer7 && location.href.indexOf("file:") != 0) {
        prompt("This is just to get input boxes started in IE7 - who deems them unsecure.", "I like input boxes...");
    }
}
function RoundNumber(num, decPlaces) {
    //var result = Math.round(num * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
    //return result;
    return parseFloat(num.toFixed(decPlaces));
}
/*
------------------------------------------------------------------------------*/
function HandleServerSideLogout(message) {
    //TODO: Validation before submit -> username and password must have values
    var f = $("#ServerSideLogout");
    if (f.length == 0) {
        f = $("<form id=\"ServerSideLogout\" action=\".\" method=\"post\" autocomplete=\"off\"></form>");
        f.appendTo($(document.body));
    }

    var table = $("<table></table>");
    var rowUsername = $("<tr><td>Username:</td></tr>").appendTo(table);
    var rowPassword = $("<tr><td>Password:</td></tr>").appendTo(table);
    var cellUsername = $("<td></td>").appendTo(rowUsername);
    var cellPassword = $("<td></td>").appendTo(rowPassword);

    var usernameInput = $("<input type=\"text\" id=\"username\" value=\"\" />").appendTo(cellUsername);
    var passwordInput = $("<input type=\"password\" id=\"password\" value=\"\" />").appendTo(cellPassword);

    if (message != undefined) {
        $("<tr><td colspan=\"2\" style=\"color:red\">{0}</td></tr>".format(message)).appendTo(table);
    }

    function OnShow() {
        usernameInput.focus();
    }

    function Submit(e) {        
        var callback = function(data, textStatus) {
            if (data.indexOf("action=\"Default.aspx\"") == -1) {
                overlayClose_Handler(e);
                HandleServerSideLogout("Invalid login");
            }
        }

        var type = "html";
        var url = applicationPath + "Home.aspx?ReturnUrl=%2fDefault.aspx";
        var data = {
            "lgnLogin$Password": passwordInput.val(),
            "lgnLogin$UserName": usernameInput.val(),
            "lgnLogin$btnLogin": "Log In",
            "__EVENTARGUMENT": "",
            "__EVENTTARGET": ""
        };
        $.post(url, data, callback, type);
        overlayClose_Handler(e);
    }

    f.overlay({
        width: 250,
        height: 70,
        title: "Login",
        content: table,
        onShow: OnShow,
        showClose: false,
        fixedHeight: false,
        actions: [{ Name: "Submit", Click: Submit }, { Name: "Cancel", Type: "button", Click: overlayClose_Handler}]
    });
}

function _DisplayingBlocking(title) {

}

/*
    Notes: Return false from callback if you do not want to close the overlay
*/
function BlockingClientServerRequest(handler, jsonRequest, callback, handleError, blockingOptions) {
    /// <summary>
    /// Makes a request to the server but also blocks the UI, stopping the user from performing any actions
    /// </summary>
    var overlayDisplayed = false;
    var displayOverlayTimeout = setTimeout(function() {
        overlayDisplayed = true;
        $(document.body).overlay({
            width: 600,
            height: 31,
            title: blockingOptions.title,
            content: "<div class='loader'></div>",
            showClose: false,
            fixedHeight: false
        });
    }, 1000);

    // RS - 01/02/2010: Modified callback to be called as part of the closing callback.
    //                  This prevents the issue where a callback opens an overlay that needs to be kept open
    //                  then this timeout closes the timeout
    // Defect: D-05864
    var callback2 = function(jsonResponse) {
        clearTimeout(displayOverlayTimeout);
        setTimeout(function() {
            var close = true;
            try {
                var result = callback(jsonResponse)
                if (typeof(result) != 'undefined' && !result) {
                    close = false;
                }
            }
            catch (exists) { }

            if (overlayDisplayed && close) {
                $(document.body).removeOverlay();
            }

        }, 1000);

        /*setTimeout(function() {
        callback(jsonResponse);
        }, 100);*/
    };

    var handleError2 = function(message) {
        clearTimeout(displayOverlayTimeout);
        $(document.body).removeOverlay();

        if (typeof handleError !== "undefined") {
            handleError(message);
        }
    };

    ClientServerRequest(handler, jsonRequest, callback2, handleError2);
}

function ClientServerRequest(handler, jsonRequest, callback, handleError) {
    try {
        if (currentUnitID) {
            // currentUnitID is on the master page
            // null for login page.
            jsonRequest.CurrentUnitID = currentUnitID;
        }
        //TODO: Remove in release mode
        ClientServerRequestProxy(jsonRequest, callback, handleError);
    }
    catch (e) {
        try {
            var responseHandler = function(jsonResponse) {
                callback(jsonResponse);
            };
            var data = { handler: handler, jsonRequest: $.toJSON(jsonRequest) };

            var error = function(XMLHttpRequest, textStatus, errorThrown) {
                var message = "";
                if (textStatus != undefined) { message += textStatus; }
                if (errorThrown != undefined) { errorThrown += textStatus; }

                if (handleError == undefined) {
                    alert("ClientServerRequest error:\r\n" + message);
                }
                else {
                    handleError(message);
                }
            };

            var dataFilter = function(data, type) {
                if (type == "json" && data.indexOf("lgnLogin") > -1) {
                    /*
                    if (data.indexOf("type=\"submit\"") > -1
                    && data.indexOf("type=\"text\"") > -1
                    && data.indexOf("type=\"password\"") > -1) {
                    }
                    <input type="submit" name="ctl00$ContentPlaceHolder1$lgnLogin$btnLogin" value="Log In" onclick="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;ctl00$ContentPlaceHolder1$lgnLogin$btnLogin&quot;, &quot;&quot;, true, &quot;lgnLogin&quot;, &quot;&quot;, false, false))" id="ctl00_ContentPlaceHolder1_lgnLogin_btnLogin" class="button_lb cursor" />
                    <input name="ctl00$ContentPlaceHolder1$lgnLogin$UserName" type="text" maxlength="50" id="ctl00_ContentPlaceHolder1_lgnLogin_UserName" class="loginTextbox" />
                    <input name="ctl00$ContentPlaceHolder1$lgnLogin$Password" type="password" maxlength="25" id="ctl00_ContentPlaceHolder1_lgnLogin_Password" class="loginTextbox" />
                    */
                    data = "{Data: [], IsSuccess: false, IsAuthenticated: false, ValidationSummaries: [{ Failures: [{ErrorMessage:\"User is not authenticated\"}], Children: [], ObjectSummary: { TypeName: \"\", ObjectName: \"\"}}]}";
                }
                return data;
            };

            //http://docs.jquery.com/Ajax/jQuery.ajax
            return $.ajax({
                type: "POST",
                url: entitiesHandlerUrl,
                dataFilter: dataFilter,
                data: data,
                success: responseHandler,
                dataType: "json",
                error: error,
                cache: false
            });

            /*
            $.post(entitiesHandlerUrl, { handler: handler, jsonRequest: $.toJSON(jsonRequest) }, function(jsonResponse) {
            callback(jsonResponse);
            }, "json");
            */
        }
        catch (e) {
            if (handleError == undefined) {
                alert("ClientServerRequest error:\r\n" + e.message);
            }
            else {
                handleError(e.message);
            }
        }
    }
}
//Used to indicate changes have been made on the client - currently used in manage regimen and manage attendance screens
var isDirty = false;

function RootError(jsonResponse) {
    var error;
    try {
        var sb = new StringBuilder();
        $(jsonResponse.ValidationSummaries).each(
                function(i, validationSummary) {
                    if (!(validationSummary.Children.length == 0 && validationSummary.Failures.length == 0)) {
                        if (validationSummary.ObjectSummary != null) {
                            sb.append("{0} {1}", validationSummary.ObjectSummary.TypeName, validationSummary.ObjectSummary.ObjectName);
                        }
                        for (var index = 0; index < validationSummary.Failures.length; index++) {
                            var f = validationSummary.Failures[index];
                            sb.append("\r\n{0}: {1}".format(f.PropertyName, f.ErrorMessage));
                        }
                    }
                });
        error = sb.toString();
    }
    catch (e) {
        error = "Operation failed";
    }
    return error;
}
/*
------------------------------------------------------------------------------*/
function setCookie(name, value, expires) {
    try {
        document.cookie = name + "=" + escape(value) + "; path=/" + ((expires == null) ? "" : "; expires=" + expires.toGMTString());
    }
    catch (e) { }
}

function getCookie(name) {
    try {
        var dc = document.cookie;
        var cname = name + "=";
        if (dc.length > 0) {
            begin = dc.indexOf(cname);
            if (begin != -1) {
                begin += cname.length;
                end = dc.indexOf(";", begin);
                if (end == -1)
                    return unescape(dc.substr(begin));
                else {
                    return unescape(dc.substring(begin, end));
                }
            }
        }
    }
    catch (e) { }
    return null;
}
/*
------------------------------------------------------------------------------*/

// Displays a tooltip for a checkbox item.
function DisplayFunctionTooltip(sender, ddlDurationUnitsId, tooltip) {
    var $tooltip = $('<div id="divFunctionTooltip"><p></p></div>');
    $(sender).append($tooltip);

    var htmlEncoded = tooltip.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
    $tooltip.find("p").html(htmlEncoded.replace(/\n/g, '<br />'));

    var x = y = 0;
    var e = window.event;
    var parent = sender;

    // Offset the tooltip hor-position from that of the mouse cursor
    var offset = 8;

    // Determine vertical position of checkbox
    while (parent != null) {
        y += parent.offsetTop;
        parent = parent.offsetParent;
    }

    // Determine horizontal position of mouse
    if (e.pageX || e.pageY) {
        x = e.pageX;
    }
    else if (e.clientX || e.clientY) {
        x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
    }

    // THIS WORKS ONLY IF THE WIDTH AND HEIGHT STYLES HAVE BEEN SET
    // Determine whether the tooltip will overflow on the right
    var viewportWidth = document.documentElement.clientWidth;
    var tooltipWidth = $tooltip.width() + (2 * parseInt($tooltip[0].currentStyle['padding']));

    if (x + offset + tooltipWidth > viewportWidth) {
        x -= (tooltipWidth + offset + offset);
    }

    $tooltip.css({ "top":  y + offset, "left": x + offset, "display": "block" });

    // IE6 issue - dropdwon showing through the div
    if ((x + offset < 620) && (ddlDurationUnitsId != null)) {
        var ddlDurationUnits = document.getElementById(ddlDurationUnitsId);
        if (ddlDurationUnits) {
            ddlDurationUnits.style.visibility = "hidden";
        }
    }

    return $tooltip;
}

// Hides the function checkbox tooltip.
function HideFunctionTooltip(ddlDurationUnitsId) {
    $("#divFunctionTooltip").remove();

    // Display the duration dropdown again
    var ddlDurationUnits = document.getElementById(ddlDurationUnitsId);
    if (ddlDurationUnits) {
        ddlDurationUnits.style.visibility = "visible";
    }
}

/*
------------------------------------------------------------------------------*/

function deserializeDate(date) {
    var d = new Date(parseInt(date.replace("/Date(", "").replace(")/", ""), 10));
    return d.getDate() + "-" + (d.getMonth() + 1) + "-" + d.getFullYear();
}

/*-------------------------------------------------------------------------------*/



$(function() {
    window.onerror = function(msg, url, lineNo) {
        var data = {
            message: msg,
            scriptUrl: url,
            pageUrl: location.href,
            lineNumber: lineNo
        };

        $.post("/Handlers/ClientErrorHandler.ashx", data, null, "json");
    };
});



