/**
 * @author Vlad Yakovlev (scorpix@design.ru)
 * @copyright Art.Lebedev Studio (http://www.artlebedev.ru)
 * @version 0.1.2
 * @date 2009-10-07
 * @requires jQuery
 * @requires jTweener
 * @requires PopupBlock
 */
var isCanvas = (function() {
	if ('undefined' != typeof(HTMLCanvasElement)) return true;

	// В IE для VML надо добавить схему и стили.
	if (!document.namespaces['v']) {
		document.namespaces.add('v', 'urn:schemas-microsoft-com:vml');
		document.namespaces.add('o', 'urn:schemas-microsoft-com:office:office');

		var ss = document.createStyleSheet();
		ss.cssText = 'v\\:arc, v\\:curve, v\\:extrusion, v\\:fill, v\\:formulas, v\\:group, v\\:handles, v\\:image, v\\:imagedata, v\\:line, v\\:oval, v\\:path, v\\:polyline, v\\:rect, v\\:roundrect, v\\:shadow, v\\:shape, v\\:shapetype, v\\:stroke, v\\:textbox, v\\:textpath, v\\:vmlframe {behavior:url(#default#VML);display:block;} o\\:callout, o\\:locks, o\\:skew {behavior:url(#default#VML);}';
	}

	return false;
})();

var LineGallery = (function() {

	var
		svgNs = 'http://www.w3.org/2000/svg',
		xlinkNs = 'http://www.w3.org/1999/xlink';

	var
		root,
		sections,
		items,
		vectors = [],
		firstIndex = 0,
		minHeight = 10,
		minWidth = 10
		info = [],
		firstImageIndex = 0,
		isAnimate = false;

	var
		popup,
		popupEl;

	function createSvg(index) {
		var
			section = sections.eq(index),
			item = items.eq(index),
			sectionWidth = section.width(),
			sectionHeight = section.height();

		var itemSvg = document.createElementNS(svgNs, 'svg');
		itemSvg.attr({
			version: '1.1',
			'class': 'shape',
			width: '200%',
			height: '200%',
			viewBox: '0 0 ' + (sectionWidth * 2) + ' ' + (sectionHeight * 2)
		});
		item.get(0).appendChild(itemSvg);

		var g = document.createElementNS(svgNs, 'g');
		g.attr({
			x: Math.round(sectionWidth),
			y: Math.round(sectionHeight / 2),
			transform: 'rotate(' + getAngle(item) + ' ' + Math.round(sectionHeight) + ' ' + Math.round(sectionWidth * 2) + ')'
		});
		itemSvg.appendChild(g);

		var image = document.createElementNS(svgNs, 'image');
		image.attr({
			height: item.height() + 'px',
			width: item.width() + 'px',
			x: Math.round(sectionWidth / 2),
			y: sectionHeight * 1.1
		});
		image.attr(xlinkNs + ':href', item.find('img').attr('src'));
		g.appendChild(image);
		vectors[index] = image;

		var leftHand = document.createElementNS(svgNs, 'image');
		leftHand.attr({
			height: item.find('.left_hand').height() + 'px',
			width: item.find('.left_hand').width() + 'px',
			x: Math.round(sectionWidth / 2) + item.find('.left_hand').position().left,
			y: sectionHeight + item.find('.left_hand').position().top
		});
		leftHand.attr(xlinkNs + ':href', getSrc(item.find('.left_hand').css('background-image')));
		g.appendChild(leftHand);

		var rightHand = document.createElementNS(svgNs, 'image');
		rightHand.attr({
			height: item.find('.right_hand').height() + 'px',
			width: item.find('.right_hand').width() + 'px',
			x: Math.round(sectionWidth / 2) + item.find('.right_hand').position().left,
			y: sectionHeight + item.find('.right_hand').position().top
		});
		rightHand.attr(xlinkNs + ':href', getSrc(item.find('.right_hand').css('background-image')));
		g.appendChild(rightHand);

		item.find('img, .left_hand, .right_hand').css('display', 'none');

		setPos(index, false);
	}

	function updateSvgImage(imageIndex) {
		var index = (firstIndex + sections.length - 1) % sections.length;
		vectors[index].attr(xlinkNs + ':href', info[imageIndex].src);
	}

	function createVml(index) {
		var
			section = sections.eq(index),
			item = items.eq(index),
			sectionWidth = section.width(),
			sectionHeight = section.height();

		var g = $(document.createElement('v:group'));
		g.addClass('shape_vml group').css({
			height: '100%',
			width: '100%'
//			rotation: getAngle(item)
		}).attr({
			coordsize: sectionWidth + ' ' + sectionHeight
		}).appendTo(item);

		var image = $(document.createElement('v:image'));
		image.css({
			height: '50%',
			width: '100%',
			top: '40%'
		}).attr({
			src: item.find('img').attr('src')
		}).appendTo(g);
		item.find('img').remove();
		vectors[index] = image;

		var leftHand = $(document.createElement('v:image'));
		leftHand.addClass('shape_vml').css({
			height: item.find('.left_hand').height(),
			width: item.find('.left_hand').width(),
			left: item.find('.left_hand').position().left,
			top: item.find('.left_hand').position().top
		}).attr({
			src: getSrc(item.find('.left_hand').css('background-image'))
		}).appendTo(g);
		item.find('.left_hand').remove();

		var rightHand = $(document.createElement('v:image'));
		rightHand.addClass('shape_vml').css({
			height: item.find('.right_hand').height(),
			width: item.find('.right_hand').width(),
			left: item.find('.right_hand').position().left,
			top: item.find('.right_hand').position().top
		}).attr({
			src: getSrc(item.find('.right_hand').css('background-image'))
		}).appendTo(g);
		item.find('.right_hand').remove();

		section.css('background-image', 'none');

		setPos(index, false);
	}

	function updateVmlImage(imageIndex) {
		var index = (firstIndex + sections.length - 1) % sections.length;
		vectors[index].attr('src', info[imageIndex].src);
	}

	function setPoses(onlyMargin) {
		sections.each(function(index) {
			setPos(index, onlyMargin);
		});
	}

	function setPos(index, onlyMargin) {
		var
			section = sections.eq(index),
			item = items.eq(index),
			correctIndex = (firstIndex + index) % sections.length,
			sectionWidth = section.width(),
			sectionHeight = section.height();

		if (onlyMargin) {
			var css = { marginLeft: -Math.round(sectionWidth / 2) };
			section.css(css);
			item.css(css);
		} else {
			switch (correctIndex) {
				case 0:
				case 4:
					var css = {
						marginLeft: -Math.round(sectionWidth * .2),
						width:  Math.round(sectionWidth * .4),
						height: Math.round(sectionHeight * .4)
					};
					section.css(css);
					item.css(css);
					break;
				case 1:
				case 3:
					var css = {
						marginLeft: -Math.round(sectionWidth * .35),
						width: Math.round(sectionWidth * .7),
						height: Math.round(sectionHeight * .7)
					};
					section.css(css);
					item.css(css);
					break;

				case 2:
					var css = {
						marginLeft: -Math.round(sectionWidth * .5),
						width: Math.round(sectionWidth),
						height: Math.round(sectionHeight)
					};
					section.css(css);
					item.css(css);
					break;
			}
		}
	}

	function next(isDuble) {
		var
			dataStart = [],
			dataFinish = [],
			index,
			nextIndex,
			section,
			item,
			css,
			rootOffset = root.offset(),
			imageIndex = getImageIndex(firstImageIndex - 1);

		isAnimate = true;
		isCanvas ? updateSvgImage(imageIndex) : updateVmlImage(imageIndex);
		updateArrows();
		loadImage(getImageIndex(imageIndex - 1));
		loadImage(getImageIndex(imageIndex - 2));

		sections.each(function(index) {
			var
				section = $(this),
				item = items.eq(index)
				css;

			if (index == (firstIndex + sections.length - 1) % sections.length) {
				dataFinish.push({
					left: root.width() - minWidth,
					height: minHeight,
					width: minWidth,
					margin: 0
				});
				css = {
					left: 0,
					height: minHeight,
					width: minWidth,
					margin: 0
				};
			} else {
				css = {
					left: Math.round(section.offset().left - rootOffset.left),
					height: section.height(),
					width: section.width(),
					margin: 0
				};
				dataFinish.push(css);
			}

			dataStart.push(css);
			section.css(css);
			item.css(css);
		});

		var isChange = false;

		$t(root, {
			time: isDuble ? .3 : .7,
			moveX: function(value) {
				if (0.5 < value && !isChange) {
					sections.each(function(index) {
						var oldIndex = parseInt(getId(this, 'pos'));
						var newIndex = (oldIndex + 1) % sections.length;
						$(this).removeClass('pos' + oldIndex).addClass('pos' + newIndex);
					});
					items.each(function(index) {
						var oldIndex = parseInt(getId(this, 'pos'));
						var newIndex = (oldIndex + 1) % sections.length;
						$(this).removeClass('pos' + oldIndex).addClass('pos' + newIndex);
					});

					isChange = true;
				}

				sections.each(function(index) {
					var
						nextIndex = (index + 1) % sections.length,
						section = sections.eq(index),
						item = items.eq(index),
						sLeft = dataStart[index].left,
						sHeight = dataStart[index].height,
						sWidth = dataStart[index].width,
						fLeft = dataFinish[nextIndex].left,
						fHeight = dataFinish[nextIndex].height,
						fWidth = dataFinish[nextIndex].width;
					var css = {
						left: sLeft + Math.round((fLeft - sLeft) * value),
						height: sHeight + Math.round((fHeight - sHeight) * value),
						width: sWidth + Math.round((fWidth - sWidth) * value)
					};
					section.css(css);
					item.css(css);
					item.find('.group').css({
						height: sHeight + Math.round((fHeight - sHeight) * value),
						width: sWidth + Math.round((fWidth - sWidth) * value)
					});
				});
			},
			onComplete: function() {
				firstIndex = (firstIndex - 1 + sections.length) % sections.length;
				firstImageIndex = getImageIndex(firstImageIndex - 1);
				setPoses(true);
				var css = { left: '' };
				sections.css(css);
				items.css(css);

				items.find('.group').css({
					height: '100%',
					width: '100%'
				});

				isAnimate = false;
				updateArrows();

				isDuble && next();
			}
		}).tween();
	}

	function prev(isDuble) {
		var
			dataStart = [],
			dataFinish = [],
			index,
			nextIndex,
			section,
			item,
			css,
			rootOffset = root.offset(),
			imageIndex = getImageIndex(firstImageIndex + sections.length - 1);

		isAnimate = true;
		isCanvas ? updateSvgImage(imageIndex) : updateVmlImage(imageIndex);
		updateArrows();
		loadImage(getImageIndex(imageIndex + 1));
		loadImage(getImageIndex(imageIndex + 2));

		sections.each(function(index) {
			var
				section = $(this),
				item = items.eq(index),
				css;

			if (index == (firstIndex + sections.length - 1) % sections.length) {
				dataFinish.push({
					left: 0,
					height: minHeight,
					width: minWidth,
					margin: 0
				});
				css = {
					left: root.width() - minWidth,
					height: minHeight,
					width: minWidth,
					margin: 0
				};
			} else {
				css = {
					left: Math.round(section.offset().left - rootOffset.left),
					height: section.height(),
					width: section.width(),
					margin: 0
				};
				dataFinish.push(css);
			}

			dataStart.push(css);
			section.css(css);
			item.css(css);
		});

		var isChange = false;

		$t(root, {
			time: isDuble ? .3 : .7,
			moveX: function(value) {
				if (0.5 < value && !isChange) {
					sections.each(function(index) {
						var oldIndex = parseInt(getId(this, 'pos'));
						var newIndex = (oldIndex - 1 + sections.length) % sections.length;
						$(this).removeClass('pos' + oldIndex).addClass('pos' + newIndex);
					});
					items.each(function(index) {
						var oldIndex = parseInt(getId(this, 'pos'));
						var newIndex = (oldIndex - 1 + sections.length) % sections.length;
						$(this).removeClass('pos' + oldIndex).addClass('pos' + newIndex);
					});

					isChange = true;
				}

				sections.each(function(index) {
					var
						nextIndex = (index - 1 + sections.length) % sections.length,
						section = sections.eq(index),
						item = items.eq(index),
						sLeft = dataStart[index].left,
						sHeight = dataStart[index].height,
						sWidth = dataStart[index].width,
						fLeft = dataFinish[nextIndex].left,
						fHeight = dataFinish[nextIndex].height,
						fWidth = dataFinish[nextIndex].width;
					var css = {
						left: sLeft + Math.round((fLeft - sLeft) * value),
						height: sHeight + Math.round((fHeight - sHeight) * value),
						width: sWidth + Math.round((fWidth - sWidth) * value)
					};
					section.css(css);
					item.css(css);
					item.find('.group').css({
						height: sHeight + Math.round((fHeight - sHeight) * value),
						width: sWidth + Math.round((fWidth - sWidth) * value)
					});
				});
			},
			onComplete: function() {
				firstIndex = (firstIndex + 1 + sections.length) % sections.length;
				firstImageIndex = getImageIndex(firstImageIndex + 1);
				setPoses(true);
				var css = { left: '' };
				sections.css(css);
				items.css(css);

				items.find('.group').css({
					height: '100%',
					width: '100%'
				});

				isAnimate = false;
				updateArrows();

				isDuble && prev();
			}
		}).tween();
	}

	function loadImage(index) {
		if (info[index].loaded) return;

		var image = new Image();
		image.onload = function() {
			info[index].loaded = true;
			updateArrows();
		};
		image.src = info[index].src;
		info[index].image = image;
	}

	function getId(el, prefix) {
		var classes = $(el).attr('class').split(' ');

		for (var i = 0; i < classes.length; i++) {
			if (prefix == classes[i].substr(0, prefix.length)) {
				return classes[i].substr(prefix.length);
			}
		}

		return false;
	}

	function getAngle(el) {
		var prefix = 'angle_';
		var classes = $(el).attr('class').split(' ');

		for (var i = 0; i < classes.length; i++) {
			if (prefix == classes[i].substr(0, prefix.length)) {
				return classes[i].substr(prefix.length);
			}
		}

		return false;
	}

	function getImageIndex(index) {
		return (index + info.length) % info.length;
	}

	function getSrc(css) {
		var urlRegExp = /^url\([\"\']?([^\'\"]*)[\"]?\)$/i;
		return css.replace(urlRegExp, "$1");
	}

	function init() {
		var imageEls = root.find('.images_info .image');
		var loaded = 0;

		imageEls.each(function(index) {
			var src = $(this).find('img').attr('src');

			info.push({
				src: src,
				content: $(this).find('.content').html(),
				loaded: false
			});

			if (index < sections.length || index == imageEls.length - 1) {
				var image = new Image();
				image.onload = function() {
					info[index].loaded = true;
					loaded++;

					if (loaded == sections.length + 1) {
						root.addClass('line_gallery_inited')
						updateArrows();
					}
				};
				image.src = src;
				info[index].image = image;
			}
		});
	}

	function updateArrows() {
		if (isAnimate || !info[getImageIndex(firstImageIndex - 1)].loaded) {
			root.find('.next, .click_photo_prev1').addClass('disabled');
		} else {
			root.find('.next, .click_photo_prev1').removeClass('disabled');
		}

		if (isAnimate || !info[getImageIndex(firstImageIndex - 1)].loaded || !info[getImageIndex(firstImageIndex - 2)].loaded) {
			root.find('.click_photo_prev2').addClass('disabled');
		} else {
			root.find('.click_photo_prev2').removeClass('disabled');
		}

		if (isAnimate || !info[getImageIndex(firstImageIndex + sections.length - 1)].loaded) {
			root.find('.prev, .click_photo_next1').addClass('disabled');
		} else {
			root.find('.prev, .click_photo_next1').removeClass('disabled');
		}

		if (isAnimate || !info[getImageIndex(firstImageIndex + sections.length - 1)].loaded || !info[getImageIndex(firstImageIndex + sections.length - 2)].loaded) {
			root.find('.click_photo_next2').addClass('disabled');
		} else {
			root.find('.click_photo_next2').removeClass('disabled');
		}
	}

	function openPopup(evt) {
		if (isAnimate) return;

		var
			index = (firstIndex - 1 + parseInt(sections.length / 2)) % sections.length,
			imageIndex = getImageIndex(firstImageIndex - 1 + parseInt(sections.length / 2)),
			popupWidth = 150 + info[imageIndex].image.width,
			handLeft = popupEl.find('.hand_left'),
			handRight = popupEl.find('.hand_right');

		for (var i = 0; i < sections.length; i++) {
			handLeft.removeClass('hand_left' + i);
			handRight.removeClass('hand_right' + i);
		}

		popupEl
			.css({
				top: root.offset().top + 120,
				width: popupWidth,
				marginLeft: -Math.round(popupWidth / 2)
			})
			.find('.popup_content').html('').html('<img alt="" src="' + info[imageIndex].src + '" />' + info[imageIndex].content);
		handLeft.addClass('hand_left' + index);
		handRight.addClass('hand_right' + index);

		popup.show(evt);
	}

	return function() {

		$(function() {
			root = $('.line_gallery');
			sections = root.find('.section');
			items = root.find('.item');

			sections.each(function(index) {
				isCanvas ? createSvg(index) : createVml(index);
			});

			popupEl = root.find('.popup_block').appendTo($('#page_body'));
			popup = PopupBlock({
				container: popupEl,
				close: popupEl.find('.popup_close'),
				afterHide: function() {
					popupEl.find('.popup_content').html('');
				}
			});
			root.find('.click_photo').click(openPopup);

			root.find('.prev, .click_photo_next1').click(function() {
				$(this).hasClass('disabled') || prev();
			});
			root.find('.next, .click_photo_prev1').click(function() {
				$(this).hasClass('disabled') || next();
			});
			root.find('.click_photo_next2').click(function() {
				$(this).hasClass('disabled') || prev(true);
			});
			root.find('.click_photo_prev2').click(function() {
				$(this).hasClass('disabled') || next(true);
			});

			init();
		});
	};
})();

$.browser.msie && 7 >= parseInt($.browser.version) && $(function() {
	$('#content .line_gallery .arrow').hover(function() {
		$(this).addClass('hover')
			.find('ins').css('left', 1).css('left', '');
	}, function() {
		$(this).removeClass('hover')
			.find('ins').css('left', 1).css('left', '');
	});
});

isCanvas && (Element.prototype.attr = function(name, value) {
	function getName(name) {
		var
			splitterIndex = name.indexOf(':'),
			ns = '',
			attr = '';

		if (-1 < splitterIndex) {
			var s = splitterIndex;

			while (-1 < s) {
				splitterIndex = s;
				s = name.indexOf(':', s + 1);
			}

			ns = name.substr(0, splitterIndex);
			attr = name.substr(splitterIndex + 1);
		} else {
			attr = name;
		}

		return [ns, attr];
	}

	if ('string' == typeof name && undefined !== value) {
		var aData = getName(name);
		'' == aData[0] ? this.setAttribute(aData[1], value) : this.setAttributeNS(aData[0], aData[1], value);
	} else if ('string' == typeof name && undefined === value) {
		var aData = getName(name);
		return '' == aData[0] ? this.getAttribute(aData[1]) : this.getAttributeNS(aData[0], aData[1]);
	} else {
		for (prop in name) {
			var aData = getName(prop);
			'' == aData[0] ? this.setAttribute(aData[1], name[prop]) : this.setAttributeNS(aData[0], aData[1], name[prop]);
		}
	}
});