/**
 * MCD HTTP Class
 * 
 * @namespace mcd
 * @author  Michael Girouard (mikeg@mcdpartners.com)
 * 
 * Derived from Panda-JS library (http://panda-js.googlecode.com)
 */
mcd.http = (function() {
	var http;
	var config = {};
	var createRequestInstance = function () {
        if (window.XMLHttpRequest) {
            return function () {
                return new XMLHttpRequest;
            }
        }
        else if (window.ActiveXObject) {
        	return function () {
				var xhr, axo, ex, objects;

				objects = ['Microsoft', 'Msxml2', 'Msxml3'];

				for (var i = 0; i < objects.length; i++) {
					axo = objects[i] + '.XMLHTTP';
					
					try {
						xhr = new ActiveXObject(axo);
						return xhr;
					}
					catch (ex) {};
				}
        	};

            throw 'Unable to create XHR object.';
		}
		else {
			throw "XMLHttp is not supported.";
		}
	}();
	
	/**
	 * Configure the request
	 * 
	 * @param {object} config The parameters to use
	 * @private
	 */
	var prepareConfig = function (config) {
		if (!config.uri) {
			throw "A request URI must be specified."
		}
		
		config.data		= config.data || '';
		config.method	= config.method || 'GET';
		config.type		= config.type || 'text';
		config.headers	= config.headers || {};

		if (typeof config.async === 'undefined') {
			config.async = true;
		}
		else if (config.async === 'true') {
			config.async = true;
		}
		else {
			config.async = false;
		}

		config.data = http.buildQueryString(config.data);
		
		if (config.method === 'GET') {
			config.uri += '?' + config.data
		}
		else if (config.method === 'POST') {
			config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
			config.headers['Content-length'] = config.data.length;
		}
		if (!config.onreadystatechange) {
			config.onreadystatechange = function() { return true; };
		}

		
		return config;
	};
	
	return http = {
		/**
		 * Create a delimited query string from data
		 * 
		 * @param {Object} data The data to parse
		 * @param {String} delimiter Optional delimiter to use
		 */
		'buildQueryString' : function(data, delimiter) {
			var name;
			var queryString = [];
			
			delimiter = delimiter || '&';
			
			for (name in data) {
				queryString.push(name + '=' + data[name]);
			}
			
			return queryString.join(delimiter);
		},
		
		/**
		 * Parses a delimited query string from data
		 * 
		 * @param {String} data The data to parse
		 * @param {String} delimiter Optional delimiter to use
		 */
		'readQueryString' : function(data, delimiter) {
			var dataObject = {};
			var splitData;
			
			delimiter = delimiter || '&';
			
			data = data.split(delimiter);
			
			if (data[0].match(/^\?/)) {
				data[0] = data[0].replace(/^\?/, '');
			}
			
			for (var i = 0; i < data.length; i++) {
				splitData = data[i].split('=');
				dataObject[splitData[0]] = splitData[1];
			}
			
			return dataObject;
		},
		
		/**
		 * Create an instance of the request for use
		 * 
		 * @param {Object} config A configuration object
		 */
		'request' : function(config) {
			var requestInstance = createRequestInstance();
			var config = prepareConfig(config);
			
			requestInstance.open(config.method, config.uri, config.async);
			requestInstance.onreadystatechange = config.onreadystatechange;
			for (var header in config.headers) {
				requestInstance.setRequestHeader(header, config.headers[header]);
			}
			
			return requestInstance;
		},
		
		/**
		 * Executes the request
		 * 
		 * @param {Object} requestInstance A request instance to execute
		 * @param {String} data Additional data to pass
		 */
		'send' : function (requestInstance, data) {
			requestInstance.send(data);
			
			return requestInstance;
		}
	}
})();