var ctFormConfig = {

	responseStatus: null // null / DOM ID / false

};


var CtForm = Class.create(CtComponent_Abstract, {

	element: null,
	wrapper: null,
	form: null,

	config: {},
	id: null,
	status: null,

	returnTrigger: null,

	isProcessing: true,

	formLocker: null,

	_processingStartDelegates: [],
	_processingFinishDelegates: [],


	refresh: function(response) {
		var json = response.json;
		var content = response.content;
		var redirect = (this.returnTrigger && $F(this.returnTrigger)) ? true : false;
		if (redirect && !json.redirectPath) {
			 json.messages.push(['"redirectPath" is not set', 0]);
		}

		var hasErrorMessages = (json && json.messages && this.status && this.status.hasErrors(json.messages));
		if (json && json.redirectPath && redirect && !json.hasErrors && !hasErrorMessages) {
			document.location.href = json.redirectPath;
			return;
		}

		this.waitStatus = true;
		this.element.observe('CtComponent:refresh', function(event) {
			if (event.memo.sender == this.status) {
				this.waitStatus = false;
				this.element.stopObserving('CtComponent:refresh');
			}
		}.bindAsEventListener(this));

		if (json && json.messages && this.status) {
			this.status.show(json.messages);
		}

		if (content) {
			if (this.status && this.status.element) {
				this.element.insert({after: this.status.element});
				this.element.update(content);
				this.element.insert({top: this.status.element});
			} else {
				this.element.update(content);
			}

			this.form = this.element.down('form');
			if (this.form) {
				this.reassembly();
			}
		}

		this.processingFinish(response);
	},




	reassembly: function() {
		this.element = $(this.element.identify());
		this.returnTrigger = this.element.down('.ctForm-return');

		this.addSubmit(this.element.down('.ctForm-submit'));
		this.addReset(this.element.down('.ctForm-reset'));

		Event.observe(this.form, 'submit', this.submitHandler.bindAsEventListener(this));

		CtPage.scriptIsReady("CtSuperSelect", function() {
			CtSuperSelect_Factory.refresh(this.element);
		}.bind(this));

		CtPage.scriptIsReady("CtFileExpert", function() {
			CtFileExpert_Factory.refresh(this.element);
		}.bind(this));

		CtPage.scriptIsReady("CtUpload", function() {
			CtUpload_Factory.refresh(this.element);
		}.bind(this));

		CtPage.scriptIsReady("CtTag", function() {
			CtTag_Factory.refresh(this.element);
		}.bind(this));

		CtPage.scriptIsReady("CtGoogleMap", function() {
			CtGoogleMap_Factory.refresh(this.element);
		}.bind(this));

		CtPage.scriptIsReady("CtGoogleSearchImage", function() {
			CtGoogleSearchImage_Factory.refresh(this.element);
		}.bind(this));

		CtPage.scriptIsReady("CtSuggest", function() {
			CtSuggest_Factory.refresh(this.element);
		}.bind(this));
	},

	addSubmit: function(htmlElement) {
		var buttonSubmit = $(htmlElement);
		if (buttonSubmit) {
			Event.observe(buttonSubmit, 'click', this.submitHandler.bindAsEventListener(this));
		}
	},

	addReset: function(htmlElement) {
		var buttonReset = $(htmlElement);
		if (buttonReset) {
			Event.observe(buttonReset, 'click', this.resetHandler.bindAsEventListener(this));
		}
	},



	initialize: function(htmlElement) {
		this.element = $(htmlElement);

		this.form = this.element.down('form');
		if (this.form) {
			this.id = this.form.identify();
		} else {
			this.id = this.element.identify();
		}


		this.config = Object.extend(ctFormConfig, (ctFormConfig[this.id]) ? ctFormConfig[this.id] : {});

		if (this.config.responseStatus !== false) {
			this.status = new CtComponent_Message();
			this.element.insert({top: this.status.element});
		} else {
			this.status = null;
		}


		if (this.form) {
			this.reassembly();
		}

		this.isProcessing = false;

		this.formLocker = new CtComponent_FormLocker(this);
	},


	addProcessingStartCallback: function(callback) {
		this._processingStartDelegates.push(callback);
	},


	addProcessingFinishCallback: function(callback) {
		this._processingFinishDelegates.push(callback);
	},


	processingStart: function() {
		this.onProcessingStart();
//		this.isProcessing = true;
//		this.form.disable();
//		this.formLocker.show();
	},


	processingFinish: function(response) {
//		this.isProcessing = false;
//		if (this.form) {
//			this.form.enable();
//		}
//		this.formLocker.hide();
		this.onProcessingFinish(response);

		if (this.waitStatus) {
			this.element.stopObserving('CtComponent:refresh');
			this.element.observe('CtComponent:refresh', function(event) {
				if (event.memo.sender == this.status) {
					this.waitStatus = false;
					this.element.stopObserving('CtComponent:refresh');
					this.fireRefresh();
				}
			}.bindAsEventListener(this));
		} else {
			this.fireRefresh();
		}
	},


	fireRefresh: function() {
		this.element.fire('CtComponent:refresh', {sender: this});
	},


	onProcessingStart: function() {
		for (var i = 0; i < this._processingStartDelegates.length; i++) {
			this._processingStartDelegates[i]();
		}
 	},


	onProcessingFinish: function(response) {
		for (var i = 0; i < this._processingFinishDelegates.length; i++) {
			this._processingFinishDelegates[i](response);
		}
 	},


	resetHandler: function(event) {
		Event.stop(event);
		this.form.reset();
	},


	submitHandler: function(event) {
		Event.stop(event);

		this.submit();
	},

	submit: function() {
		if (this.isProcessing) {
			return;
		}

		var request = CtPage.getRequest(this.id, 'iframe');
		request.form = this.form;
		request.send();
		this.processingStart();
	}

});


var CtForm_Normal = Class.create(CtComponent_Abstract, {

	element: null,
	wrapper: null,
	form: null,

	config: {},
	id: null,

	isProcessing: true,


	refresh: function(response) {
		var content = response.content;

		if (content) {

			var children = this.wrapper.immediateDescendants();
			for (var i = 0; i < children.length; i++) {
				children[i].remove();
			}

			this.wrapper.update(content);
			this.form = this.element.down('form');

			this.reassembly();
		}

//		this.processingFinish();
	},

	reassembly: function() {
		var buttonSubmit = this.element.down('.ctForm-submit');
		if (buttonSubmit) {
			Event.observe(buttonSubmit, 'click', this.submitHandler.bindAsEventListener(this));
		}

		var buttonReset = this.element.down('.ctForm-reset');
		if (buttonReset) {
			Event.observe(buttonReset, 'click', this.resetHandler.bindAsEventListener(this));
		}

		Event.observe(this.form, 'submit', this.submitHandler.bindAsEventListener(this));
	},

	initialize: function(htmlElement) {
		this.element = $(htmlElement);

		this.form = this.element.down('form');
		if (this.form) {
			this.id = this.form.identify();
		} else {
			this.id = this.element.identify();
		}

		this.config = Object.extend(ctFormConfig, (ctFormConfig[this.id]) ? ctFormConfig[this.id] : {});

		// избавляемся от враппера
		/*
		this.wrapper = new Element('div', {className: 'ctForm-wrapper'});

		var children = this.element.childElements();
		for (var i = 0; i < children.length; i++) {
			this.wrapper.appendChild(children[i]);
		}
		this.element.appendChild(this.wrapper);
		*/
		if (this.form) {
			this.reassembly();
		}

		this.isProcessing = false;
	},


//	processingStart: function() {
//		this.isProcessing = true;
//		this.form.disable();
//	},
//
//
//	processingFinish: function() {
//		this.isProcessing = false;
//		this.form.enable();
//	},


	resetHandler: function(event) {
		Event.stop(event);
		this.form.reset();
	},


	submitHandler: function(event) {
		Event.stop(event);

		if (this.isProcessing) {
			return;
		}

		this.form.submit();

//		this.processingStart();
	}

});


var CtForm_Factory = new (Class.create({
	initialize: function() {
	},

	refresh: function(htmlElement) {
		var elements = [];
		if (htmlElement) {
			elements = $(htmlElement).select('div.ctForm');
		} else {
			elements = $$('div.ctForm');
		}
		var i;
		for (i = 0; i < elements.length; i++) {
			elements[i].removeClassName('ctForm');
			var form = new CtForm(elements[i]);
			CtPage.addComponent(form);
		}

		if (htmlElement) {
			elements = $(htmlElement).select('div.ctForm_Normal');
		} else {
			elements = $$('div.ctForm_Normal');
		}

		for (i = 0; i < elements.length; i++) {
			elements[i].removeClassName('ctForm_Normal');
			CtPage.addComponent(new CtForm_Normal(elements[i]));
		}
	}
}));

var CtForm_Autoloader = new (Class.create({
	initialize: function() {
		document.observe('dom:loaded', function() { CtForm_Factory.refresh(); });
	}
}));

var CtForm_Textarea = Class.create(CtComponent_Abstract, {

	initialize: function(htmlElement) {
		this.element = $(htmlElement);
		if (this.element && this.element.identify) {
			this.id = this.element.identify();
		} else {
			this.id = null;
		}
	},

	refresh: function(response) {
		if (this.element) {
			this.element.value = response.content;
		}
	}

});


CtPage.registerScript("CtForm");
