﻿/// <reference path="/scripts/jquery.1.4.4.js" />
/// <reference path="/scripts/json2.js" />
/// <reference path="/scripts/jquery.1.4.4.min.js" />

window.LOCID_DIALOG_OFFSET_WIDTH = "0";
window.LOCID_DIALOG_OFFSET_HEIGHT = "0";

//var DEV_URL = 'http://abnc-crm3:5560/insurance2011';
//var DEV_USERID = '{080CEDB3-A903-E011-BC90-B8AC6F82C45E}';
//var DEV_URL = 'http://localhost:5555/mindfiresolutions2011';
//var DEV_URL = 'http://localhost:5558/mfbbsrcrm';
//var DEV_USERID = '{939CF975-B368-4200-910F-3BE74AF52C0D}';
var DEV_USERID = '{1187E15F-5DBF-4C58-975E-39479F514836}';
var DEV_URL = 'https://mindfire1.crm5.dynamics.com'; 

var DEV_MODE = false;

var serverUrl;

Crm = function () {
  
    var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc";
    var SOAP_ENDPOINT = "/XRMServices/2011/Organization.svc/web";
    var errorUrl = "/WebResources/abcore_/html/error.htm";

    var errorMessage = "Context to retrieve the Server URL is not available.";
    if (typeof GetGlobalContext != "undefined")
    { serverUrl = GetGlobalContext().getServerUrl(); }
    else {
        if (typeof Xrm != "undefined") {
            serverUrl = Xrm.Page.context.getServerUrl();
        }
        else {
            if (typeof DEV_URL != "undefined") {
                serverUrl = DEV_URL;
                errorUrl = "/abcore_/html/error.htm";
                DEV_MODE = true;
            } else {
                alert(errorMessage);
            }
        }
    }
    if (serverUrl.match(/\/$/)) {
        serverUrl = serverUrl.substring(0, serverUrl.length - 1);
    }


    var _openCrmWindow = function (url, name, features) {
        if (GetGlobalContext().isOutlookClient()) {
            var $w0 = window.external, $w1 = null;
            $w1 = $w0.openWindow(url.toString(), name, features);
            $w1.opener = window.self;
            return $w1;
        } else {
            return window.open(url, name, features);
        }
    }


    var _doRequest = function (options, async, internalCallback, errorCallback) {
        // default settings
        var settings = {
            type: "GET",
            async: async,
            contentType: "application/json; charset=utf-8",
            datatype: "json",
            beforeSend: function (request) {
                request.setRequestHeader("Accept", "application/json");
            },
            error: function (XmlHttpRequest, textStatus, errorThrown) {
                if (XmlHttpRequest.responseText != null) {
                    var sMessage = XmlHttpRequest.responseText;
                    var o = $.parseJSON(sMessage);

                    if (DEV_MODE) {
                        openStdDlg(errorUrl, o, "600", "400", true, false, "center:1;");
                    }
                    else {
                        openStdDlg(serverUrl + errorUrl, o, "600", "400", true, false, "center:1;");
                    }
                    if (errorCallback != null) {
                        errorCallback(o);
                    }
                } else {
                    alert("Error : " + textStatus + ": " + XmlHttpRequest.statusText);
                }
            }
        };
        options = $.extend(settings, options);

        if (!async) {
            var result = $.ajax(options).responseText;
            var jsonResult = (result) ? JSON.parse(result).d : null;

            return !!internalCallback ? internalCallback(jsonResult) : jsonResult;
        }
        else {
            settings.success = function (data, textStatus, XmlHttpRequest) {
                internalCallback(data.d);
            };

            $.ajax(options);
        }
    };


    var _retrieveByUrl = function (restUrl, callback, errcallback) {
        var async = !!callback;
        var query = serverUrl + ODATA_ENDPOINT + "/" + restUrl;

        return _doRequest({ url: query }, async, function (result) {
            if (async)
                callback(result);
            else
                return result;
        }, errcallback);
    };

    var _retrieve = function (entityName, id, columns, callback, errcallback) {
        var async = !!callback;
        var setName = entityName + 'Set';
        var query = serverUrl + ODATA_ENDPOINT + "/" + setName + "(guid'" + id + "')";
        if (columns != null) query += "?$select=" + columns.join(',');

        return _doRequest({ url: query }, async, function (result) {
            if (async)
                callback(result);
            else
                return result;
        }, errcallback);
    };

    var _retrieveMultiple = function (entityName, columns, filter, callback, orderby, errcallback) {
        var async = !!callback;
        var setName = entityName + 'Set';
        var _callback = callback;

        filter = (filter) ? "&$filter=" + filter : '';

        var query = serverUrl + ODATA_ENDPOINT + "/" + setName + "()" + "?";
        if (columns != null) query += "$select=" + columns.join(',');
        if (orderby != null) {
            if (columns != null) query += '&';
            query += "$orderby=" + orderby;
        }
        query += filter;

        var performRequest = function (query, fnCallback) {
            var async = !!fnCallback;
            var options = { url: query }

            return _doRequest(options, async, function (data) {
                var next = data.__next || null;
                var results = data.results || data;
                var response = { 'results': results, 'next': next }

                if (next) { // enable eage loading
                    response.LoadNext = function (callback) {
                        return performRequest(next, callback);
                    };
                }

                if (async)
                    fnCallback(response);
                else
                    return response;
            }, errcallback);
        };

        return performRequest(query, callback);
    };

    var _created = function (entityName, entityObject, callback, errcallback) {
        var async = !!callback;
        var setName = entityName + 'Set';
        var json = window.JSON.stringify(entityObject);
        var query = serverUrl + ODATA_ENDPOINT + "/" + setName;

        var options = { type: "POST", url: query, data: json };

        return _doRequest(options, async, function (result) {
            if (async)
                callback(result);
            else
                return result;
        }, errcallback);
    };

    var _update = function (entityName, id, entityObject, callback, errcallback) {
        var async = !!callback;
        var setName = entityName + 'Set';
        var json = window.JSON.stringify(entityObject);
        var _id = id;
        var query = serverUrl + ODATA_ENDPOINT + "/" + setName + "(guid'" + _id + "')"

        var options = {
            type: "POST",
            url: query,
            data: json,
            beforeSend: function (request) {

                request.setRequestHeader("Accept", "application/json");
                request.setRequestHeader("X-HTTP-Method", "MERGE");
            }
        };

        return _doRequest(options, async, function () {
            if (async)
                callback(_id);
            else
                return _id;

        }, errcallback);
    };

    var _delete = function (entityName, id, callback, errcallback) {
        var async = !!callback;
        var setName = entityName + 'Set';
        var query = serverUrl + ODATA_ENDPOINT + '/' + setName + "(guid'" + id + "')";

        var options = {
            type: "POST",
            url: query,
            beforeSend: function (request) {
                request.setRequestHeader('Accept', 'application/json');
                request.setRequestHeader('X-HTTP-Method', 'DELETE');
            }
        };

        return _doRequest(options, async, function (result) {
            if (async)
                callback(result);
            else
                return result;
        }, errcallback);
    };

    var _copy = function (sourceEntityObject, fields) {
        var n = {};
        for (var i = 0; i < fields.length; i++) {
            try {
                n[fields[i]] = sourceEntityObject[fields[i]];
            }
            catch (e) {
                // field does not exist.
            }
        }


        return n;
    };

    var _retrieveRelated = function (entityName, guid, relationshipName, callback, errcallback) {
        var async = !!callback;
        var setName = entityName + 'Set';
        var _callback = callback;

        var query = serverUrl + ODATA_ENDPOINT + "/" + setName + "(guid'" + guid + "')/" + relationshipName;

        var performRequest = function (query, fnCallback) {
            var options = { url: query }
            var async = !!fnCallback;

            return _doRequest(options, async, function (data) {
                var next = data.__next || null;
                var results = data.results || data;
                var response = { 'results': results, 'next': next }

                if (next) { // enable edge loading
                    response.LoadNext = function (callback) {
                        return performRequest(next, callback);
                    };
                }

                if (async)
                    fnCallback(response);
                else
                    return response;
            }, errcallback);
        };

        return performRequest(query, callback);
    }

    var _retrieveRelatedWithFilter = function (entityName, guid, relationshipName, filter, callback, errcallback) {
        var async = !!callback;
        var setName = entityName + 'Set';
        var _callback = callback;

        filter = (filter) ? "?$filter=" + filter : '';

        var query = serverUrl + ODATA_ENDPOINT + "/" + setName + "(guid'" + guid + "')/" + relationshipName + filter;

        var performRequest = function (query, fnCallback) {
            var options = { url: query }
            var async = !!fnCallback;

            return _doRequest(options, async, function (data) {
                var next = data.__next || null;
                var results = data.results || data;
                var response = { 'results': results, 'next': next }

                if (next) { // enable edge loading
                    response.LoadNext = function (callback) {
                        return performRequest(next, callback);
                    };
                }

                if (async)
                    fnCallback(response);
                else
                    return response;
            }, errcallback);
        };

        return performRequest(query, callback);
    }
    var _completeRequest = function (entityName, guid, statecode, statuscode, callback, errcallback) {
        var requestMain = ""
        requestMain += "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
        requestMain += "  <s:Body>";
        requestMain += "    <Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
        requestMain += "      <request i:type=\"b:SetStateRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\" xmlns:b=\"http://schemas.microsoft.com/crm/2011/Contracts\">";
        requestMain += "        <a:Parameters xmlns:c=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
        requestMain += "          <a:KeyValuePairOfstringanyType>";
        requestMain += "            <c:key>EntityMoniker</c:key>";
        requestMain += "            <c:value i:type=\"a:EntityReference\">";
        requestMain += "              <a:Id>" + guid + "</a:Id>";
        requestMain += "              <a:LogicalName>" + entityName + "</a:LogicalName>";
        requestMain += "              <a:Name i:nil=\"true\" />";
        requestMain += "            </c:value>";
        requestMain += "          </a:KeyValuePairOfstringanyType>";
        requestMain += "          <a:KeyValuePairOfstringanyType>";
        requestMain += "            <c:key>State</c:key>";
        requestMain += "            <c:value i:type=\"a:OptionSetValue\">";
        requestMain += "              <a:Value>" + statecode + "</a:Value>";
        requestMain += "            </c:value>";
        requestMain += "          </a:KeyValuePairOfstringanyType>";
        requestMain += "          <a:KeyValuePairOfstringanyType>";
        requestMain += "            <c:key>Status</c:key>";
        requestMain += "            <c:value i:type=\"a:OptionSetValue\">";
        requestMain += "              <a:Value>" + statuscode + "</a:Value>";
        requestMain += "            </c:value>";
        requestMain += "          </a:KeyValuePairOfstringanyType>";
        requestMain += "        </a:Parameters>";
        requestMain += "        <a:RequestId i:nil=\"true\" />";
        requestMain += "        <a:RequestName>SetState</a:RequestName>";
        requestMain += "      </request>";
        requestMain += "    </Execute>";
        requestMain += "  </s:Body>";
        requestMain += "</s:Envelope>";
        var req = new XMLHttpRequest();
        req.open("POST", serverUrl + SOAP_ENDPOINT, (callback != null));
        req.setRequestHeader("Accept", "application/xml, text/xml, */*");
        req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");

        if (callback != null)
            req.onreadystatechange = function () { _completeResponse(req, callback, errcallback); };

        req.send(requestMain);
        if (callback == null) return _completeResponse.call(this, req, null, errcallback);
        //        var callback = null;
        //        var errcallback = null;
        //        req.onreadystatechange = function () { _completeResponse(req, callback, errcallback); };
        //        req.send(requestMain);

    };
    var _completeResponse = function (req, callback, errcallback) {
        if (req.readyState == 4) {
            if (req.status == 200) {
                if (callback != null)
                { callback(); }
            }
            else {
                errcallback(_getSOAPError(req.responseXML));
            }
        }

    };

    var _assignRequest = function (entityName, guid, userid, callback, errcallback) {
        var request = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
        request += "<s:Body>";
        request += "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\"";
        request += " xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
        request += "<request i:type=\"b:AssignRequest\"";
        request += " xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\"";
        request += " xmlns:b=\"http://schemas.microsoft.com/crm/2011/Contracts\">";
        request += "<a:Parameters xmlns:c=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<c:key>Target</c:key>";
        request += "<c:value i:type=\"a:EntityReference\">";
        request += "<a:Id>" + guid + "</a:Id>";
        request += "<a:LogicalName>" + entityName + "</a:LogicalName>";
        request += "<a:Name i:nil=\"true\" />";
        request += "</c:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<c:key>Assignee</c:key>";
        request += "<c:value i:type=\"a:EntityReference\">";
        request += "<a:Id>" + userid + "</a:Id>";
        request += "<a:LogicalName>systemuser</a:LogicalName>";
        request += "<a:Name i:nil=\"true\" />";
        request += "</c:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "</a:Parameters>";
        request += "<a:RequestId i:nil=\"true\" />";
        request += "<a:RequestName>Assign</a:RequestName>";
        request += "</request>";
        request += "</Execute>";
        request += "</s:Body>";
        request += "</s:Envelope>";

        var req = new XMLHttpRequest();
        req.open("POST", serverUrl + SOAP_ENDPOINT, (callback != null));
        req.setRequestHeader("Accept", "application/xml, text/xml, */*");
        req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");

        if (callback != null)
            req.onreadystatechange = function () { _assignResponse(req, callback, errcallback); };

        req.send(request);
        if (callback == null) return _assignResponse.call(this, req, null, errcallback);
    };

    var _assignResponse = function (req, callback, errcallback) {
        if (req.readyState == 4) {
            if (req.status == 200) {
                if (callback != null)
                { callback(); }
            }
            else {
                errcallback(_getSOAPError(req.responseXML));
            }
        }
    };

    var _getSOAPError = function (faultXml) {
        var errorMessage = "Unknown Error (Unable to parse the fault)";
        if (typeof faultXml == "object") {
            try {
                var bodyNode = faultXml.firstChild.firstChild;
                //Retrieve the fault node
                for (var i = 0; i < bodyNode.childNodes.length; i++) {
                    var node = bodyNode.childNodes[i];
                    //NOTE: This comparison does not handle the case where the XML namespace changes
                    if ("s:Fault" == node.nodeName) {
                        for (var j = 0; j < node.childNodes.length; j++) {
                            var faultStringNode = node.childNodes[j];
                            if ("faultstring" == faultStringNode.nodeName) {
                                errorMessage = faultStringNode.text;
                                break;
                            }
                        }
                        break;
                    }
                }
            }
            catch (e) { };
        }
        return new Error(errorMessage);
    };

    return {
        GetRecord: _retrieve,
        GetRecords: _retrieveMultiple,
        GetRelatedRecords: _retrieveRelated,
        GetRecordByUrl: _retrieveByUrl,
        CreateRecord: _created,
        UpdateRecord: _update,
        DeleteRecord: _delete,
        CopyRecord: _copy,
        GetRelatedRecordsWithFilter: _retrieveRelatedWithFilter,
        AssignRecord: _assignRequest,
        CompleteRecord: _completeRequest,
        OpenWindow: _openCrmWindow
    };
} ();

function GetQueryStr(ji) {
    hu = window.location.search.substring(1);
    gy = hu.split("&");
    for (i = 0; i < gy.length; i++) {
        ft = gy[i].split("=");
        if (ft[0] == ji) {
            return ft[1];
        }
    }
    return '';
}

function ParseJsonDate(date) {
    if (date) {
        var d = new Date(parseInt(date.replace(/(Date)|[(\/)]/gi, "")));
        return d;
    } else {
        return null;
    }
}

function ParseJsonDateAsText(date) {
    if (date) {
        var d = ParseJsonDate(date);
        return (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getYear();
    } else {
        return null;
    }
}

function UTCtoUserTime(dateObj) {
    var currentUserId = null;
    var uerrorMessage = "Context to retrieve the UserId is not available.";
    if (typeof GetGlobalContext != "undefined")
    { currentUserId = GetGlobalContext().getUserId(); }
    else {
        if (typeof Xrm != "undefined") {
            currentUserId = Xrm.Page.context.getUserId();
        }
        else {
            if (typeof DEV_USERID != "undefined") {
                currentUserId = DEV_USERID;
            } else {
                alert(uerrorMessage);
            }
        }
    }

    var usersettings = Crm.GetRelatedRecords("SystemUser", currentUserId, "user_settings");

    if (usersettings.results.length > 0) {
        var uo = usersettings.results[0];
        if (uo.TimeZoneBias != null) {
            var dVal = dateObj.valueOf();
            var minute = 60 * 1000;
            return new Date(dVal + minute * parseInt(uo.TimeZoneBias));
        }
    }
    return dateObj;
}

function GetToday() {
    var currentUserId = null;
    var uerrorMessage = "Context to retrieve the UserId is not available.";
    if (typeof GetGlobalContext != "undefined")
    { currentUserId = GetGlobalContext().getUserId(); }
    else {
        if (typeof Xrm != "undefined") {
            currentUserId = Xrm.Page.context.getUserId();
        }
        else {
            if (typeof DEV_USERID != "undefined") {
                currentUserId = DEV_USERID;
            } else {
                alert(uerrorMessage);
            }
        }
    }

    var d = new Date();

    d = new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), d.getUTCMilliseconds());

    var usersettings = Crm.GetRelatedRecords("SystemUser", currentUserId, "user_settings");

    if (usersettings.results.length > 0) {
        var uo = usersettings.results[0];
        if (uo.TimeZoneBias != null) {
            var dVal = d.valueOf();
            var minute = 60 * 1000;
            return new Date(dVal - minute * parseInt(uo.TimeZoneBias));
        }
    }
    return d;
}

function GetUserCurrencyId(defaultCurrency) {
    var currentUserId = null;
    var uerrorMessage = "Context to retrieve the UserId is not available.";
    if (typeof GetGlobalContext != "undefined")
    { currentUserId = GetGlobalContext().getUserId(); }
    else {
        if (typeof Xrm != "undefined") {
            currentUserId = Xrm.Page.context.getUserId();
        }
        else {
            if (typeof DEV_USERID != "undefined") {
                currentUserId = DEV_USERID;
            } else {
                alert(uerrorMessage);
            }
        }
    }

    // Get the user settings
    var usersettings = Crm.GetRelatedRecords("SystemUser", currentUserId, "user_settings");
    if (usersettings.results.length > 0) {
        var uo = usersettings.results[0];
        if (uo.TransactionCurrencyId.Id != null) {
            return uo.TransactionCurrencyId;
        } else {
            return GetCurrency(defaultCurrency);
        }
    } else {
        return GetCurrency(defaultCurrency);
    }
    return null;
}

function GetCurrency(CurrencyName) {
    // get the default Currency
    var cc = Crm.GetRecords("TransactionCurrency", ["CurrencyName", "TransactionCurrencyId"], "CurrencyName eq '" + CurrencyName + "'");
    if (cc.results.length > 0) {
        var tc = {
            Id: cc.results[0].TransactionCurrencyId,
            Name: CurrencyName,
            LogicalName: "transactioncurrency"
        };

        return tc;
    }
    return null;
}

function Pause(ms) {
    var dt = new Date();
    while ((new Date()) - dt <= ms) {
    }
}

function CleanNumber(text) {
    return String(text).replace(/[$,]/g, '');
}

function FormatAsCurrency(amount, precision) {
    var i = parseFloat(amount);
    if (isNaN(i)) { i = 0.00; }
    var minus = '';
    if (i < 0) { minus = '-'; }
    i = Math.abs(i);
    i = parseInt((i + .005) * 100);
    i = i / 100;
    s = new String(i);
    if (s.indexOf('.') < 0) { s += '.00'; }
    if (s.indexOf('.') == (s.length - 2)) { s += '0'; }
    s = minus + s;
    return '$' + FormatAsNumber(s, precision);
}

function FormatAsNumber(nStr, precision) {
    nStr += '';
    if (nStr == '')
        return '';

    if (!!precision) {
        try {
            tX = parseFloat(nStr.replace('$', '').replace(',', '').replace(',', '').replace(',', '').replace(',', '').replace(',', ''));
            tX = Math.round(tX * 100) / 100;
            nStr = tX.toFixed(precision).toString();
        }
        catch (e) { }
    }
    x = nStr.split('.');
    x1 = x[0];
    x2 = x.length > 1 ? '.' + x[1] : '';
    var rgx = /(\d+)(\d{3})/;
    while (rgx.test(x1)) {
        x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }

    return x1 + x2;
}

function RunFunction(functionName, args) {
    var tmp = new Function('return ' + functionName + '(' + (args == null ? '' : args) + ')');
    return tmp();
}

function ExportToExcel(jsonData) {

    var oExcel = new ActiveXObject("Excel.Application");
    var oBook = oExcel.Workbooks.Add;
    var oSheet = oBook.Worksheets(1);

    // Get table metadata
    var firstRow = jsonData[0];
    var numCols = firstRow.length;

    // Column headers
    var index = 1; /* Keep track of the column position */
    for (var col in firstRow) {
        if (col != "__metadata") {
            oSheet.Cells(1, index) = col; /* The x-value is 1 because Excel rows start at 1 instead of 0 */
            index++; /* Navigate to next column */
        }
    }

    // Iterate through each row
    for (var i = 0; i < jsonData.length; i++) {
        var rowData = jsonData[i];

        // Iterate through each property of the json object
        index = 1; /* Keep track of the column position */
        for (var j in rowData) {
            if (j != "__metadata") {

                // Check whether the property of the CRM record is a reference to another CRM entity
                if (typeof (rowData[j]) != "object") {
                    oSheet.Cells(i + 2, index) = rowData[j]; /* We use +2 because Excel rows start at 1 and the first row is already populated as the header row */
                }
                else {
                    // If it is, then get the Name if its a lookup, otherwise get the value if its an optionset value
                    for (var k in rowData[j]) {
                        if (k == "Name" || k == "Value") {
                            oSheet.Cells(i + 2, index) = rowData[j][k];
                        }
                    }
                }
                index++;  /* Navigate to next column */
            }
        }
    }

    // Make Excel visible through the Application object.
    oExcel.Visible = true;
    oExcel.UserControl = true;
}

function GetPicklistValue(a, v) {
    // Retrieve Value by Text.
    if (a.AttributeType != 'Picklist' && a.AttributeType != 'Status') return null;

    for (var i_ = 0; i_ < a.OptionSet.Options.length; i_++) {
        if (a.OptionSet.Options[i_].OptionMetadata.Label.UserLocalizedLabel.Label == v)
            return a.OptionSet.Options[i_].OptionMetadata.Value;
    }

    return null;
}

function GetPicklistText(a, v) {
    // Retrieve Text by Value.
    if (a.AttributeType != 'Picklist' && a.AttributeType != 'Status') return null;

    for (var i_ = 0; i_ < a.OptionSet.Options.length; i_++) {
        if (a.OptionSet.Options[i_].OptionMetadata.Value == v)
            return a.OptionSet.Options[i_].OptionMetadata.Label.UserLocalizedLabel.Label;
    }

    return null;
}

function parseXml(xml) {
    if (jQuery.browser.msie) {
        var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.loadXML(xml);
        xml = xmlDoc;
    }
    return xml;
}

function GetUserForLookup(userid) {
    if (userid != null) {
        var o = Crm.GetRecord("SystemUser", userid, ["FullName", "SystemUserId"]);
        var luItem = {
            Id: userid,
            Name: o.FullName,
            DefaultType: "8",
            entityname: "systemuser"
        };

        var lu = new Array();
        lu[0] = luItem;
        return lu;
    }
}

function UserHasRole(roleName) {
    var serverUrl = Xrm.Page.context.getServerUrl();

    try {
        var oDataEndpointUrl = serverUrl + "/XRMServices/2011/OrganizationData.svc/";
        oDataEndpointUrl += "RoleSet?$top=1&$filter=Name eq '" + roleName + "'";

        var service = GetRequestObject();

        if (service != null) {
            service.open("GET", oDataEndpointUrl, false);
            service.setRequestHeader("X-Requested-Width", "XMLHttpRequest");
            service.setRequestHeader("Accept", "application/json, text/javascript, */*");
            service.send(null);
            //alert(service.responseText);

            var requestResults = eval('(' + service.responseText + ')').d;

            if (requestResults != null && requestResults.results.length == 1) {
                var role = requestResults.results[0];

                var id = role.RoleId;

                var currentUserRoles = Xrm.Page.context.getUserRoles();

                for (var i = 0; i < currentUserRoles.length; i++) {
                    var userRole = currentUserRoles[i];

                    if (GuidsAreEqual(userRole, id)) {
                        return true;
                    }
                }
            }
        }
    }
    catch (err) {
        alert(err);
    }

    return false;
}

function GetRequestObject() {
    if (window.XMLHttpRequest) {
        return new window.XMLHttpRequest;
    }
    else {
        try {
            return new ActiveXObject("MSXML2.XMLHTTP.3.0");
        }
        catch (ex) {
            return null;
        }
    }
}

function GuidsAreEqual(guid1, guid2) {
    var isEqual = false;

    if (guid1 == null || guid2 == null) {
        isEqual = false;
    }
    else {
        isEqual = guid1.replace(/[{}]/g, "").toLowerCase() == guid2.replace(/[{}]/g, "").toLowerCase();
    }

    return isEqual;
}

Crm.Date = function () {
    var _ParseJsonDate = function (jsonstring) {
        if (jsonstring) {
            var d = new Date(parseInt(jsonstring.replace(/(Date)|[(\/)]/gi, "")));
            return d;
        } else {
            return null;
        }
    };
    var _LocalDateTimeJson = function (jsonstring) {
        var odate = this.ParseJsonDate(jsonstring);
        return new Date(odate.setMinutes(odate.getMinutes() + odate.getTimezoneOffset() + window.ORG_TIMEZONE_OFFSET));
    };
    var _LocalDateTime = function (odate) {
        return new Date(odate.setMinutes(odate.getMinutes() + odate.getTimezoneOffset() + window.ORG_TIMEZONE_OFFSET));
    };
    var _LocalDateTimeNow = function () {
        var odate = new Date;
        return new Date(odate.setMinutes(odate.getMinutes() + odate.getTimezoneOffset() + window.ORG_TIMEZONE_OFFSET));
    };
    var _LocalDateToday = function () {
        var i_1 = this.LocalDateTimeNow(); return new Date(i_1.getFullYear(), i_1.getMonth(), i_1.getDate());
    };
    var _LocalDateUserString = function (userDateString) {
        var sDate = this.User2Rest(userDateString);
        return (new Date(sDate));
    };
    var _JsonDateToUserDateString = function (jsonstring, includeTime) {
        var dDate = this.LocalDateTimeJson(jsonstring);

        return _FormatAsUserDateString(dDate, includeTime);
    };
    var _UserDateStringToRESTDateString = function (sdate) {
        var bContainsTime = false;
        var bHasAMPM = false;
        var sDateOnly = sdate.valueOf();
        var sTimeOnly = "";
        var sAMPMOnly = "";
        if (sdate.indexOf(" ") > 0) {
            bContainsTime = true;
            var sDateTimeSplit = sdate.split(" ");
            sDateOnly = sDateTimeSplit[0];
            sTimeOnly = sDateTimeSplit[1];
            if (sDateTimeSplit.length >= 3) {
                sAMPMOnly = sDateTimeSplit[2];
            }
        }
        var us_o = this.UserSettings();
        var us_dateFormat = us_o.DateFormatString;
        var us_dateSep = us_o.DateSeparator;
        us_dateFormat = us_dateFormat.replace(/[\/]/gi, us_dateSep);

        var us_timeFormat = us_o.TimeFormatString;
        if (us_timeFormat.indexOf("tt") > 0) {
            bHasAMPM = true;
        }
        var us_timeSep = us_o.TimeSeparator;

        var d_un = us_dateFormat.split(us_dateSep);
        var dayIndex;
        var monthIndex;
        var yearIndex;
        for (var i = 0; i < d_un.length; i++) {
            switch (d_un[i]) {
                case "dd":
                    dayIndex = i;
                    break;
                case "d":
                    dayIndex = i;
                    break;
                case "MM":
                    monthIndex = i;
                    break;
                case "M":
                    monthIndex = i;
                    break;
                case "yyyy":
                    yearIndex = i;
                    break;
                case "yy":
                    yearIndex = i;
                    break;
            }
        }

        var sDateList = sDateOnly.split(us_dateSep);
        var sNewDateTime = sDateList[monthIndex] + "/" + sDateList[dayIndex] + "/" + sDateList[yearIndex];

        if (bContainsTime) {
            var t_un;
            if (bHasAMPM) {
                us_timeFormat = us_timeFormat.split(" ")[0];
            }
            t_un = us_timeFormat.split(us_timeSep);

            var hourIndex = null;
            var bHourLeadingZero = false;
            var bHour24 = false;
            var minuteIndex = null;
            var bMinuteLeadingZero = false;
            for (var j = 0; j < t_un.length; j++) {
                switch (t_un[j]) {
                    case "hh":
                        bHourLeadingZero = true;
                        hourIndex = j;
                        break;
                    case "h":
                        hourIndex = j;
                        break;
                    case "HH":
                        bHourLeadingZero = true;
                        bHour24 = true;
                        hourIndex = j;
                        break;
                    case "H":
                        bHour24 = true;
                        hourIndex = j;
                        break;
                    case "mm":
                        bMinuteLeadingZero = true;
                        minuteIndex = j;
                        break;
                    case "m":
                        minuteIndex = j;
                        break;
                }
            }
            var isPM = false;
            if (bHasAMPM) {
                if (sAMPMOnly.indexOf(us_o.PMDesignator) >= 0) {
                    isPM = true;
                }
                sTimeOnly = sTimeOnly.split(" ")[0];
            }
            var sTimeList = sTimeOnly.split(us_timeSep);
            var hhHour = parseInt(sTimeList[hourIndex]);
            if (bHour24) {
                if (hhHour > 12) {
                    hhHour = hhHour - 12;
                    isPM = true;
                }
            }
            sNewDateTime += " " + hhHour + ":" + sTimeList[minuteIndex] + " " + (isPM ? "PM" : "AM");
        }
        return sNewDateTime;
    };
    var _ConvertToRESTDateString = function (dateObject) {
        var d;
        if (typeof (dateObject) != "object") {
            d = new Date(dateObject);
        } else {
            d = dateObject;
        }
        var p = "AM";
        var s = d.getMonth() + 1 + "/" + d.getDate() + "/" + d.getFullYear() + " ";
        if (d.getHours() == 0) {
            s += "12";
        } else if (d.getHours() > 11) {
            var nH = (d.getHours() - 12);
            if (nH == 0) {
                s += "12";
            } else {
                s += nH;
            }
            p = "PM";
        } else {
            s += d.getHours();
        }
        s += ":" + (d.getMinutes() < 10 ? "0" + d.getMinutes() : d.getMinutes()) + " " + p;

        return s;

    };
    var _FormatAsUserDateString = function (dateObject, includeTime) {
        var dDate = new Date(dateObject.valueOf());
        var us_o = _UserSettings();
        var us_dateFormat = us_o.DateFormatString;
        var us_dateSep = us_o.DateSeparator;
        us_dateFormat = us_dateFormat.replace(/[\/]/gi, us_dateSep);

        var sDate = us_dateFormat + (includeTime ? " " + us_o.TimeFormatString : "");
        if (sDate.match("dd")) {
            if (dDate.getDate() < 10) {
                sDate = sDate.replace("dd", "0" + dDate.getDate().toString());
            } else {
                sDate = sDate.replace("dd", dDate.getDate().toString());
            }
        } else if (sDate.match("d")) {
            sDate = sDate.replace("d", dDate.getDate().toString());
        }

        var s_m = dDate.getMonth() + 1;
        if (sDate.match("MM")) {
            if (s_m < 10) {
                sDate = sDate.replace("MM", "0" + s_m.toString());
            } else {
                sDate = sDate.replace("MM", s_m.toString());
            }
        } else if (sDate.match("M")) {
            sDate = sDate.replace("M", s_m.toString());
        }

        if (sDate.match("yyyy")) {
            sDate = sDate.replace("yyyy", dDate.getFullYear().toString());
        } else if (sDate.match("yy")) {
            sDate = sDate.replace("yy", dDate.getFullYear().toString().substring(2, 2));
        }

        if (sDate.match("H")) {
            if (sDate.match("HH")) {
                if (dDate.getHours() < 10) {
                    sDate = sDate.replace("HH", "0" + dDate.getHours().toString());
                } else {
                    sDate = sDate.replace("HH", dDate.getHours().toString());
                }
            } else if (sDate.match("H")) {
                sDate = sDate.replace("H", dDate.getHours().toString());
            }
        } else {
            var nH;
            var isPM = false;
            if (dDate.getHours() == 0) {
                nH = 12;
            } else if (dDate.getHours() > 11) {
                nH = dDate.getHours() - 12;
                if (nH == 0) {
                    nH = 12;
                }
                isPM = true;
            } else {
                nH = dDate.getHours();
            }
            if (sDate.match("hh")) {
                if (nH < 10) {
                    sDate = sDate.replace("hh", "0" + nH.toString());
                } else {
                    sDate = sDate.replace("hh", nH.toString());
                }
            } else if (sDate.match("h")) {
                sDate = sDate.replace("h", nH.toString());
            }

            if (sDate.match("tt")) {
                sDate = sDate.replace("tt", (isPM ? us_o.PMDesignator : us_o.AMDesignator));
            }
        }

        if (sDate.match("mm")) {
            if (dDate.getMinutes() < 10) {
                sDate = sDate.replace("mm", "0" + dDate.getMinutes().toString());
            } else {
                sDate = sDate.replace("mm", dDate.getMinutes().toString());
            }
        }

        return sDate;
    };
    var _IsDaylightSaving = function (optionalDateObject) {
        var currentUserId = null;
        var uerrorMessage = "Context to retrieve the UserId is not available.";
        if (typeof GetGlobalContext != "undefined")
        { currentUserId = GetGlobalContext().getUserId(); }
        else {
            if (typeof Xrm != "undefined") {
                currentUserId = Xrm.Page.context.getUserId();
            }
            else {
                if (typeof DEV_USERID != "undefined") {
                    currentUserId = DEV_USERID;
                } else {
                    alert(uerrorMessage);
                }
            }
        }

        var usersettings = Crm.GetRelatedRecords("SystemUser", currentUserId, "user_settings");

        if (usersettings.results.length > 0) {
            var uo = usersettings.results[0];
            var dn = (optionalDateObject ? this.LocalDateTime(optionalDateObject) : this.LocalDateTimeNow());
            var dd = new Date(Date.UTC(dn.getUTCFullYear(), uo.TimeZoneDaylightMonth, uo.TimeZoneDaylightDay, uo.TimeZoneDaylightHour, 0, 0, 0));
            var ds = new Date(Date.UTC((uo.TimeZoneDaylightMonth <= uo.TimeZoneStandardMonth ? dn.getUTCFullYear() : dn.getUTCFullYear() + 1), uo.TimeZoneStandardMonth, uo.TimeZoneStandardDay, uo.TimeZoneStandardHour, 0, 0, 0));
            if (dn >= dd && dn < ds) {
                return true;
            } else {
                return false;
            }
        }
    };
    var _UserTimeZoneOffset = function () {
        var currentUserId = null;
        var uerrorMessage = "Context to retrieve the UserId is not available.";
        if (typeof GetGlobalContext != "undefined")
        { currentUserId = GetGlobalContext().getUserId(); }
        else {
            if (typeof Xrm != "undefined") {
                currentUserId = Xrm.Page.context.getUserId();
            }
            else {
                if (typeof DEV_USERID != "undefined") {
                    currentUserId = DEV_USERID;
                } else {
                    alert(uerrorMessage);
                }
            }
        }

        var usersettings = Crm.GetRelatedRecords("SystemUser", currentUserId, "user_settings");

        if (usersettings.results.length > 0) {
            var uo = usersettings.results[0];
            var dn = new Date();
            var dd = new Date(Date.UTC(dn.getUTCFullYear(), uo.TimeZoneDaylightMonth, uo.TimeZoneDaylightDay, uo.TimeZoneDaylightHour, 0, 0, 0));
            var ds = new Date(Date.UTC((uo.TimeZoneDaylightMonth <= uo.TimeZoneStandardMonth ? dn.getUTCFullYear() : dn.getUTCFullYear() + 1), uo.TimeZoneStandardMonth, uo.TimeZoneStandardDay, uo.TimeZoneStandardHour, 0, 0, 0));
            if (dn >= dd && dn < ds) {
                return -(uo.TimeZoneBias + uo.TimeZoneDaylightBias);
            } else {
                return -(uo.TimeZoneBias + uo.TimeZoneStandardBias);
            }
        }
    };
    var _UserDateFormatString = function () {
        var currentUserId = null;
        var uerrorMessage = "Context to retrieve the UserId is not available.";
        if (typeof GetGlobalContext != "undefined")
        { currentUserId = GetGlobalContext().getUserId(); }
        else {
            if (typeof Xrm != "undefined") {
                currentUserId = Xrm.Page.context.getUserId();
            }
            else {
                if (typeof DEV_USERID != "undefined") {
                    currentUserId = DEV_USERID;
                } else {
                    alert(uerrorMessage);
                }
            }
        }

        var usersettings = Crm.GetRelatedRecords("SystemUser", currentUserId, "user_settings");

        if (usersettings.results.length > 0) {
            var uo = usersettings.results[0];
            return (uo.DateFormatString.replace(/[\/]/gi, uo.DateSeparator));
        }
    };
    var _UserTimeFormatString = function () {
        var currentUserId = null;
        var uerrorMessage = "Context to retrieve the UserId is not available.";
        if (typeof GetGlobalContext != "undefined")
        { currentUserId = GetGlobalContext().getUserId(); }
        else {
            if (typeof Xrm != "undefined") {
                currentUserId = Xrm.Page.context.getUserId();
            }
            else {
                if (typeof DEV_USERID != "undefined") {
                    currentUserId = DEV_USERID;
                } else {
                    alert(uerrorMessage);
                }
            }
        }

        var usersettings = Crm.GetRelatedRecords("SystemUser", currentUserId, "user_settings");

        if (usersettings.results.length > 0) {
            var uo = usersettings.results[0];
            return (uo.TimeFormatString.replace(/[\/]/gi, uo.TimeSeparator));
        }
    };
    var _UserPMDesignator = function () {
        var currentUserId = null;
        var uerrorMessage = "Context to retrieve the UserId is not available.";
        if (typeof GetGlobalContext != "undefined")
        { currentUserId = GetGlobalContext().getUserId(); }
        else {
            if (typeof Xrm != "undefined") {
                currentUserId = Xrm.Page.context.getUserId();
            }
            else {
                if (typeof DEV_USERID != "undefined") {
                    currentUserId = DEV_USERID;
                } else {
                    alert(uerrorMessage);
                }
            }
        }

        var usersettings = Crm.GetRelatedRecords("SystemUser", currentUserId, "user_settings");

        if (usersettings.results.length > 0) {
            var uo = usersettings.results[0];
            return uo.PMDesignator;
        }
    };
    var _UserAMDesignator = function () {
        var currentUserId = null;
        var uerrorMessage = "Context to retrieve the UserId is not available.";
        if (typeof GetGlobalContext != "undefined")
        { currentUserId = GetGlobalContext().getUserId(); }
        else {
            if (typeof Xrm != "undefined") {
                currentUserId = Xrm.Page.context.getUserId();
            }
            else {
                if (typeof DEV_USERID != "undefined") {
                    currentUserId = DEV_USERID;
                } else {
                    alert(uerrorMessage);
                }
            }
        }

        var usersettings = Crm.GetRelatedRecords("SystemUser", currentUserId, "user_settings");

        if (usersettings.results.length > 0) {
            var uo = usersettings.results[0];
            return uo.AMDesignator;
        }
    };
    var _UserSettings = function () {
        var currentUserId = null;
        var uerrorMessage = "Context to retrieve the UserId is not available.";
        if (typeof GetGlobalContext != "undefined")
        { currentUserId = GetGlobalContext().getUserId(); }
        else {
            if (typeof Xrm != "undefined") {
                currentUserId = Xrm.Page.context.getUserId();
            }
            else {
                if (typeof DEV_USERID != "undefined") {
                    currentUserId = DEV_USERID;
                } else {
                    alert(uerrorMessage);
                }
            }
        }

        var usersettings = Crm.GetRelatedRecords("SystemUser", currentUserId, "user_settings");

        if (usersettings.results.length > 0) {
            var uo = usersettings.results[0];
            return uo;
        }
    };
    var _getODataUTCDateFilter = function (date) {

        var monthString;
        var rawMonth = date.getUTCMonth().toString();
        if (rawMonth.length == 1) {
            monthString = "0" + rawMonth;
        }
        else
        { monthString = rawMonth; }

        var dateString;
        var rawDate = date.getUTCDate().toString();
        if (rawDate.length == 1) {
            dateString = "0" + rawDate;
        }
        else
        { dateString = rawDate; }


        var DateFilter = "datetime\'";
        DateFilter += date.getUTCFullYear() + "-";
        DateFilter += monthString + "-";
        DateFilter += dateString;
        DateFilter += "T" + date.getUTCHours() + ":";
        DateFilter += date.getUTCMinutes() + ":";
        DateFilter += date.getUTCSeconds() + ":";
        DateFilter += date.getUTCMilliseconds();
        DateFilter += "Z\'";
        return DateFilter;
    };
    var _Rest2User = function (reststring, includeTime) {
        return (_FormatAsUserDateString(new Date(reststring), includeTime));
    };
    var _Json2Rest = function (jsonString) {
        return _ConvertToRESTDateString(this.LocalDateTimeJson(jsonString));
    };
    var _NumberOfWeeksInYear = function (cAS2) {
        var o312_s = ",2004,2009,2015,2020,2026,2032,2037,2043,2048,2054,2060,2065,2071,2076,2082,2088,2093,2099,2105,2111,2116,2122,2128,2133,";
        if (o312_s.match(cAS2.toString())) {
            return 53;
        }
        return 52;
    };
    var _CreateCrmDatePickerOnForm = function (id, fieldname, datevalue, isreadonly) {

        var inputrow = '  <INPUT style="IME-MODE: auto" id="DateInput" tabIndex=1020 class="CrmBaseControl">';

        var html = '<TABLE style="ime-mode: inactive; table-layout: fixed" id=t_' + id + ' class="ms-crm-DateTime" cellSpacing="0" cellPadding="0" width="100%" attrFormat="date" attrPriv="7" attrName="' + fieldname + '" req="0" initialAllowTimeEdit="true" initialAllDayDisplayMode="false" initialDisableInit="false" initialAllowBlankDate="true" initialShowTime="true" format="date" _dtValue="' + datevalue + '">';
        html += '  <colgroup>';
        html += '      <col />';
        html += '      <col width="36" />';
        html += '  </colgroup>';
        html += '  <TBODY>';
        html += '    <TR>';
        html += '    <TD class="DateTimeUI_RenderDateControl_td">';
        html += inputrow;
        html += '      </TD>';

        if (!isreadonly) {
            html += '      <TD>';
            html += '        <IMG id=' + id + 'img class="ms-crm-DateTime ms-crm-ImageStrip-btn_off_cal" alt="Select date" src="/_imgs/btn_off_Cal.gif">';
            html += '      </TD>';
        }
        html += '    </TR>';
        html += '  </TBODY>';
        html += '</TABLE>';

        return html;
    };
    var _GetDateValue = function (id) {
        return $("#t_" + id + " > TBODY > TR > TD[class=DateTimeUI_RenderDateControl_td] > INPUT").val();
    };
    var _SetDateValue = function (id, value) {
        $("#t_" + id + " > TBODY > TR > TD[class=DateTimeUI_RenderDateControl_td] > INPUT").val(value);
    };


    return {
        ParseJsonDate: _ParseJsonDate,
        LocalDateTimeJson: _LocalDateTimeJson,
        LocalDateTimeNow: _LocalDateTimeNow,
        LocalDateTime: _LocalDateTime,
        LocalDateToday: _LocalDateToday,
        LocalDateUserString: _LocalDateUserString,
        IsDaylightSaving: _IsDaylightSaving,
        UserTimeZoneOffset: _UserTimeZoneOffset,
        GetODataUTCDateFilter: _getODataUTCDateFilter,
        UserDateFormatString: _UserDateFormatString,
        UserTimeFormatString: _UserTimeFormatString,
        UserPMDesignator: _UserPMDesignator,
        UserAMDesignator: _UserAMDesignator,
        UserSettings: _UserSettings,
        User2Date: _LocalDateUserString,
        User2Rest: _UserDateStringToRESTDateString,
        Rest2User: _Rest2User,
        Json2User: _JsonDateToUserDateString,
        Json2Rest: _Json2Rest,
        Date2Rest: _ConvertToRESTDateString,
        Date2User: _FormatAsUserDateString,
        Today: _LocalDateToday,
        Now: _LocalDateTimeNow,
        NumberOfWeeksInYear: _NumberOfWeeksInYear,
        CreateCrmDatePickerOnForm: _CreateCrmDatePickerOnForm,
        GetDateValue: _GetDateValue,
        SetDateValue: _SetDateValue
    };
} ();

if (window.ORG_TIMEZONE_OFFSET == null || typeof (window.ORG_TIMEZONE_OFFSET) == "undefined") {
    window.ORG_TIMEZONE_OFFSET = Crm.Date.UserTimeZoneOffset();
}






