
function Request(uri, options) {

	var _this  = this;
	var isGet  = false;
	var query  = '';
	var params = {};

	if (typeof options == 'object') {
        if (options.onResponse) {
            this.onResponse = options.onResponse;
        }

        if (options.get) {
            isGet = true;
        }

        if (options.parameters) {
			params = options.parameters;
		}
	}

	this.request = params;

	for (var name in params) {
		var value = params[name];
		if (typeof value == 'object') {
			for (var subName in value) {
				query += (query ? '&' : '') + encodeURIComponent(name) + '=' + encodeURIComponent(value[subName]);
			}
		} else {
			query += (query ? '&' : '') + encodeURIComponent(name) + '=' + encodeURIComponent(value);
		}
	}

	try {
		this.transport = new XMLHttpRequest();
	} catch(e) {
		try {
			this.transport = new ActiveXObject('Microsoft.XMLHTTP');
		} catch(e) {
			return;
		}
	}

	if (isGet) {
		with (this.transport) {
			open('GET', uri + (query.length > 0 ? '?' + query : ''), true);
			send(null);
		}
	} else {
		with (this.transport) {
			open('POST', uri, true);
			try { setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') } catch(e) {};
			send(query);
		}
	}

	function dispatch() {
		if (_this.transport.readyState == 4 && _this.transport.status != 0) {

			clearInterval(_this.timer);

			if (_this.onResponse) {

				var response = {
					text: _this.transport.responseText,
					xml: _this.transport.responseXML,
					js: {}
				}

				if (response.text.substr(0, 1) == '{') {
					try { eval('response.js = ' + response.text) } catch(e) {}
				}

				_this.onResponse(response, _this.request);

				response.js = null;
				response.text = null;
				response.xml = null;
			}

			for (var node in _this) {
				_this[node] = null;
			}

			_this = null;
		}
	}

	this.timer = setInterval(dispatch, 20);
}

