
	if (!IntersonForm) {
		var IntersonForm = function (sId, aErrors) {
			this.sId = sId;
			this.rows = [];
			this.input = [];
			this.errors = aErrors;
			this.state = {};

			$(document).ready(ref(this, this.initialize));
		};

		IntersonForm.prototype.initialize = function () {
			this.oForm = $('#' + this.sId);

			if (!this.oForm.length)
				return;

			var row = this.oForm.find('.form_row');
			for (var k = 0; k < row.length; k ++) {
				var r = {
					"input": {}
				};

				row[k] = $(row[k]);

				var input = row[k].find('.form_input');
				var is_error = false;

				for (var jk = 0; jk < input.length; jk ++) {
					input[jk] = $(input[jk]);
					var st = input[jk].hasClass('checkform-groupstatus') ? input[jk].parent().parent().find('.form_status') : input[jk].find('.form_status');

					var i = {
						"status": st.length ? $(st[0]) : null,
						"row": row[k],
						"input": input[jk],
						"form": this,
						"controlChecking": false,
						"controlCheckingTimeout": null
					};

					var control = i['control'] = this.getControl(input[jk]);

					if (!control) {
						if (this.errors[name])
							alert(this.errors[name]);

						continue;
					}

					var name = i['name'] = control.attr('name').replace('[]', '');

					var ctrl = IntersonForm.getControls(input[jk]);
					for (var l = 0; l < ctrl.length; l ++) {
						ctrl[l].blur(ref(i, this.controlChange));
						ctrl[l].change(ref(i, this.controlChangeDelay));
						ctrl[l].keyup(ref(i, this.controlChangeDelay));
					}

					r.input[name] = i;
					this.input[name] = i;

					this.state[name] = 1;

					if (this.errors[name] != undefined) {
						is_error = true;
						if (i.status && this.errors[name]) {
							i.status.html('<img src="' + JS_HOST + 'view/img/icon_error.png" class="mid" /> <span class="mid">' + this.errors[name] + '</span>');
							i.status.addClass('form_error_status');
						} else if (this.errors[name] && $('#error-space-' + this.sId).length > 0) {
							var d = $('<div class="error"></div>');
							d.html(this.errors[name]);
							$('#error-space-' + this.sId).append(d);
						} else {
							this.state[name] = this.errors[name] ? 0 : 1;
						}

						input[jk].parent().addClass('form_error');
					} else if (i.status) {
						i.status.hide();
					}
				}

				if (is_error) {
					row[k].addClass('form_error');
				}
			}

			for (k in this.errors) {
				if (!this.state[k]) {
					alert(this.errors[k]);
				}
			}
		};

		IntersonForm.prototype.getControl = function (node) {
			var input = node.find('input');
			if (input.length > 0 && !$(input[0]).hasClass('skip-autoform'))
				return $(input[0]);

			input = node.find('textarea');
			if (input.length > 0 && !$(input[0]).hasClass('skip-autoform'))
				return $(input[0]);

			input = node.find('select');
			if (input.length > 0 && !$(input[0]).hasClass('skip-autoform'))
				return $(input[0]);

			return null;
		};

		IntersonForm.getControls = function (node, named) {
			var res = named ? {"item": {}, "length": 0} : [];

			var input = node.find('input');
			for (var i = 0; i < input.length; i ++) {
				input[i] = $(input[i]);

				if (named) {
					res.item[input[i].attr('name')] = input[i];
					res.length ++;
				} else
					res.push(input[i]);
			}

			input = node.find('textarea');
			for (i = 0; i < input.length; i ++) {
				input[i] = $(input[i]);

				if (named) {
					res.item[input[i].attr('name')] = input[i];
					res.length ++;
				} else
					res.push(input[i]);
			}

			input = node.find('select');
			for (i = 0; i < input.length; i ++) {
				input[i] = $(input[i]);

				if (named) {
					res.item[input[i].attr('name')] = input[i];
					res.length ++;
				} else
					res.push(input[i]);
			}

			return res;
		};

		IntersonForm.prototype.controlChangeDelay = function () {
			clearInterval(this.controlCheckingTimeout);
			this.controlCheckingTimeout = setTimeout(ref(this, this.form.controlChange), 1000);
		};

		IntersonForm.prototype.controlChange = function () {
			return false;
			
			if (!this.controlChecking) {
				clearInterval(this.controlCheckingTimeout);

				this.controlChecking = true;

				try {
					var sUrl = this.form.oForm.attr('action');
					sUrl = sUrl.replace(/\/[^\/]+\/(\?(.*))?$/, '/checkfield/?$2');
					sUrl += '&field=' + this.name;

					$.post(sUrl, IntersonForm.getFormData(this.form.oForm), ref(this, function (data) {
						try {
							try {
								if (data) {
									if (data.is_null) {
										this.input.parent().addClass('form_error');

										if (data.errstr != "") {
											this.status.html('<img src="' + JS_HOST + 'view/img/icon_error.png" class="mid" /> ' +  data.errstr);
											this.status.show();
										}

										this.status.addClass('form_error_status');
									} else {
										this.input.parent().removeClass('form_error');
//										this.status.removeClass('form_error_status');

										//this.status.html('<img src="' + JS_HOST + 'view/img/icon_ok.png" class="mid" /> ' + (this.status.nodeName.toLowerCase() == 'div' ? 'OK' : ''));
										this.status.hide();
									}
								}
							} catch (e) {
								debug(e);
							}
						} finally {
							this.controlChecking = false;
						}
					}), 'json');
				} catch (e) {
					debug(e);
					this.controlChecking = false;
				}
			}
		};

		IntersonForm.getFormData = function (form) {
			res = {};

			var ip = form.find('input');
			for (k = 0; k < ip.length; k ++) {
				ip[k] = $(ip[k]);

				if (ip[k].attr('name') != null && !ip[k].hasClass('skip-partial')) {
					if (ip[k].attr('type') == 'radio' || ip[k].attr('type') == 'checkbox') {
						if (!ip[k].attr('checked')) {
							continue;
						}
					}

					if (ip[k].attr('name') == 'partial')
						continue;

						res[ip[k].attr('name')] = ip[k].attr('value');
				}
			}

			var t = form.find('textarea');
			for (l = 0; l < t.length; l ++) {
				t[l] = $(t[l]);

				if (t[l].attr('name') != null) {
					res[t[l].attr('name')] = t[l].attr('value');
				}
			}

			t = form.find('select');
			for (l = 0; l < t.length; l ++) {
				t[l] = $(t[l]);

				if (t[l].attr('name') != null) {
					res[t[l].attr('name')] = t[l].attr('value');
				}
			}

			return res;
		};
	}

