////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Provides access to the CRM REST end-point allowing access to data creation, update and delete utilities.
// Refer to the CRM 2011 SDK for the original code and more details on the REST end-point.
// Requires
// Requires Jquery 1.4.1 or later. Now includes JSON 2 - see below, as well as the 3 x Retrieve Settings functions from Exordia.
// If used in a standalone page (as opposed to a CRM form), the host HTML page must have a reference to ClientGlobalContext.js.aspx.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

var serverUrl = parent.Xrm.Page.context.getClientUrl();
var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc";

function createRecord(entityObject, odataSetName, successCallback, passThruObject, debug, errorCallback) {
    //entityObject is required
    if (!entityObject) {
        alert("entityObject is required.");
        return;
    }
    if (!odataSetName) {
        alert("odataSetName is required.");
        return;
    }
    //Parse the entity object into JSON
    // var jsonEntity = window.JSON.stringify(entityObject); // PM - Consider JQuery ParseJSON - reduces need for json2
    var thisUrl = serverUrl + ODATA_ENDPOINT + "/" + odataSetName
    if (debug) {
        alert(thisUrl)
    }
    var jsonEntity = window.JSON.stringify(entityObject);
    $.ajax({ // Create the record
        type: "POST",
        contentType: "application/json; charset=utf-8",
        datatype: "json",
        url: thisUrl,
        data: jsonEntity,
        beforeSend: function (XMLHttpRequest) {
            XMLHttpRequest.setRequestHeader("Accept", "application/json"); // Ensure JSON comes back
        },
        success: function (data, textStatus, XmlHttpRequest) {
            if (successCallback) {
                successCallback(data.d, passThruObject, textStatus, XmlHttpRequest);
            }
        },
        error: function (XmlHttpRequest, textStatus, errorThrown) {
            if (errorCallback) errorCallback(XmlHttpRequest, textStatus, errorThrown, passThruObject, entityObject);
            else errorHandler(XmlHttpRequest, textStatus, errorThrown, passThruObject, entityObject);
        }
    });
}

function updateRecord(id, entityObject, odataSetName, successCallback, debug, errorCallback) {
    if (!id) {
        alert("record id is required.");
        return;
    }
    if (!odataSetName) {
        alert("odataSetName is required.");
        return;
    }
    var jsonEntity = window.JSON.stringify(entityObject); // PN: Consider using Jquery methods
    $.ajax({ // Update Single CRM Record
        type: "POST",
        contentType: "application/json; charset=utf-8",
        datatype: "json",
        data: jsonEntity,
        url: serverUrl + ODATA_ENDPOINT + "/" + odataSetName + "(guid'" + id + "')",
        beforeSend: function (XMLHttpRequest) {
            XMLHttpRequest.setRequestHeader("Accept", "application/json"); // Ensure Results will be JSON
            //Specify the HTTP method MERGE to update just the changes you are submitting.
            XMLHttpRequest.setRequestHeader("X-HTTP-Method", "MERGE");
        },
        success: function (data, textStatus, XmlHttpRequest) {
            //The MERGE does not return any data at all, so we'll add the id
            //onto the data object so it can be leveraged in a Callback. When data
            //is used in the callback function, the field will be named generically, "id"
            data = new Object();
            data.id = id;
            if (successCallback) {
                successCallback(data, textStatus, XmlHttpRequest);
            }
        },
        error: function (XmlHttpRequest, textStatus, errorThrown) {
            if (errorCallback) errorCallback(XmlHttpRequest, textStatus, errorThrown);
            else errorHandler(XmlHttpRequest, textStatus, errorThrown);
        }
    });
}

function deleteRecord(id, odataSetName, successCallback, debug, errorCallback) {
    if (!id) {
        alert("record id is required.");
        return;
    }
    if (!odataSetName) {
        alert("odataSetName is required.");
        return;
    }
    $.ajax({ // Delete a CRM Record
        type: "POST",
        contentType: "application/json; charset=utf-8",
        datatype: "json",
        url: serverUrl + ODATA_ENDPOINT + "/" + odataSetName + "(guid'" + id + "')",
        beforeSend: function (XMLHttpRequest) {
            XMLHttpRequest.setRequestHeader("Accept", "application/json"); // Ensure results in JSON
            //Specify the HTTP method DELETE to perform a delete operation.
            XMLHttpRequest.setRequestHeader("X-HTTP-Method", "DELETE");
        },
        success: function (data, textStatus, XmlHttpRequest) {
            if (successCallback) {
                successCallback(data.d, textStatus, XmlHttpRequest);
            }
        },
        error: function (XmlHttpRequest, textStatus, errorThrown) {
            if (errorCallback) errorCallback(XmlHttpRequest, textStatus, errorThrown);
            else errorHandler(XmlHttpRequest, textStatus, errorThrown);
        }
    });
}

function errorHandler(xmlHttpRequest, textStatus, errorThrow, passThruObject, entityObject) {
    var jsonPassThruObject = window.JSON.stringify(passThruObject);
    var jsonentityObject = window.JSON.stringify(entityObject);
    alert("Client360: Problem updating or creating record > " + xmlHttpRequest.statusText + "\n\nError Response Text:\n\n" + xmlHttpRequest.responseText + "\n\nControl Object:\n\n" + jsonPassThruObject + "\n\nRecord Object:\n\n" + jsonentityObject);
}