define('jls/util/Sxe', [
  'jls/lang/Class',
  'jls/lang/Exception',
  'jls/lang/Logger',
  'jls/util/SxeEnvelope',
  'jls/util/EventBroker'
], function (
  Class,
  Exception,
  Logger,
  SxeEnvelope,
  EventBroker
) {

var Sxe;
Sxe = Class.create( /** @lends jls.util.Sxe.prototype */
{
    /**
     * Creates a Simple XML Exchange.
     * 
     * @param {String} url The URL.
     * @constructs
     * @class This class represents a Simple XML Exchange.
     */
    initialize : function(url) {
        this._url = url;
        this._eventBroker = null;
    },
    getEventBroker : function() {
        if (this._eventBroker == null) {
            return Sxe.DEFAULT_EVENT_BROKER;
        }
        return this._eventBroker;
    },
    setEventBroker : function(eventBroker) {
        this._eventBroker = eventBroker;
    },
    onException : function(e) {
        Logger.getInstance().warn('Uncaught exception during exchange processing "' + e + '"');
        setTimeout(function() {
            throw new Exception('Uncaught exception during exchange processing "' + e + '"', e);
        }, 10);
    },
    /**
     * Sends the SXE request.
     * 
     * @param {jls.util.SxeEnvelope} value The XML value to send.
     * @param {Function} [onComplete] The function to call when a request completes.
     * @param {Function} [onException] The function to call when an exception is raised.
     */
    send : function(value, onComplete, onException) {
        //var charset = 'ISO-8859-1';
        var charset = 'UTF-8';
		var body = value.toString(charset);
        Logger.getInstance().trace('Sxe.send("' + body + '")');
    	var onCompleteWrapper = Class.emptyFunction;
    	if (onComplete) {
    	    var self = this;
    		onCompleteWrapper = function() {
    		    if (this.succeed()) {
    		        Logger.getInstance().trace('Sxe received ->' + this.getResponseText() + '<-');
    		    } else {
                    Logger.getInstance().trace('Sxe failed (' + this.getStatus() + ')');
    		    }
				var response = new Sxe.SxeResponse(this);
				if (typeof onComplete == 'string') {
				    self.getEventBroker().publish(onComplete, response);
				} else {
				    onComplete(response);
				}
            };
    	}
    	new _native.boot.httpRequest(this._url, {
            method :'post',
            contentType :'application/x-www-form-urlencoded', // 'text/plain',
            postBody :body,
            encoding : charset,
            asynchronous :true,
            onException : this.getEventBroker().callback(onException) || this.onException,
            onComplete : onCompleteWrapper,
            context : this
        }).send();
    }
});

Object.extend(Sxe,
{
    /**
     * The default event broker.
     * @type jls.util.EventBroker
     */
    DEFAULT_EVENT_BROKER: EventBroker.DEFAULT
});


Sxe.SxeResponse = Class.create( /** @lends jls.util.Sxe.SxeResponse.prototype */
{
    /**
     * Creates a Simple XML Exchange Response.
     * 
     * @param {Object} httpRequest The HTTP request native object.
     * @constructs
     * @class This class represents a Simple XML Exchange Response.
     */
    initialize : function(httpRequest) {
        this._httpRequest = httpRequest;
    },
    /**
     * Returns the HTTP status.
     * @returns {Number} the HTTP status.
     */
    getStatus : function() {
        return this._httpRequest.getStatus();
    },
    /**
     * Tells wether or not the exchange completes succesfully.
     * @returns {Boolean} true if the exchange completes succesfully.
     */
    succeed : function() {
        var status = this._httpRequest.getStatus();
        if ((status >= 200) && (status < 300) && (this._httpRequest._xhr.responseXML)) {
            return true;
        }
        return false;
    },
    /**
     * Returns the response envelope.
     * @returns {jls.util.SxeEnvelope} the response envelope.
     */
    getEnvelope : function() {
        return SxeEnvelope.createFromDOM(this._httpRequest.getResponseXML());
    }
});

return Sxe;
});
