function FormManager() {

}

FormManager.init = function ($settings) {
	$.ajaxSetup({cache: false});

	this.url = '';
	this.fieldMask = '#PREFIX#[#ID#][#FIELD#]';

	this.noErrorsHTML = ''
	this.checkTimeout = 1000;
	this.pendingChecks = {};

	this.fields = {};
	this.forms = {};
	this.fieldWatermarks = {};

	$.extend(this, $settings);
}

FormManager.resetFields = function ($prefix) {
	this.fields[$prefix] = new Array ();
}

FormManager.registerForm = function ($settings) {
	var $defaults = {
		url: false,
		prefix: 'u',
		enabled: true,
		enabledTimer: null,
		thank_you_template: '',
		save_event: '',
		id: 0,
		form_id: '',
		before_close: '',
		onValidationFailure: '',
		immediate_validate: true
	}
	this.forms[$settings.prefix] = {};
	$.extend(this.forms[$settings.prefix], $defaults, $settings);

	// when form is registred, then all it's fields should also be registred
	var $me = this;

	if ($me.immediate_validate) {
		$( $.makeArray(this.fields[$settings.prefix]) ).each(
			function() {
				var $blur_field = $me.blurField($settings.prefix, $settings.id, this);

				$blur_field
				.blur(
					function ($e) {
						$me.checkField(this);
					}
				);
			}
		);
	}
}

FormManager.blurField = function ($prefix, $id, $field) {
	var $id = $prefix + '[' + $id + '][' + $field + ']';

	if (($prefix == 'p.new') && ($field == 'Images')) {
		// uploader field needs special approach
		$id += '[tmp_names]';
	}

	return $('#' + jq($id));
}

FormManager.registerField = function ($prefix, $field, $watermark) {
	// fields are registered before form -> store them in separate array
	if (!this.fields[$prefix]) {
		this.fields[$prefix] = new Array ();
	}

	if ($watermark === undefined) {
		$watermark = '';
	}

	this.fieldWatermarks[$prefix + '_' + $field] = $watermark;

	this.fields[$prefix].push($field);
}

FormManager.getURL = function ($prefix, $template, $event, $params) {
	// var $url = this.forms[$prefix].url ? this.forms[$prefix].url : this.url;
	var $url = this.url;

	if ($template === undefined) {
		$template = '';
	}
	$url = $url.replace('#TEMPLATE#', $template);

	if ($event !== undefined) {
		$url += ($url.indexOf('?') == -1 ? '?' : '&') + 'events[' + $prefix + ']=' + $event;
	}

	if (typeof($params) == 'object') {
		for (key in $params) {
			$url += ($url.indexOf('?') == -1 ? '?' : '&') + key + '=' + $params[key];
		}
	}

	return $url;
}

FormManager.getField = function ($prefix, $field, $prepend, $append) {
	if ($prepend === undefined) {
		$prepend = '';
	}

	if ($append === undefined) {
		$append = '';
	}

	var $control_id = this.fieldMask.replace('#PREFIX#', $prefix).replace('#ID#', this.forms[$prefix].id).replace('#FIELD#', $field);

	return document.getElementById($prepend + $control_id + $append);
}

FormManager.openForm = function ($prefix, $template, $width, $height, $source_form, $params) {
	var $url = this.getURL($prefix, $template, undefined, $params);

	$url += ($url.indexOf('?') == -1 ? '?' : '&') + 'width=' + $width + '&height=' + $height + '&modal=true';
	$url = $url.replace('/blog/index.php', '/index.php');

	var $tb_settings = {url: $url};

	if ($source_form !== undefined) {
		$tb_settings.postParams = $($source_form).serialize();
	}
	TB.show($tb_settings);
}

FormManager.closeForm = function ($prefix, $data, $add_params) {
	if ($.isFunction(this.forms[$prefix].before_close)) {
		var $result = this.forms[$prefix].before_close.call(this, $data, $add_params);

		if ($result === false) {
			return;
		}
	}
}

FormManager._getFormFields = function ($prefix) {
	var $fields = this.fields[$prefix];
	if (typeof($fields) == 'undefined') {
		$fields = [];
	}

	for (var $i = 0; $i < $fields.length; $i++) {
		if ($fields[$i] == 'SimplePassword') {
			continue;
		}

		var $control = this.getField($prefix, $fields[$i]);
		var $watermark = this.fieldWatermarks[$prefix + '_' + $fields[$i]];

		if ($control && $watermark !== undefined && $control.value == $watermark) {
			$control.value = '';
		}
	}

	var form = document.getElementById(this.forms[$prefix].form_id);
	var $form_fields = $(form).serialize();

	for (var $i = 0; $i < $fields.length; $i++) {
		if ($fields[$i] == 'SimplePassword') {
			continue;
		}

		var $control = this.getField($prefix, $fields[$i]);
		var $watermark = this.fieldWatermarks[$prefix + '_' + $fields[$i]];

		if ($control && $watermark !== undefined && !$control.value) {
			$control.value = $watermark;
		}
	}

	return $form_fields;
}

FormManager.enableForm = function ($prefix, $enabled) {
	if ($enabled === undefined) {
		$enabled = true;
	}

	if ($enabled) {
		clearTimeout(this.forms[$prefix].enabledTimer);
		this.forms[$prefix].enabledTimer = null;
	}
	else {
		var $me = this;

		// set timer for 10 seconds to enable form back (just in case if ajax responce fails)
		this.forms[$prefix].enabledTimer = setTimeout(
			function () {
//				alert('enabling for for [' + $prefix + '] in setTimeout');
				$me.enableForm($prefix, true);
			}
			, 10000
		);
	}

	this.forms[$prefix].enabled = $enabled;
}

FormManager.submitForm = function ($prefix, $add_params) {
	if (!this.forms[$prefix].enabled) {
//		alert('duplicate submits of [' + $prefix + '] form are forbidden');
		return ;
	}

	if (!this.immediate_validate) {

	}

	// disable form
	this.enableForm($prefix, false);

	var $me = this;
	$.post(
		this.getURL($prefix, '', this.forms[$prefix].save_event).replace('/blog/index.php', '/index.php'),
		this._getFormFields($prefix),
		function ($data) {
			var $match_redirect = new RegExp('^#redirect#(.*)').exec($data);

			if ($match_redirect != null) {
				// redirect to external template requested
				window.location.href = $match_redirect[1];
				return ;
			}
			$me.processResponse($prefix, eval('(' + $data + ')'), $add_params);
		}
	)
}

FormManager.processResponse = function ($prefix, $data, $add_params) {
	// enable form back
//	alert('enabling for for [' + $prefix + '] in processResponse');
	// alert(' $data ' + $data);
	$add_params ? ($add_params.response = $data) : ($add_params = {response : $data});
	if ($data.status == 'OK') {
		var $next_template = false;

		if ($data.next_template && $data.next_template != '') {
			$next_template = $data.next_template;
		}
		else if (this.forms[$prefix].thank_you_template && this.forms[$prefix].thank_you_template != '') {
			$next_template = this.forms[$prefix].thank_you_template;
		}

		if ($next_template || $data.do_refresh) {
			if ($.isFunction(this.forms[$prefix].before_close)) {
				this.forms[$prefix].before_close.call(this, $data, $add_params);
			}

			if ($next_template) {
				// load another template instead of current form
				$('#TB_ajaxContent').html('').load( this.getURL($prefix, $next_template, undefined, $data.params) );
			}
			else if ($data.do_refresh) {
				// refresh whole form
				window.location.href = window.location.href;
			}
		}
		else {
			// close form without refreshing the page
			this.closeForm($prefix, $data, $add_params);
		}
	} else {
		// clear errors from all from fields
		var $fields = this.fields[$prefix];
		if (typeof($fields) == 'undefined') {
			$fields = [];
		}

		for (var $i = 0; $i < $fields.length; $i++) {
			this.setStatus($prefix, $fields[$i]);
		}

		// set new errors
		for ($field in $data.field_errors) {
			this.setStatus($prefix, $field, $data.field_errors[$field]);
		}

		if ($.isFunction(this.forms[$prefix].onValidationFailure)) {
			this.forms[$prefix].onValidationFailure.call(this, $data, $add_params);
		}
	}

	$form_manager = this;
	setTimeout(function () { $form_manager.enableForm($prefix, true); }, 1000);
}

FormManager.Redirect = function ($prefix, url)
{
	$('#TB_ajaxContent').html('').load(url);
	$form_manager = this;
	setTimeout(function () { $form_manager.enableForm($prefix, true); }, 1000);		
}

FormManager.setStatus = function ($prefix, $field_name, $error_msg) {
	var field_cell = this.getField($prefix, $field_name, undefined, '_field_cell');
	var status_cell = this.getField($prefix, $field_name, undefined, '_status_cell');

	if (!field_cell) {
		// alert('Error Field "' + $field_name + '" Missing.');
		//return ;
	}

	if ($error_msg === undefined || !$error_msg) {
		// show OK
		$(field_cell).parents('tr:first').removeClass('error').addClass('ok');

		$(status_cell).removeClass('error-msg').html(this.noErrorsHTML);
	}
	else {
		// show error message
		$(field_cell).parents('tr:first').removeClass('ok').addClass('error');

		$(status_cell).addClass('error-msg').html($error_msg);

		if ($field_name == 'Captcha') {
			var original_src = $('img:first', field_cell).attr('original_src');
			$('img:first', field_cell).attr('src',	original_src + '&_=' + Number(new Date()) );
		}
	}
}

FormManager.checkField = function ($input, delayed) {
	/*if ($.trim($input.value) == '') {
		// skip fields with empty values
		return ;
	}*/

	if (delayed === undefined) {
		delayed = false;
	}

	if (!$input.id.match(/^(.*?)\[.*?\]\[(.*?)\].*?$/)) {
		return ;
	}

	var $prefix = RegExp.$1;
	var $field = RegExp.$2;

	if (this.pendingChecks[$field]) {
		clearTimeout(this.pendingChecks[$field]);
		delete this.pendingChecks[$field];
	}

	var $me = this;

	this.pendingChecks[$field] = setTimeout(
		function () {
			var form = document.getElementById($me.forms[$prefix].form_id);

			$.post(
				$me.getURL($prefix, undefined, 'OnValidateField') + '&field=' + encodeURIComponent($field) + '&' + $input.name + '=' + encodeURIComponent($input.value),
				$(form).serialize(),
				function ($data) {
					$data = eval('(' + $data + ')');
					$me.setStatus($prefix, $field, $data.status == 'OK' ? undefined : $data.status);
				}
			);
		},
		(delayed ? this.checkTimeout : 0)
	);
}
