var FormValidator = Class.create({

	messages: {
		error: 'Некоторые поля не заполнены или заполнены с ошибками!',
		err_error: 'Поле заполнено с ошибками!',
		err_required: 'Обязательное поле для заполнения!',
		err_rules: 'Вы не согласились с нашими правилами!',
		err_numeric: 'Значение должно быть числом!',
		err_email: 'Неправильно указан e-mail адрес!',
		err_confirm: 'Значение не совпадает с повтором!'
		},

	initialize: function(form, opts, mess)
	{
		this.options = Object.extend({
			add_validators: null,
			callback_ShowError: null,
			error_div: null
			}, opts || {});

		this.errors = [];

		this.form = $(form);
		this.form.observe('submit', this.on_submit.bind(this));
	
		var fx = this.on_change.bind(this);

		this.form.getElements().each(function(el)
			{
				$(el).observe('blur', fx);
			});
	},

	on_submit: function(ev)
	{
		if ( ! this.Validate())
			ev.stop();
	},

	on_change: function(ev)
	{
		this.ValidateInput(ev.element());
	},

	ShowError: function(err)
	{
		if (this.options.callback_ShowError)
			this.options.callback_ShowError(this, err);
		else if (this.options.error_div)
			this.options.error_div.update(err);
		else
			alert(err);
	},
	
	Validate: function()
	{
		var q = this;

		this.errors = [];

		this.form.getElements().each(function(el)
			{
				var rc = q.ValidateInput(el);
				if (rc !== true)
				{
					q.errors.push(rc);
				}
			});

		if (this.errors.length)
		{
			var form_error = '';

			if (this.errors[0] == 'err_rules')
				form_error = this.errors[0];
			else
				form_error = 'error';

			this.ShowError( this.messages[form_error] || form_error );

			return false;
		}
		else if (this.options.add_validators)
		{
			for( var i = 0, l = this.options.add_validators.length, rc; i < l; i++ )
			{
				if ( !this.options.add_validators[i](this) )
					return false;
			}
		}

		return true;
	},

	ValidateInput: function(input)
	{
		var rc = true;
		input = $(input);

		if ( ! input.disabled)
		{
			var value = input.getValue();
			if (value == null) value = '';

			if (typeof value == 'object')
				value = value.join('');

			value_stripped = value.strip();

			var classes = input.classNames().grep(/^fv_/);

			if (classes.indexOf('fv_required') > 0)
			{
				classes = classes.without('fv_required').unshift('fv_required');
			}

			for( var i = 0, l = classes.length, clss, rc2; i < l; i++ )
			{
				clss = classes[i].replace(/^fv_/, '');
				if (
					this.validators[clss]
					&&
					((rc2 = this.DoValidate(clss, input, value_stripped)) !== true)
					)
				{
					rc = rc2 === false ? (
						clss ? 'err_'+clss : 'error'
						) : rc2;
					break;
				}
			}
		}

		this.SetError(input, rc === true ? '' : rc);

		return rc;
	},

	DoValidate: function(name, input, value)
	{
		return this.validators[name](this, input, value);
	},

	SetError: function(input, error)
	{
		var label = input.id ? this.form.down( 'label[for='+input.id+']' ) : null;
		var info = input.id ? this.form.down( '#'+input.id+'-verifymess' ) : null;

		if (error)
		{
			input.addClassName('error');
			if (label) label.addClassName('error');
		}
		else
		{
			input.removeClassName('error');
			if (label) label.removeClassName('error');
		}
	
		if (info)
		{
			if (error && error != 'error')
				info.update( this.messages[error] || error ).show();
			else
				info.update('').hide();
		}

	},

	validators:
	{

		required: function(fv, input, value)
		{
			return (value != '');
		},

		rules: function(fv, input, value)
		{
			return (value != '');
		},

		numeric: function(fv, input, value)
		{
			return value == '' || /^[+-]?\d+([\.,]\d{1,2})?$/.test(value);
		},

		email: function(fv, input, value)
		{
			return value == '' || /^[\w_\-]+(\.[\w_\-]+)*@([\w_\-]+\.)+[a-zA-Z]{2,6}$/.test(value);
		},

		confirm: function(fv, input, value)
		{
			var original = fv.form[ input.name.replace(/[_\-]*confirm[_\-]*/, '') ];
			return !(original && original.value != '' && input.value != original.value);
		}

	}


}); // FormValidator

var CoolTabs = Class.create();

CoolTabs.prototype = {

initialize: function(pel, opt)
{
	if ( ! (pel && (pel = $(pel)))) return;

	this.opt = opt || {
		onClick: null,
		onObserve: null
		};

	this.tabs = [];
	var obj = this;

	pel.select('input[type=checkbox]', 'input[type=radio]').each(function(el)
		{
			var label = pel.select('label[for='+el.id+']').first();
			if (label)
			{
//				el.hide();
				el.setStyle({
					'position':'absolute',
					'left':'-1000em'
					});
				obj.tabs.push([el, label]);
				el.observe('click', obj.onClick.bind(obj, obj.tabs.length - 1));
				if (obj.opt.onObserve) obj.opt.onObserve(label);
			}
		});

	this.onClick(-1);
},

onClick: function(j)
{
	if (j >= 0)
	{
		var el = this.tabs[j][0];
		var label = this.tabs[j][1];
	
//		el.checked = ! el.checked;
	}

	for( var i = 0, l = this.tabs.length; i < l; i++ )
	{
		var ch;

		if (this.tabs[i][0].type == 'checkbox')
		{
			ch = this.tabs[i][0].checked;
//			if (j == i) ch = ! ch;
		}
		else if (this.tabs[i][0].type == 'radio')
		{
			ch = true;
		}

		if (ch)
			this.tabs[i][1].addClassName('checked');
		else
			this.tabs[i][1].removeClassName('checked');

		if (this.opt.onClick) this.opt.onClick(this.tabs[i][1], ch);
	}
}

}; // CoolTabs

var CoolMenu = Class.create();

CoolMenu.prototype = {

initialize: function(pel, opt)
{
	if ( ! (pel && (pel = $(pel)))) return;

	// find parent ul
	this.parent = pel.nodeName == 'UL' ? pel : pel.down('ul');
	if ( ! this.parent) return;

	this.opt = opt || {
		onObserve: null
		};

	this.last = null;
	this.tm = null;


	var obj = this;
	var fn_prepare = function(el, is_child)
		{
			el.observe('mouseover', obj.onMouseOver.bind(obj, el));
			el.observe('mouseout', obj.onMouseOut.bind(obj, el, !is_child));
			if (obj.opt.onObserve) obj.opt.onObserve(el, is_child);
		};

	this.parent.childElements().each(function(el)
		{
			fn_prepare(el, false);
//			el.select('li').each(function(el2){fn_prepare(el2, true)});
		});


	Event.observe(window, 'resize', this.fix_position.bind(this));

	this.fix_position();
},

fix_position: function()
{
	var par_offset = $(this.parent.parentNode).cumulativeOffset();
	var max_right = par_offset[0] + $(this.parent.parentNode).getWidth();

	this.parent.select('ul').each(function(ul)
		{
			var w = 0;
			var block_off = ul.getStyle('display') != 'block';
			var ps = ul.getStyle('position');
			var lft = ul.getStyle('left');
			var tp = ul.getStyle('top');
			if (block_off) ul.setStyle({
						position: 'absolute',
						left: '-10000em',
						top: '-10000em',
						display: 'block'
						});
			ul.childElements().each(function(li)
				{
					w += li.getWidth();
				});
			if (block_off) ul.setStyle({
						position: ps,
						left: lft,
						top: tp,
						display: ''
						});
//			ul.setStyle({ width: w + 1 +'px' });

			var ul_offset = $(ul.parentNode).cumulativeOffset();
			var ul_pos = max_right - w;

			if (ul_offset[0]+w > max_right || ul_offset[0] > ul_pos)
			{
				if (ul_pos < par_offset[0]) ul_pos = par_offset[0];
				
				ul.setStyle({ left: (
					ul_offset[0] == ul_pos ? '0' :  ( '-'+(ul_offset[0] - ul_pos)+'px' )
					) });
			}
		});
},


onMouseOver: function(el)
{
	this.clearTimeout();

	this.parent.addClassName('hover');

	el.addClassName('hover');
},

onMouseOut: function(el, timeout)
{
	if ( ! timeout)
		return this.removeHover(el, false);

	var tm = 300;

	if (el.hasClassName('current') || el.hasClassName('current-in'))
		return this.removeHover(el, true);

	var fx = function()
		{
			this.removeHover(this.last, true);
			this.tm = null;
			this.last = null;
		};

	this.tm = setTimeout( fx.bindAsEventListener(this), tm );
	this.last = el;
},

clearTimeout: function(remove_active)
{
	if (this.tm)
	{
		clearTimeout(this.tm);
		this.tm = null;
	}
	if (this.last)
	{
		this.removeHover(this.last, remove_active);
	}
},

removeHover: function(el, remove_active)
{
	if (el)
	{
		el.removeClassName('hover');
	}

	if (remove_active)
		this.parent.removeClassName('hover');
}

}; // CoolMenu


document.observe('dom:loaded', function(){

	var add_rbox = function(el)
		{
			if ( el && ! el.down('.r-box') )
				el.update(
					'<span class="r-box"><span class="cont"><span>'+el.innerHTML+'</span></span><span class="tl"></span><span class="tr"></span><span class="bl"></span><span class="br"></span></span>'
					);
		};

	new CoolTabs( $$('#order-form .product-opts').first(),
		{
			onObserve: add_rbox
		});

	new CoolMenu( 'nav',
		{
//			onObserve: function(el, is_child) { if (is_child) add_rbox(el) }
		});

	new FormValidator('order-form', {
		callback_ShowError: function (fv, err)
				{
					$('order-form-err').update(err);
					if (fv._tm)
						clearTimeout(fv._tm);
					else
					{
						Effect.BlindUp('order-form-comm', { duration: 0.2 });
						Effect.BlindDown('order-form-err', { duration: 0.4 });
					}
					fv._tm = setTimeout( function()
						{
							clearTimeout(fv._tm);
							fv._tm = null;
							Effect.BlindUp('order-form-err', { duration: 0.2 });
							Effect.BlindDown('order-form-comm', { duration: 0.4 });
						}, 3000);
				},
		add_validators: [
			function (fv)
				{
					var email = fv.form.down('input[name=email]').getValue().strip();
					var phone = fv.form.down('input[name=phone]').getValue().strip();
					if (
						email != ''
						||
						phone != ''
						)
						return true;

					fv.ShowError( 'Укажите e-mail или контактный телефон!' );

					return false;
				},
			function (fv)
				{
					var rc = false;
					fv.form.select('input[type=checkbox]').each(function(el)
						{
							if (el.name == 'product[]' && el.checked)
								rc = true;
						});
					
					if (!rc)
						fv.ShowError( 'Выберите что-то из предлагаемых услуг!' );
					
					return rc;
				}
			]
		});

});

