/**
 * @author Vladislav Yakovlev (scorpix@design.ru)
 * @copyright Art.Lebedev Studio (http://www.artlebedev.ru)
 * @requires jQuery
 * @requires jQuery Dimensions (jquery.dimensions.min.js)
 * @requires jTweener 0.2
 * @requires PopupBlock 2.1
 */

$('.for_submit input').click(function(event){
		event.preventDefault();
	});

/**
 * Объект анимации "кривых" форм.
 */
var skewed = (function(){
	
	/**
	 * Коэффициент искривления.
	 */
	var kHeight = 0.311;

	/**
	 * Текущая секция. Варианты:
	 * <ul>
	 * 	<li><code>login</code> - авторизация,</li>
	 * 	<li><code>remind</code> - отправка пароля на почту,</li>
	 * 	<li><code>register</code> - регистрация,</li>
	 * 	<li><code>full_register</code> - регистрация с расширенными полями.</li>
	 * </ul>
	 */
	var currentView = 'login';

	/**
	 * Высота 1 em в пикселях.
	 * @type {int}
	 */
	var emHeight;

	/**
	 * Корневой блок искривленной формы.
	 * @type {jQuery}
	 */
	var block;

	/**
	 * Блок декора.
	 * @type {jQuery}
	 */
	var decor;

	/**
	 * Блоки секций с формами.
	 */
	var sections = {};

	/**
	 * Блок измерителя высоты 1 em.
	 * @type {jQuery}
	 */
	var measure;

	var padsInSections = {};

	$(function() {

		block = $('.skewed');
		decor = block.find('.decor');
		sections = {
			'login': block.find('.section.login'),
			'remind': block.find('.section.remind'),
			'register': block.find('.section.register'),
			'full_register': block.find('.section.full_register')
		};

		block.find('.pseudo_link').click(function() {
			
			/**
			 * Массив названий классов элемента.
			 * @type {Array[String]}
			 */
			var classes = $(this).attr('class').split(' ');

			/** Префикс класса, отвечающего за тип представления. */
			var prefix = 'link_';

			// Находим тип и показываем нужную секцию.
			for (var i = 0; i < classes.length; i++) {
				if (0 == classes[i].indexOf(prefix)) {
					showSection(classes[i].substr(prefix.length));

					break;
				}
			}
		});

		PopupBlock({
			container: block,
			link: $('#fitting .enter'),
			close: block.find('.fitting .pseudo_link'),
			showFunction: function() {
				block.find('.section:visible input:text:first').focus();
				//$('#fitting').addClass('hidden');
			}// ,
			// 			hideFunction: function(){
			// 				$('#fitting').removeClass('hidden');
			// 			}
		});

		init();
	});

	/**
	 * Инициализация блока форм.
	 */
	function init() {
		block.css({
			visibility: 'hidden',
			display: 'block'
		});

		block.addClass('section_' + currentView);

		/** Измеритель высоты 1em в блоке */
		measure = $('<div class="measure"/>').appendTo(block);

		emHeight = measure.height();
		offsetForm = sections[currentView].find('form').offset();
		updatePads();
		// $('#popups > div.popup').css('left',getDecorPad(currentView)*2);
		block.css({
			left: -getDecorPad(currentView),
			visibility: '',
			display: ''
		});

		setInterval(checkEm, 200);
	}

	/**
	 * Следит за изменением масштабирования страницы.
	 */
	function checkEm() {

		if ('none' == block.css('display')) {
			return;
		}

		/** Новая высота 1 em */
		var newEmHeight = measure.height();

		if (newEmHeight != emHeight) {
			emHeight = newEmHeight;
			updatePads();
		}
	}

	/**
	 * Возвращает смещение контента.
	 *
	 * @param {String} type Название секции.
	 * @return {Number}
	 */
	function getDecorPad(type) {
		return Math.ceil(sections[type].height() * kHeight);
	}

	/**
	 * Обновляет ширину декоративного блока.
	 */
	function updateDecorPad() {
		var pad = $.browser.msie && 6 >= parseInt($.browser.version) ? 366 : 0;
		decor.width(Math.ceil(decor.height() * kHeight) + pad);
	}

	/**
	 * Обновляет смещение элементов в секции.
	 *
	 * @param {String} type Название секции. По умолчанию - текущая секция, указанная в <code>currentView</code>.
	 */
	function updateFormPads(type) {

		if (!type) {
			type = currentView;
		}

		/**
		 * Секция, с которой будем работать.
		 * @type {jQuery}
		 */
		var curSection = sections[type];

		if (padsInSections[type]) {
			return;
		}

		padsInSections[type] = true;

		/**
		 * Смещение формы относительно страницы.
		 * @type {Object}
		 */
		var offsetForm = curSection.find('form').offset();

		// Вычисляем смещения для каждого элемента секции.
		curSection.find('form .pad').each(function() {
			var offset = $(this).offset();
			var diff = (offset.top - offsetForm.top) * kHeight;
			$(this).css('left', ((curSection.height() * kHeight - diff) / emHeight) + 'em');
		});
	}

	/**
	 * Перерисовывает блок.
	 */
	function updatePads() {
		updateDecorPad();
		updateFormPads();
	}

	/**
	 * Анимация смены секций.
	 *
	 * @param {String} type Название секции, которую нужно показать.
	 */
	function showSection(type) {

		/**
		 * Смещение элементов в показываемой секции.
		 * @type {Number}
		 */
		var decorPadType = getDecorPad(type);

		/**
		 * Смещение элементов в текущей секции.
		 * @type {Number}
		 */
		var decorPadCurrent = getDecorPad(currentView);

		var oldHeight = sections[currentView].height();
		var newHeight = sections[type].height();
		var blockLeft = parseInt(block.css('left'));
		var maxPad = decorPadType > decorPadCurrent ? decorPadType : decorPadCurrent;

		/**
		 * Ширина большей секции вместе со смещением.
		 * @type {Number}
		 */
		var maxWidth = decorPadType > decorPadCurrent ? sections[type].width() : sections[currentView].width();
		maxWidth += maxPad;

		// Вычисляем смещения элементов у показываемой секции.
		sections[type].find('form').css({
			height: newHeight,
			width: maxPad / 2 + 366
		});
		sections[type].css({
			visibility: 'hidden',
			display: 'block',
			position: 'absolute',
			top: 0
		});
		updateFormPads(type);
		sections[type].css({
			display: '',
			position: '',
			top: '',
			visibility: ''
		});

		block.css({
			left: decorPadCurrent < decorPadType ? blockLeft - decorPadType + decorPadCurrent : blockLeft,
			width: maxPad + 366
		});
		block.find('.content').css({
			width: maxPad + 366
		});
		decor.css({
			left: 'auto',
			right: 0
		});
		sections[currentView].css('display', 'none');
		sections[type].css({
			display: 'block',
			left: decorPadCurrent > decorPadType ? -decorPadType + decorPadCurrent : 0
		});
		sections[type].find('form').css({
			height: oldHeight,
			overflow: 'hidden',
			width: maxPad / 2 + 366
		});

		block.find('.decor .back.hidden_in_' + currentView).css('display', 'block');
		block.find('.decor .back.hidden_in_' + type).css('z-index', 1);

		jTweener.addNSAction({
			onComplete: function() {

				// Удалим namespace, чтоб Complete'ы не накапливались.
				jTweener.removeNSActions('skewed');

				// Удаляем все стили, которые применили для анимации, и меняем класс
				// у корневого блока.
				sections[type].css({
					display: '',
					left: ''
				});
				sections[type].find('form').css({
					height: '',
					overflow: '',
					width: ''
				});
				block.addClass('section_' + type).removeClass('section_' + currentView);
				block.find('.content').css('width', '');
				decor.css({
					left: '',
					right: ''
				});
				block.css({
					left: -decorPadType,
					width: ''
				});
				sections[currentView].css('display', '');
				decor.find('.back').css({
					display: '',
					opacity: '',
					'z-index': ''
				});

				// Теперь текущая секция другая.
				currentView = type;

				updateFormPads();
				sections[currentView].find('input:text:first').focus();

				// В IE после анимации секция исчезает. Исправим это.
				if ($.browser.msie) {
					sections[currentView].attr('class', sections[currentView].attr('class') + ' ');
				}
			},
			onUpdate: updateDecorPad
		}, 'skewed');

		var animateParams = {
			'namespace': 'skewed',
			time: 0.2,
			transition: 'easeOutQuad'
		};

		// Все приготовили для анимации, теперь запускаем ее.
		$t(sections[type].find('form'), animateParams).tween({ height: newHeight });
		$t(block.find('.decor .back.hidden_in_' + type), animateParams).tween({ opacity: 0 });
	}

	return {
		updatePads: updatePads
	};
})();