
//= depends: zapi

/**
 * A JSON-P-style class for cross-domain AJAX-ish requests.
 *
 * @name ZAPI.ScriptSrcRequest
 * @constructor
 */
ZAPI.ScriptSrcRequest = Class.create((function() {
	var head = document.getElementsByTagName('head')[0] ||  document.documentElement,
		scriptSrcRequestID = 0;
	return {
		initialize: function(url, options) {
			this.options = $H({
				'removeScript': true,
				'callbackParamName': 'ZCB',
				'callbackName': '__zapi_ssr_' + (scriptSrcRequestID++) + '__',
				'timeout': 10000
			}).merge(options);

			this._script = new Element('script', { type: 'text/javascript', src: url });

			if (Object.isFunction(this.options.get('onSuccess'))) {
				window[this.options.get('callbackName')] = function(json) {
					this._cleanUp();
					this.options.get('onSuccess').call(this, json);
				}.bind(this);
				if (url.indexOf('?') < 0) {
					this._script.src += '?';
				}
				this._script.src += '&' + this.options.get('callbackParamName') + '=' +
					this.options.get('callbackName');
			}

			if (Object.isFunction(this.options.get('onFailure'))) {
				this._timeout = setTimeout(function() {
					this._cleanUp();
					window[this.options.get('callbackName')] = function() {};
					this.options.get('onFailure').call(this);
				}.bind(this), this.options.get('timeout'));
			}

			if (Object.isFunction(this.options.get('onLoad'))) {
				this._script.onload = this._script.onreadystatechange = function() {
					this.options.get('onLoad')();
					this._script.onload = this._script.onreadystatechange = null;
					this._cleanUp();
				}.bind(this);
			}

			head.insertBefore(this._script, head.firstChild);
		},

		_cleanUp: function() {
			if (this.options.get('removeScript')) {
				if (this._timeout) {
					clearTimeout(this._timeout);
					this._timeout = null;
				}
				if (this._script && Object.isElement(this._script)) {
					$(this._script).remove();
					this._script = null;
				}
			}
			window[this.options.get('callbackName')] = undefined;
		}
	};
}()));
