var CtRequest_Iframe = Class.create({

	iframe: null,
	callback: null,
	ident: null,

	options: {},
	url: null,
	form: null,

	initialize: function(ident, callback) {
		this.url = 'about:blank';
		this.form = null;
		this.options = {};

		this.callback = callback;
		this.ident = ident;
		var iframeName = 'iframe-' + (Math.random() + '').replace('.', '');
		this.iframe = new Element('iframe', {className: 'hidden', name: iframeName, src: this.url});
		$$('body')[0].appendChild(this.iframe);
	},

	send: function() {
		if (this.url == 'about:blank' && this.form == null) {
			throw "CtRequest error: cannot send request without URL or FORM";
		}

		if (this.url != 'about:blank' && this.form != null) {
			throw "CtRequest error: both URL and FORM are set. Specify either URL or FORM";
		}

		Event.observe(this.iframe, 'load', this._responseHandler.bindAsEventListener(this));

		if (this.url != 'about:blank') {
			this.iframe.src = this.url;
		} else {
			this.form.writeAttribute('target', this.iframe.readAttribute('name'));
			this.form.submit();
		}

		return true;
	},

	_responseHandler: function(event) {
		Event.stop(event);
//		if (this.firstRun) {
//			this.firstRun = false;
//			return;
//		}
//		if (this.iframe.src == 'about:blank')

		var json = false;
		var content = {}; content[this.ident] = {json: null, content: null};
		var raw = this.iframe.contentWindow.document.body.innerHTML;
		var blocks = this.iframe.contentWindow.document.body.getElementsByTagName('div');
		if (raw.length == 0) {
			return;
		}
//e(raw);
//e(this.iframe.src);
//e(blocks);
//e(blocks); return;
		if (blocks) {

			for (var i = 0; i < blocks.length; i++) {
				var block = $(blocks[i]);
				var ident = Element.readAttribute(block, 'title');
				//e(ident);
				if (ident == '_json') {
					try {
						json = block.innerHTML.evalJSON();
						json.redirectPath = (json.redirect_path) ? json.redirect_path.unescapeHTML() : '/';
						content[this.ident].json = json;
					} catch (e) {
						break;
					}
					continue;
				}

				if (ident == '_content') {
					content[this.ident].content = block.innerHTML.unescapeHTML();
					continue;
				}

				if (!content[ident]) {
					content[ident] = {json: null, content: null};
				}
				switch (block.className) {
					case 'content':
						if (content[ident].content) {
							content[ident].content += block.innerHTML.unescapeHTML();
						} else {
							content[ident].content = block.innerHTML.unescapeHTML();
						}
						break;
					case 'json':
						try {
							json = block.innerHTML.evalJSON();
						} catch (e) {
							json = {};
						}
//console.log(this.ident, ident, content[ident].json);

						content[ident].json = Object.extend(content[ident].json ? content[ident].json : {}, json ? json : {});

						break;
					default:
						break;
				}
			}

		}
//e(blocks.length, json);
		if (!blocks || json === false) {
			content =  {'error': {json: null, content: raw}};
			content[this.ident] = false;
		}

		this.iframe.stopObserving('load');
		this.iframe.src = 'about:blank';
		this.iframe.remove();
		this.iframe = null;

		this.callback(content);
	}

});


var CtRequest_Ajax = Class.create({

	callback: null,
	ident: null,

	options: {},
	url: null,
	form: null,

	initialize: function(ident, callback) {
		this.callback = callback;
		this.ident = ident;
		this.url = '';
		this.options = {};
		this.form = null;
	},


	send: function() {

		if (this.url == '' && this.form == null) {
			throw "CtRequest error: cannot send request without URL or FORM";
		}

		if (this.options.parameters && this.form != null) {
			throw "CtRequest error: both OPTION PARAMETERS and FORM are set. Specify either OPTION PARAMETERS or FORM";
		}

		if (this.form) {
			this.options.parameters = Form.serialize(this.form);
			this.url = this.form.readAttribute('action');
		}

		this.options.onSuccess = this._successHandler.bind(this);
		this.options.onFailure = this._failureHandler.bind(this);
		new Ajax.Request(this.url, this.options);

		return true;
	},



	_failureHandler: function() {
		raw = 'Error. Check your internet connection';
		content =  {'error': {json: null, content: raw}};
		content[this.ident] = false;

		this.callback(content);
	},


	_successHandler: function(transport, json) {
		var content = {};
		if (json) {
			content[this.ident] = {json: json, content: transport.responseText};
	 	} else {
			content =  {'error': {json: null, content: raw}};
			content[this.ident] = false;
	 	}

		this.callback(content);
	}


});



var CtRequest_Manager = Class.create({

	adapters: {},


	initialize: function() {
		this.adapters = {};
	},


	get: function(ident, requestType) {

		var adapter = null;
		switch (requestType) {
			case 'ajax':
				adapter = new CtRequest_Ajax(ident, this._responseHandler.bind(this));
				break;

			case 'iframe':
				adapter = new CtRequest_Iframe(ident, this._responseHandler.bind(this));
				break;

			default:
				throw 'Request type for component ' + ident + ' is not defined';
				break;
		}

		this.adapters[ident] = adapter;

		return adapter;
	},


	send: function(ident) {
		var result = this.adapters[ident].send();
	},



	_responseHandler: function(content) {
		Object.keys(content).each(function(ident) {
//e(ident);
//e(ident, content[ident], CtPage.getComponent(ident));
			var component = CtPage.getComponent(ident);
			if (component === null) {
				component = new CtComponent_Default(ident);
				CtPage.addComponent(component);
			}
			component.refresh(content[ident]);
		}.bind(this));
	}




});

CtPage.registerScript("CtRequest");
