define('jls/util/XMLHttpRequest', ['jls/lang/Class', 'jls/lang/Exception'], function (Class, Exception) {

var XMLHttpRequest;
XMLHttpRequest = Class.create({
    /**
     * Creates an XMLHttpRequest.
     * 
     * @param {String} url The URL.
     * @constructs
     * @class This class allows to perform HTTP requests.
     */
    initialize : function(url) {
        this._url = url;
        this._method = 'get';
        this._contentType = 'application/x-www-form-urlencoded'; // 'text/plain';
        this._user = null;
        this._password = null;
        this._async = true;
        this._headers = null;
    },
    /**
     * Sets the authentication credentials.
     * 
     * @param {String} user The authentication user.
     * @param {String} password The authentication password.
     * @returns {jls.util.XMLHttpRequest} this XMLHttpRequest.
     */
    setAuthentication : function(user, password) {
        this._user = user;
        this._password = password;
        return this;
    },
    /**
     * Sets the HTTP content type.
     * 
     * @param {String} contentType The HTTP content type.
     * @returns {jls.util.XMLHttpRequest} this XMLHttpRequest.
     */
    setContentType : function(contentType) {
        this._contentType = contentType;
        return this;
    },
    /**
     * Sets the HTTP method.
     * 
     * @param {String} method The HTTP method.
     * @returns {jls.util.XMLHttpRequest} this XMLHttpRequest.
     */
    setMethod : function(method) {
        this._method = method;
        return this;
    },
    /**
     * Adjusts this request's asynchronous mode.
     * 
     * @param {Boolean} asynchronous Whether the request is placed in asynchronous mode.
     * @returns {jls.util.XMLHttpRequest} this XMLHttpRequest.
     */
    configureAsynchronous : function(asynchronous) {
        this._async = asynchronous;
        return this;
    },
    /**
     * Appends an header to the list of HTTP header name/value pairs to be used in the request.
     * 
     * @param {String} name The name of the header.
     * @param {String} [value] The value of the header.
     * @returns {jls.util.XMLHttpRequest} this XMLHttpRequest.
     */
    setRequestHeader : function(name, value) {
        if (this._headers == null) {
            this._headers = {};
        }
        if (typeof value == 'undefined') {
            delete this._headers[name];
        } else {
            this._headers[name] = value;
        }
        return this;
    },
    /**
     * Sends the HTTP request.
     * 
     * @param {String} [data] The HTTP body to send.
     * @param {Function} [onComplete] The function to call when the request completes.
     * @param {Function} [onException] The function to call when an exception is thrown.
     */
    send : function(data, onComplete, onException) {
        new _native.boot.httpRequest(this._url, {
            method : this._method,
            contentType : this._contentType,
    	    user : this._user,
    	    password : this._password,
            postBody : data || null,
            asynchronous : this._async,
            onComplete : onComplete || Class.emptyFunction,
            onException : onException || XMLHttpRequest.DEFAULT_ON_EXCEPTION,
            headers : this._headers,
            context : this
        }).send();
    }
});

Object.extend(XMLHttpRequest, /** @lends jls.util.XMLHttpRequest */
{
    DEFAULT_ON_EXCEPTION: function(e) {
        //jls.logger.warn('Uncaught exception during exchange processing "' + e + '"');
        setTimeout(function() {
            throw new Exception('Uncaught exception during request processing (' + e + ')', e);
        }, 10);
    }
});

return XMLHttpRequest;
});
