Object.extend(Ajax,{
	getTransport: function(transport)
	{
		return Try.these(
			function() {return new transport();},
			function() {return new XMLHttpRequest();},
			function() {return new ActiveXObject('Msxml2.XMLHTTP');},
			function() {return new ActiveXObject('Microsoft.XMLHTTP');}
		) || false;
	},
	activeRequestCount: 0
});

Object.extend(Ajax.Base.prototype,{
	setOptions: function(options) {
		this.options = {
			method:       'post',
			asynchronous: true,
			contentType:  'application/x-www-form-urlencoded',
			parameters:   '',
			transport: null,
			checkString: '',
			timeoutSeconds: 20,
			jsonParamName: null
		}
		Object.extend(this.options, options || {});
		
		this.options.method = this.options.method.toLowerCase();
		if (typeof this.options.parameters == 'string')
			this.options.parameters = this.options.parameters.toQueryParams();
	}
});

Object.extend(Ajax.Request.prototype, {
	initialize: function(url, options) {
		this.setOptions(options);
		this.transport = Ajax.getTransport(this.options.transport);
		this.request(url);
	},
	request: function(url) {
		this.url = url;
		this.method = this.options.method;
		var params = this.options.parameters;

		if (!['get', 'post'].include(this.method)) {
			// simulate other verbs over post
			params['_method'] = this.method;
			this.method = 'post';
		}

		params = Hash.toQueryString(params);
		if (params && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_='

		// when GET, append parameters to URL
		if (this.method == 'get' && params)
			this.url += (this.url.indexOf('?') > -1 ? '&' : '?') + params;

		try {
			Ajax.Responders.dispatch('onCreate', this, this.transport);

			try{ this.transport.open(this.options.method, this.url, this.options.asynchronous,this.options.username,this.options.password,this.options); }
			catch(err){ this.transport.open(this.options.method, this.url,this.options.asynchronous); }

			if (this.options.asynchronous) {
				this.transport.onreadystatechange = this.onStateChange.bind(this);
				setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
			}

			this.setRequestHeaders();

			var body = this.method == 'post' ? (this.options.postBody || params) : null;
			this.transport.send(body);
			
			/* Force Firefox to handle ready state 4 for synchronous requests */
			if (!this.options.asynchronous && this.transport.overrideMimeType)
				this.onStateChange();

		} catch (e) {
			this.dispatchException(e);
		}
	},
	evalJSON: function() {
		if(this.transport.json){ return this.transport.json; }
		else
		{
			try {
				return eval('(' + this.header('X-JSON') + ')');
			} catch (e) {}
		}
	}
});

if (typeof(com) == 'undefined') {
	var com = {};
}

if (typeof(com.espn) == 'undefined') {
	com.espn = {};
}

if (typeof(com.espn.io) == 'undefined') {
	com.espn.io = {};
}

com.espn.io.ScriptSrcTransport = Class.create();

com.espn.io.ScriptSrcTransport.prototype = {
	initialize: function()
	{
		if(!document.scriptRequests){ document.scriptRequests = $H({}); }
		this.requestId = 'id' + document.scriptRequests.keys().length;
		this.readyState = 1;
		this.status = null;
		this.checkTimer = null;
		this.timeoutTimer = null;
	},
	_changeState: function(status,readyState)
	{
		this.readyState = readyState;
		this.status = status;
		this.onreadystatechange();
	},
	onreadystatechange: function(){},
	open: function(method,url,asynch,username,password,options)
	{
		options = options || {};
		this.options = options;
		var jsonParamName = options.jsonParamName;
		var sep;

		if(jsonParamName)
		{
			sep = (/\?/.test(url)) ? '&' : '?';
			url += sep + jsonParamName + '=document.scriptRequests.' + this.requestId + '.doSuccess';
		}

		this.scriptTag = document.createElement('script');
		this.scriptTag.setAttribute('type','text/javascript');
		this.scriptTag.setAttribute('src',url);
	},
	abort: function()
	{
		if(this.scriptTag.parentNode)
		{
			Element.remove(this.scriptTag);
			this.scriptTag = null;
		}
		clearInterval(this.checkTimer);
		clearTimeout(this.timeoutTimer);
	},
	send: function()
	{
		var checkString = this.options.checkString;
		var timeout = this.options.timeoutSeconds;
		var loadScript = (checkString) ? (typeof(eval(checkString)) == 'undefined') : true;

		if(timeout)
		{
			timeout *= 1000;
			this.timeoutTimer = setTimeout(function(){this.doError();}.bind(this),timeout);
		}

		if(checkString)
		{
			this.checkTimer = setInterval(function()
			{
				if(typeof(eval(checkString)) != 'undefined')
				{
					this.doSuccess();
				}
			}.bind(this),100);
		}

		document.scriptRequests[this.requestId] = this;

		if(loadScript)
		{
			try{ document.getElementsByTagName('head')[0].appendChild(this.scriptTag); } catch(err){}
		}
	},
	doSuccess: function(jsonObject)
	{
		clearInterval(this.checkTimer);
		clearTimeout(this.timeoutTimer);
		this.json = jsonObject;
		this._changeState(200,4);
		document.scriptRequests[this.requestId] = null;
	},
	doError: function()
	{
		clearInterval(this.checkTimer);
		clearTimeout(this.timeoutTimer);
		this._changeState(404,4);
		document.scriptRequests[this.requestId] = null;
	},
	setRequestHeader: function(){},
	getAllResponseHeaders: function(){ return []; },
	getResponseHeader: function(){ return null; }
};