/**
 * @author Vlad Yakovlev (scorpix@design.ru)
 * @copyright Art.Lebedev Studio (http://www.artlebedev.ru)
 * @version 0.1
 * @date 2009-08-13
 * @requires jQuery
 * @requires jTweener
 * @requires jCommon
 */

/**
 *	Переключатель табов.
 */
$(function() {

	var
		typesBlock = $('#main_content .chooser .types');
		/**
		 * Блоки, содержащие изображения людей.
		 * @type {jQuery}
		 */
		imageBlocks = $('#main_content .chooser .types .human'),
		/**
		 * Блоки переключателей табов.
		 * @type {jQuery}
		 */
		links = $('#main_content .chooser .types .item'),
		/**
		 * Блок с секциями контента табов.
		 * @type {jQuery}
		 */
		sectionsBlock = $('#main_content .chooser .big_bubble .bb_content'),
		/**
		 * Блоки контента табов.
		 * @type {jQuery}
		 */
		sections = sectionsBlock.find('.section'),
		/**
		 * Блок, который закрывает контент при анимации.
		 * @type {jQuery}
		 */
		fader = sectionsBlock.find('.fader');

	var
		/**
		 * Массив изображений людей.
		 * @type {Array[HumaImage]}
		 */
		images = [],
		/**
		 * Индекс выбранной секции.
		 * @type {Number}
		 */
		curIndex = -1,
		/**
		 * Флаг процесса анимации.
		 * @type {Boolean}
		 */
		isAnimate = false,
		/**
		 * Коэффициент размеров маленького человечка относительно большого.
		 * @type {Number}
		 */
		kHover = 0.8,

		kSmall = 0.73;


	var runnerAnimator = (function() {

		var
			/**
			 * Блок, в котором будет бегунок.
			 * @type {jQuery}
			 */
			runnerBlock = $('#main_content .chooser .mouth_runner'),
			/**
			 * Высота бегунка.
			 * @type {Number}
			 */
			runnerHeight = 17,
			/**
			 * Ширина бегунка.
			 * @type {Number}
			 */
			runnerWidth = 25,
			/**
			 * Позиции бегунка по горизонтали от левого края.
			 * @type {Array[Number]}
			 */
			positions = [231, 45, 395],
			/**
			 * Цвет бордера бегунка.
			 * @type {String}
			 */
			strokeColor = runnerBlock.css('border-top-color'),
			/**
			 * Ширина бордера бегунка.
			 * @type {Number}
			 */
			strokeWeight = parseInt(runnerBlock.css('border-top-width')),
			/**
			 * Цвет фона бегунка.
			 * @type {String}
			 */
			backColor = runnerBlock.css('background-color'),
			/** @type {jQuery} */
			canvas,
			/**
			 * Контекст канваса.
			 * @type {CanvasRenderingContext2D}
			 */
			ctx,
			/**
			 * Ширина канваса.
			 * @type {Number}
			 */
			width,
			/**
			 * Высота канваса.
			 * @type {Number}
			 */
			height,
			/**
			 * Индекс выбранной секции.
			 * @type {Number}
			 */
			curIndex = -1,
			/**
			 * Флаг процесса анимации.
			 * @type {Boolean}
			 */
			isAnimate = false;

		var graphicAdapter = (function() {
			function createCanvas() {
				canvas = $('<canvas class="shape"></canvas>').appendTo(runnerBlock).attr({
					height: height,
					width: width
				});
				ctx = canvas.get(0).getContext('2d');

				ctx.fillStyle = backColor;
				ctx.strokeStyle = strokeColor;
				ctx.lineWidth = strokeWeight;
			}

			function updateCanvas(coords) {
				ctx.clearRect(0, 0, width, height);
				ctx.beginPath();
				ctx.moveTo(coords[0].x, coords[0].y);

				for (var i = 0; i < 3; i++) {
					ctx.bezierCurveTo(coords[i * 3].x, coords[i * 3].y, coords[i * 3 + 1].x, coords[i * 3 + 1].y, coords[i * 3 + 2].x, coords[i * 3 + 2].y);
				}

				ctx.closePath();
				ctx.fill();
				ctx.stroke();
			}

			function createVml() {
				canvas = $(document.createElement('v:shape')).addClass('shape vml').css({
					left: 0,
					height: height,
					top: 0,
					width: width
				}).attr({
					coordsize: width + ' ' + height,
					fillcolor: backColor,
					strokecolor: strokeColor,
					strokeweight: strokeWeight
				}).appendTo(runnerBlock);
			}

			function updateVml(coords) {
				var path = 'm ' + coords[0].x + ',' + coords[0].y;

				for (var i = 0; i < 3; i++) {
					path += ' c ' + coords[i * 3].x + ',' + coords[i * 3].y + ' ' + coords[i * 3 + 1].x + ',' + coords[i * 3 + 1].y + ' ' + coords[i * 3 + 2].x + ',' + coords[i * 3 + 2].y;
				}

				canvas.attr('path', path);
			}

			return jCommon.isCanvas ? {
				create: createCanvas,
				update: updateCanvas
			} : {
				create: createVml,
				update: updateVml
			};
		})();

		init();

		/**
		 * Инициализирует канвас/VML.
		 */
		function init() {
			runnerBlock.css({
				backgroundColor: 'transparent',
				borderWidth: 0
			});
			height = runnerBlock.height();
			width = runnerBlock.width();
			graphicAdapter.create();
		}

		/**
		 * Задает начальное положение бегунка.
		 * @param {Number} index Индекс позиции.
		 */
		function initSelected(index) {

			/** @type {Number} */
			var startLeft = positions[index] - Math.round(runnerWidth / 2);
			/** @type {Number} */
			var yTop = 0;
			/** @type {Number} */
			var yBottom = runnerHeight;
			/** @type {Array[Object]} */
			var dots = [];

			// Начальные координаты бегунка.
			dots.push({ x: startLeft, y: yBottom });
			dots.push({ x: startLeft, y: yBottom });
			dots.push({ x: startLeft, y: yBottom });
			dots.push({ x: startLeft, y: yBottom });
			dots.push({ x: startLeft + Math.round(runnerWidth / 2), y: yTop });
			dots.push({ x: startLeft + Math.round(runnerWidth / 2), y: yTop });
			dots.push({ x: startLeft + Math.round(runnerWidth / 2), y: yTop });
			dots.push({ x: startLeft + runnerWidth, y: yBottom });
			dots.push({ x: startLeft + runnerWidth, y: yBottom });

			graphicAdapter.update(dots);
		}

		/**
		 * Анимирует передвижение бегунка из текущего положения в новое.
		 * @param {Number} oldIndex Индекс начального положения бегунка.
		 * @param {Number} newIndex Индекс конечного положения бегунка.
		 */
		function animate(oldIndex, newIndex) {

			isAnimate = true;

			/** @type {Array[Object]} */
			var dots = calculateDots(oldIndex, newIndex);

			jTweener.addTween(runnerBlock, {
				time: 0.5,
				transition: 'easeInOutCubic',
				moveX: function(value) {
					step(dots, 0, value);
				},
				onComplete: function() {
					jTweener.addTween(runnerBlock, {
						time: 0.5,
						transition: 'easeOutCubic',
						moveX: function(value) {
							step(dots, 9, value);
						},
						onComplete: function() {
							isAnimate = false;
						}
					});
				}
			});
		}

		/**
		 * Шаг анимации.
		 * @param {Array[Object]} dots Массив координат.
		 * @param {Number} startIndex Индекс начальной точки.
		 * @param {Number} value - Коффициент анимации.
		 */
		function step(dots, startIndex, value) {
			/** @type {Array[Object]} */
			var coords = [];

			for (var i = startIndex; i < startIndex + 9; i++) {
				coords.push({ x: dots[i].x + Math.round((dots[i + 9].x - dots[i].x) * value), y: dots[i].y + Math.round((dots[i + 9].y - dots[i].y) * value) });
			}

			graphicAdapter.update(coords);
		}

		/**
		 * Вычисляет начальные и конечные точки анимации бегунка.
		 * @param {Number} oldIndex Текущий индекс секции.
		 * @param {Number} newIndex Новый индекс секции.
		 * @return {Array[Object]} Массив координат точек.
		 */
		function calculateDots(oldIndex, newIndex) {
			/** @type {Number} */
			var startLeft = positions[oldIndex] - Math.round(runnerWidth / 2);
			/** @type {Number} */
			var finishLeft = positions[newIndex] - Math.round(runnerWidth / 2);
			/** @type {Number} */
			var yTop = 0;
			/** @type {Number} */
			var yBottom = runnerHeight;

			/** Смещение направляющей у первой кривой. */
			var cMove1 = { x: 5, y: 5 };

			var cMove3 = { x: Math.round(Math.abs(finishLeft - startLeft) / 3), y: 0 };

			if (startLeft < finishLeft) {
				cMove1.x = -cMove1.x;
				cMove3.x = -cMove3.x;
			}

			/** Координаты опорной точки первой кривой. */
			var s1 = {
				x: finishLeft + Math.round(runnerWidth / 2) + Math.round((startLeft - finishLeft) / 5),
				y: Math.round(runnerHeight / 2) + 2
			};
			/** Координаты первой направляющей первой кривой. */
			var c1_1 = {
				x: finishLeft,
				y: yBottom
			};
			/** Координаты второй направляющей первой кривой. */
			var c1_2 = {
				x: s1.x - cMove1.x,
				y: s1.y + cMove1.y
			};

			/** Координаты опорной точки второй кривой. */
			var s2 = {
				x: finishLeft + Math.round(runnerWidth / 2),
				y: yTop
			};
			/** Координаты первой направляющей второй кривой. */
			var c2_1 = {
				x: s1.x + cMove1.x,
				y: s1.y - cMove1.y
			};
			/** Координаты второй направляющей второй кривой. */
			var c2_2 = {
				x: s2.x,
				y: s2.y
			};

			/** Координаты опорной точки третьей кривой. */
			var s3 = {
				x: startLeft + runnerWidth,
				y: yBottom
			};
			/** Координаты первой направляющей третьей кривой. */
			var c3_1 = {
				x: s2.x,
				y: s2.y
			};
			/** Координаты второй направляющей третьей кривой. */
			var c3_2 = {
				x: s3.x - cMove3.x,
				y: s3.y - cMove3.y
			};

			var dots = [];

			// Начальные координаты стрелки.
			dots.push({ x: startLeft, y: yBottom });
			dots.push({ x: startLeft, y: yBottom });
			dots.push({ x: startLeft, y: yBottom });
			dots.push({ x: startLeft, y: yBottom });
			dots.push({ x: startLeft + Math.round(runnerWidth / 2), y: yTop });
			dots.push({ x: startLeft + Math.round(runnerWidth / 2), y: yTop });
			dots.push({ x: startLeft + Math.round(runnerWidth / 2), y: yTop });
			dots.push({ x: startLeft + runnerWidth, y: yBottom });
			dots.push({ x: startLeft + runnerWidth, y: yBottom });

			// Промежуточные координаты изогнутой стрелки.
			dots.push(c1_1);
			dots.push(c1_2);
			dots.push(s1);
			dots.push(c2_1);
			dots.push(c2_2);
			dots.push(s2);
			dots.push(c3_1);
			dots.push(c3_2);
			dots.push(s3);

			// Конечные координаты стрелки.
			for (var i = 0; i < 9; i++) {
				dots.push({ x: dots[i].x + finishLeft - startLeft, y: dots[i].y });
			}

			return dots;
		}

		return {
			/**
			 * Запускает анимацию смены положения бегунка.
			 * @param {Number} index Индекс новой позиции.
			 */
			select: function(index) {
				-1 < curIndex ? animate(curIndex, index) : initSelected(index);
				curIndex = index;
			}
		};
	})();

	function HumanImage(rootBlock, k) {

		/**
		 * Блок изображения.
		 * @type {jQuery}
		 */
		var imageBlock = rootBlock.find('img');
		/**
		 * Изображение человека.
		 * @type {Image}
		 */
		var image;

		var isInited = false;

		var curWidth;

		var curHeight;

		var graph = (function() {

			/**
			 * @type {Image}
			 */
			var image;
			/**
			 * @type {jQuery}
			 */
			var canvas;
			/**
			 * Контекст канваса.
			 * @type {CanvasRenderingContext2D}
			 */
			var ctx;

			function createSimple(parentBlock, inImage) {
				image = parentBlock;
			}

			function updateSimple(width, height) {
				image.find('img').css({
					width: width,
					height: height
				});
			}

			function createCanvas(parentBlock, inImage) {
				image = inImage;
				canvas = $('<canvas class="shape"></canvas>').appendTo(parentBlock).attr({
					height: image.height,
					width: image.width
				});
				ctx = canvas.get(0).getContext('2d');
			}

			function updateCanvas(width, height) {
				var dx = (image.width - width) / 2;
				var dy = image.height - height;

				ctx.clearRect(0, 0, image.width, image.height);
				ctx.drawImage(image, 0, 0, image.width, image.height, dx, dy, width, height);
			}

			function createVml(parentBlock, inImage) {
				image = inImage;

				canvas = $(document.createElement('v:image')).addClass('shape vml').css({
					height: image.height,
					width: image.width
				}).attr('src', image.src).appendTo(parentBlock);
			}

			function updateVml(width, height) {
				canvas.css({
					width: width,
					height: height,
					left: Math.round((image.width - width) / 2)
				});
			}

			if ($.browser.opera) {
				return {
					create: createSimple,
					update: updateSimple
				};
			} else if (jCommon.isCanvas) {
				return {
					create: createCanvas,
					update: updateCanvas
				};
			} else {
				return {
					create: createVml,
					update: updateVml
				};
			}

//			return jCommon.isCanvas ? {
//				create: createCanvas,
//				update: updateCanvas
//			} : {
//				create: createVml,
//				update: updateVml
//			};
		})();

		init();

		function onImageLoad() {
			setCurSize(image.width * k, image.height * k);
			graph.create(rootBlock, image);
			graph.update(curWidth, curHeight);
			$.browser.opera && imageBlock.css('bottom', -180).removeClass('hidden');

			$t($.browser.opera ? imageBlock : rootBlock.find('.shape'), {
				delay: 0.2 * rootBlock.parent().nextAll().size(),
				time: 0.3,
				bottom: 0
			}).tween();

			isInited = true;
		}

		function init() {
			image = new Image();
			image.onload = onImageLoad;
			image.src = imageBlock.attr('src');
			imageBlock.addClass('hidden');
		}

		function animateTo(k, time) {
			if (!isInited) {
				setCurSize(image.width * k, image.height * k);

				return;
			}

			jTweener.removeTween(rootBlock);

			var startWidth = curWidth;

			var startHeight = curHeight;

			var difWidth = image.width * k - startWidth;

			var difHeight = image.height * k - startHeight;

			$t(rootBlock, {
				time: time,
				moveX: function(value) {
					curWidth = startWidth + difWidth * value;
					curHeight = startHeight + difHeight * value;
					graph.update(curWidth, curHeight);
				}
			}).tween();
		}

		function setCurSize(width, height) {
			curWidth = width;
			curHeight = height;
		}

		return {
			animateTo: animateTo
		};
	};

	init();

	/**
	 * Инициализирует изображения и секции.
	 */
	function init() {
		imageBlocks.each(function(index) {
			images.push(new HumanImage($(this), index ? kSmall : 1));
		});

		sections.addClass('hidden');
		selectSection(0);

		links.each(function(index) {
			var el = $(this);

			el.click(function() {
				!isAnimate && curIndex != index && selectSection(index);
			});
			el.hover(function() {
				curIndex != index && images[index].animateTo(kHover, 0.2);
			}, function() {
				curIndex != index && images[index].animateTo(kSmall, 0.2);
			});
		});
	}

	function fadeSelected(sectionIndex) {
		sections.eq(sectionIndex).find('.selected_corner').each(function() {
			if (!$(this).parent().hasClass('selected')) return;
			var el = $(this).find('.selc_fade');

			el.css({
				display: 'block',
				opacity: 1
			});
			setTimeout(function() {
				$t(el, {
					time: .3,
					opacity: 0,
					transition: 'easeNone',
					onComplete: function() {
						el.css({
							display: 'none',
							opacity: ''
						});
					}
				}).tween();
			}, 1200);
		});
	}

	function selectSection(index) {

		runnerAnimator.select(index);

		if (-1 < curIndex) {
			animate(curIndex, index);
		} else {
			links.eq(index).addClass('selected');
			sections.eq(index).removeClass('hidden');
		}

		curIndex = index;
	}

	function animate(oldIndex, newIndex) {

		isAnimate = true;

		images[oldIndex].animateTo(kSmall, 0.5);
		images[newIndex].animateTo(1, 0.5);
		links.eq(oldIndex).removeClass('selected');
		links.eq(newIndex).addClass('selected');

		var oldSection = sections.eq(oldIndex);

		var newSection = sections.eq(newIndex);

		var oldSectionHeight = oldSection.height();

		newSection.css({
			display: 'block',
			left: -10000,
			visibility: 'hidden',
			top: -10000,
			position: 'absolute',
			width: '100%'
		});

		var newSectionHeight = newSection.height();

		newSection.css({
			display: '',
			left: '',
			visibility: '',
			top: '',
			position: '',
			width: ''
		});

		var sectionsHeight = oldSectionHeight > newSectionHeight ? oldSectionHeight : newSectionHeight;

		sectionsBlock.height(sectionsHeight);
		fader.css({
			display: 'block',
			opacity: 0
		});

		typesBlock.addClass('types_animate');

		if ($.browser.msie && 6 >= parseInt($.browser.version)) {
			fader.height(fader.parent().outerHeight());
		}

		fadeSelected(newIndex);

		$t(fader, {
			time: 0.5,
			transition: 'easeInOutCubic',
			opacity: 1,
			onComplete: function() {
				oldSection.addClass('hidden');
				newSection.removeClass('hidden');

				$t(fader, {
					time: 0.5,
					transition: 'easeOutCubic',
					opacity: 0,
					onComplete: function() {
						isAnimate = false;
						typesBlock.removeClass('types_animate');

						fader.css({
							display: 'none',
							opacity: 1
						});
						sectionsBlock.css('height', '');

						// В Сафари баг с перерисовкой, если скроллинг был больше высоты окна.
						$(window).scrollTop($(window).scrollTop());
					}
				}).tween();
			}
		}).tween();
	}
});


/**
 * Переключатель симптомов.
 */
$(function() {
	var rootBlock = $('#main_content .health');

	var links = rootBlock.find('.navigation .item');

	var sections = rootBlock.find('.health_section');

	var symptoms = rootBlock.find('.symptoms .symptom');

	var symptomsCharacts = [];

	var curIndex = -1;

	init();

	function init() {
		sections.addClass('hidden');

		symptoms.each(function(index) {

			var el = $(this);
			var coldEl = $(this).find('.cold');
			var fluEl = $(this).find('.flu');

			symptomsCharacts.push([{
				color: getColor(el.css('color')),
				left: parseInt(el.css('left')),
				size: parseInt(el.css('font-size')),
				top: parseInt(el.css('top'))
			}, {
				color: getColor(coldEl.css('color')),
				left: parseInt(coldEl.css('left')),
				size: parseInt(coldEl.css('font-size')),
				top: parseInt(coldEl.css('top'))
			}, {
				color: getColor(fluEl.css('color')),
				left: parseInt(fluEl.css('left')),
				size: parseInt(fluEl.css('font-size')),
				top: parseInt(fluEl.css('top'))
			}, {}]);
		});

		fastSelect(1);

		links.find('.pseudo_link').each(function(index) {
			$(this).click(function() {
				index == curIndex || select(index);
			});
		});
	}

	function select(index) {
		if (-1 < curIndex) {
			links.eq(curIndex).removeClass('selected');
			sections.eq(curIndex).addClass('hidden');
		}

		links.eq(index).addClass('selected');
		sections.eq(index).removeClass('hidden');

		var tweenParams = {
			time: 1
		};

		var oldIndex = curIndex;
		var newIndex = index;

		for (var i = 0; i < symptomsCharacts.length; i++) {
			jTweener.removeTween(symptoms.eq(i));

			var params = function(symptom) {
				return {
					fontSize: symptomsCharacts[symptom][newIndex].size,
					left: symptomsCharacts[symptom][newIndex].left,
					top: symptomsCharacts[symptom][newIndex].top,
					moveX: function(value) {
						var oldSymptom = symptomsCharacts[symptom][3];
						var newSymptom = symptomsCharacts[symptom][newIndex];
						var curSymptom = {
							color: [
								oldSymptom.color[0] + Math.round((newSymptom.color[0] - oldSymptom.color[0]) * value),
								oldSymptom.color[1] + Math.round((newSymptom.color[1] - oldSymptom.color[1]) * value),
								oldSymptom.color[2] + Math.round((newSymptom.color[2] - oldSymptom.color[2]) * value)
							],
							left: oldSymptom.left + Math.round((newSymptom.left - oldSymptom.left) * value),
							size: oldSymptom.size + Math.round((newSymptom.size - oldSymptom.size) * value),
							top: oldSymptom.top + Math.round((newSymptom.top - oldSymptom.top) * value)
						};

						symptomsCharacts[symptom][3] = curSymptom;
						symptoms.eq(symptom).css('color', 'rgb(' + curSymptom.color[0] + ', ' + curSymptom.color[1] + ', ' + curSymptom.color[2] + ')');
					}
				};
			};
			$t(symptoms.eq(i), tweenParams).tween(params(i));
		}

		curIndex = index;
	}

	function fastSelect(index) {
		if (-1 < curIndex) {
			links.eq(curIndex).removeClass('selected');
			sections.eq(curIndex).addClass('hidden');
		}

		links.eq(index).addClass('selected');
		sections.eq(index).removeClass('hidden');

		for (var i = 0; i < symptomsCharacts.length; i++) {
			symptomsCharacts[i][3].color = symptomsCharacts[i][index].color;
			symptomsCharacts[i][3].left = symptomsCharacts[i][index].left;
			symptomsCharacts[i][3].size = symptomsCharacts[i][index].size;
			symptomsCharacts[i][3].top = symptomsCharacts[i][index].top;
			symptoms.eq(i).css({
				color: 'rgb(' + symptomsCharacts[i][3].color[0] + ',' + symptomsCharacts[i][3].color[1] + ',' + symptomsCharacts[i][3].color[2] + ')',
				fontSize: symptomsCharacts[i][3].size,
				left: symptomsCharacts[i][3].left,
				top: symptomsCharacts[i][3].top
			});
		}

		curIndex = index;
	}

	function getColor(colorStyle) {
		var rgbReg = /^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/i;
		var htmlReg = /^#([\dabcdef]+)$/;

		if (rgbReg.test(colorStyle)) {
			var color = colorStyle.replace(rgbReg, "$1 $2 $3").split(' ');

			for (var i = 0; i < color.length; i++) {
				color[i] = parseInt(color[i]);
			}

			return color;
		}

		if (htmlReg.test(colorStyle)) {
			var color = colorStyle.replace(htmlReg, "$1");

			if (3 == color.length) {
				color = color.substr(0, 1) + color.substr(0, 1) + color.substr(1, 1) + color.substr(1, 1) + color.substr(2, 1) + color.substr(2, 1);
			}

			return [parseInt('0x' + color.substr(0, 2)), parseInt('0x' + color.substr(2, 2)), parseInt('0x' + color.substr(4, 2))];
		}

		return false;
	}
});

$.browser.msie && 6 >= parseInt($.browser.version) && $(window).bind('load resize', function() {
	$('#main_content .wrap th').css('width', 1352 > document.documentElement.clientWidth ? 665 : '50%');
});

$.browser.msie && 7 >= parseInt($.browser.version) && $(function() {
	$('#main_content .big_bubble .drugs h3 a').each(function() {
		var a = $(this);
		a.find('img').click(function() {
			location.href = a.attr('href');
		});
	});
});


/**
 * Ховер баннеров видео.
 */
$(function() {

	var
		rootEl = $('#main_content .video .main_image'),
		mainLinkEl = $('#main_content .video .view'),
		linkEls = rootEl.find('a');

	var backEl = $('<span class="opback"></span>').appendTo(rootEl);
	var backOpacity = 0.7;

	backEl.css('opacity', 0);

	linkEls.each(function(index) {
		var sourceEl = $(this);
		var destEl = sourceEl.clone().addClass('additional').appendTo(rootEl);

		destEl.hover(function() {
			destEl.animate({ opacity: 1 }, 400);
			destEl.css('z-index', 3);
		}, function() {
			destEl.animate({ opacity: 0 }, 400);
			destEl.css('z-index', '');
		});
	});

	rootEl.hover(function() {
		mainLinkEl.addClass('hover');
		backEl.animate({ opacity: backOpacity }, 400);
	}, function() {
		mainLinkEl.removeClass('hover');
		backEl.animate({ opacity: 0 }, 400);
	});
});