Element.implement({
	enableButtons: function() {
		var inputs = this.getElements("input");
		var buttons = inputs.filter(function (item, index) {
			var buttonType = item.getProperty("type");
			return buttonType == "button" || buttonType == "submit" || buttonType == "reset";
		});
		buttons.each(function (item, index) {
			item.disabled = false;
		});
	},
	disableButtons: function() {
		var inputs = this.getElements("input");
		var buttons = inputs.filter(function (item, index) {
			var buttonType = item.getProperty("type");
			return buttonType == "button" || buttonType == "submit" || buttonType == "reset";
		});
		buttons.each(function (item, index) {
			item.disabled = true;
		});
	},
	ajaxJSON: function(options) {
		if (this.tagName.toLowerCase() != "form") {
			alert("This class only applies to form tag.");
			return;
		}
		if (!this.getProperty("action")) {
			alert("This class requires the form tag has an action property.");
			return;
		}
		var enctype = this.getProperty("enctype");
		if (enctype && enctype.toLowerCase() == "multipart/form-data") {
			return new iFrameFormRequest(this, options);
		} else {
			return new FormRequestJSON(this, options);
		}
	}
});

var FormRequestJSON = new Class({

	Implements: Options,

	options: {
		onRequest: function(form) {
			return true;
		},
		onComplete: function(responseJSON, responseText) {},
		onFailure: function() {
			errorMessage("发生网络传输错误，请重试");
		}
	},

	initialize: function(formElement, options) {
		this.formElement = formElement;
		this.action = formElement.getProperty("action");
		if (!this.action) {
			errorMessage("Form 必须指定 action 属性。")
		}
		this.setOptions(options);
		this.loading = false;
		this.formElement.addEvent('submit', function(event) {
			new Event(event).stop();
			this.formElement.disableButtons();
			var valid = this.options.onRequest.run(this.formElement);
			if (!valid) {
				this.formElement.enableButtons();
				return;
			}
			var params = Form.serialize(this.formElement);
			new Request.JSON({
				url: this.action,
				method : 'post',
				data : params,
				onSuccess : function(responseJSON, responseText) {
					this.formElement.enableButtons();
					this.options.onComplete.run(responseJSON, responseText);
				}.bind(this),
				onFailure : function (xhr) {
					this.formElement.enableButtons();
					this.options.onFailure.run(xhr);
				}.bind(this)
			}).send();
		}.bind(this));
	}
});

var iFrameFormRequest = new Class({

	Implements: Options,

	options: {
		onRequest: $empty,
		onComplete: function(data) {},
		onFailure: $empty
	},

	initialize: function(formElmt, options) {
		this.formElement = formElmt;
		this.setOptions(options);
		this.frameId = 'f' + Math.floor(Math.random() * 99999);
		this.formElement.set('target', this.frameId);
		this.loading = false;
		this.formElement.addEvent('submit', function(event) {
			this.formElement.disableButtons();
			this.loading = this.options.onRequest();
			if (!this.loading) {
				new Event(event).stop();
				this.formElement.enableButtons();
			}
		}.bind(this));

		this.iframe = new IFrame({
			name: this.frameId,
			styles: {
				display: 'none'
			},
			src: 'about:blank',
			events: {
				load: function(self) {
					if (self.loading) {
						var doc = document.getElementById(self.frameId).contentWindow.document;
						if (doc) {
							if (doc.location.href == 'about:blank') {
								self.options.onFailure();
							}
							if ($type(self.options.onComplete) == 'function') {
								var body = $(doc.body);
								self.options.onComplete(body.get('html'));
							}
						} else {
							self.options.onFailure();
						}
						self.loading = false;
						self.formElement.enableButtons();
					}
				}.pass(this)
			}
		}).inject($(document.body), 'top');
	},

	toElement: function() {
		return this.iframe;
	}

});

var iFrameFormRequestJSON = new Class({

	Implements: Options,

	options: {
		onRequest: $empty,
		onComplete: function(data) {},
		onFailure: $empty
	},

	initialize: function(formElmt, options) {
		this.formElement = formElmt;
		this.setOptions(options);
		this.frameId = 'f' + Math.floor(Math.random() * 99999);
		this.formElement.set('target', this.frameId);
		this.loading = false;
		this.formElement.addEvent('submit', function(event) {
			this.formElement.disableButtons();
			this.loading = this.options.onRequest();
			if (!this.loading) {
				new Event(event).stop();
				this.formElement.enableButtons();
			}
		}.bind(this));

		this.iframe = new IFrame({
			name: this.frameId,
			styles: {
				display: 'none'
			},
			src: 'about:blank',
			events: {
				load: function(self) {
					if (self.loading) {
						var doc = document.getElementById(self.frameId).contentWindow.document;
						if (doc) {
							if (doc.location.href == 'about:blank') {
								self.options.onFailure();
							}
							if ($type(self.options.onComplete) == 'function') {
								var body = $(doc.body);
								self.options.onComplete(JSON.decode(body.get('text')));
							}
						} else {
							self.options.onFailure();
						}
						self.loading = false;
						self.formElement.enableButtons();
					}
				}.pass(this)
			}
		}).inject($(document.body), 'top');
	},

	toElement: function() {
		return this.iframe;
	}

});

