/**
 * Class that contains everything needed to make a request
 * This includes:
 *    The url were calling
 *    If were calling a remote method, the class and method name
 *    The payload, unserialized
 *    The timeout for async calls
 *    The callback method
 *    Optional event handlers: onError, Load, Send
 *    A serializer instance
 *
 * @category    HTML
 * @package    AJAX
 * @author    Joshua Eichorn <josh@bluga.net>
 * @copyright    2005 Joshua Eichorn
 * @license    http://www.opensource.org/licenses/lgpl-license.php  LGPL
 *
 * See Main.js for author/license details
 */
function HTML_AJAX_Request(serializer) {
    this.serializer = serializer;
}
HTML_AJAX_Request.prototype = {

    // Instance of a serializer
    serializer: null,

    // Is this an async request
    isAsync: false,

    // HTTP verb
    requestType: 'POST',

    // The actual URL the request is sent to
    requestUrl: '',

    // Remote Class
    className: null,

    // Remote Method
    methodName: null,

    // Timeout in milliseconds for requests
    timeout: 20000,

    // unserialized data, for rpc calls use add args, to send raw data just set this directly
    args: null,

    // async callback method
    callback: null,

    // Queue to push this request too
    queue: 'default',

    // default priority
    priority: 0,

    // a hash of headers to add to add to this request
    customHeaders: {'X-Requested-With': 'XMLHttpRequest', 'X-Ajax-Engine': 'HTML_AJAX/@package_version@'},

    // true if this request will be sent using iframes
    iframe: false,

    // is this a grab request? if so we need to proxy for iframes
    grab: false,

    // true if this request should expect a multipart response
    multipart: false,

    // remote callback
    phpCallback: false,

    /**
     * Add an argument for the remote method
     * @param string argument name
     * @param mixed value
     * @return void
     * @throws Error code 1004
     */
    addArg: function(name, value) 
    {
        if ( !this.args ) {
            this.args = [];
        }
        if (!/[^a-zA-Z_0-9]/.test(name) ) {
            this.args[name] = value;
        } else {
            throw new Error('Invalid parameter name ('+name+')');
        }
    },

    /**
     * Get the payload in a serialized manner
     */
    getSerializedPayload: function() {
        return this.serializer.serialize(this.args);
    },

    /**
     * Get the content type
     */
    getContentType: function() {
        return this.serializer.contentType;
    },

    /**
     * Get the complete url, adding in any needed get params for rpc
     */
    completeUrl: function() {
        if (this.className || this.methodName) {
            this.addGet('c', this.className);
            this.addGet('m', this.methodName);
        }
        if (this.phpCallback) {
            if (HTML_AJAX_Util.getType(this.phpCallback) == 'array') {
                this.phpCallback = this.phpCallback.join('.');
            }
            this.addGet('cb', this.phpCallback);
        }
        if (this.multipart) {
            this.addGet('multipart', '1');
        }
        return this.requestUrl;
    },

    /**
     * Compare to another request by priority
     */
    compareTo: function(other) {
        if (this.priority == other.priority) {
            return 0;
        }
        return (this.priority > other.priority ? 1 : -1);
    },

    /**
     * Add a GET argument
     */
    addGet: function(name, value) {
        var url = new String(this.requestUrl);
        url += (url.indexOf('?') < 0 ? '?' : '&') + escape(name) + '=' + escape(value);
        this.requestUrl = url;
    }
}
