/**
 * @author Vlad Yakovlev (red.scorpix@gmail.com)
 * @link http://www.scorpix.ru
 * @version 0.1.1 (2005-09-17)
 * @requires jQuery
 */
(function() {

	var browserType = 800 < screen.availWidth ? 'normal' : 'mobile';

	if ('normal' == browserType) {
		$(function() {
			$('#navigation').removeClass('hidden');
		});
	}

	$(function() {

		var mondrian = (function() {
			var
				numberMistake = 0.001,
				interval = 4,
				imagesSrc = [
					[ './i/b0_0.jpg', './i/b0_1.jpg', './i/b0_2.jpg', './i/b0_3.jpg', './i/b0_4.jpg', './i/b0_5.jpg' ],
					[ './i/b1_0.jpg', './i/b1_1.jpg', './i/b1_2.jpg', './i/b1_3.jpg', './i/b1_4.jpg', './i/b1_5.jpg' ],
					[ './i/b2_0.jpg', './i/b2_1.jpg', './i/b2_2.jpg', './i/b2_3.jpg', './i/b2_4.jpg', './i/b2_5.jpg' ],
					[ './i/b3_0.jpg', './i/b3_1.jpg', './i/b3_2.jpg', './i/b3_3.jpg', './i/b3_4.jpg', './i/b3_5.jpg' ],
					[ './i/b4_0.jpg', './i/b4_1.jpg', './i/b4_2.jpg', './i/b4_3.jpg', './i/b4_4.jpg', './i/b4_5.jpg' ],
					[ './i/b5_0.jpg', './i/b5_1.jpg', './i/b5_2.jpg', './i/b5_3.jpg', './i/b5_4.jpg', './i/b5_5.jpg' ],
					[ './i/b6_0.jpg', './i/b6_1.jpg', './i/b6_2.jpg', './i/b6_3.jpg', './i/b6_4.jpg', './i/b6_5.jpg' ],
					[ './i/b7_0.jpg', './i/b7_1.jpg', './i/b7_2.jpg', './i/b7_3.jpg', './i/b7_4.jpg', './i/b7_5.jpg' ],
					[ './i/b8_0.jpg', './i/b8_1.jpg', './i/b8_2.jpg', './i/b8_3.jpg', './i/b8_4.jpg', './i/b8_5.jpg' ],
					[ './i/b9_0.jpg', './i/b9_1.jpg', './i/b9_2.jpg', './i/b9_3.jpg', './i/b9_4.jpg', './i/b9_5.jpg' ],
					[ './i/b10_0.jpg', './i/b10_1.jpg', './i/b10_2.jpg', './i/b10_3.jpg', './i/b10_4.jpg', './i/b10_5.jpg' ],
					[ './i/b11_0.jpg', './i/b11_1.jpg', './i/b11_2.jpg', './i/b11_3.jpg', './i/b11_4.jpg', './i/b11_5.jpg' ],
					[ './i/b12_0.jpg', './i/b12_1.jpg', './i/b12_2.jpg', './i/b12_3.jpg', './i/b12_4.jpg', './i/b12_5.jpg' ],
					[ './i/b13_0.jpg', './i/b13_1.jpg', './i/b13_2.jpg', './i/b13_3.jpg', './i/b13_4.jpg', './i/b13_5.jpg' ]
				];

			var blocks = $('.block');

			var
				positions = [],
				matrix = [],
				lines = {},
				minPos,
				maxPos,
				startMouse,
				startPos,
				isDndVer,
				dndLine,
				dndPrevIndexes,
				dndNextIndexes,
				winWidth,
				winHeight,
				images = [],
				prefix = './i/b',
				suffix = '.jpg',
				sectionsStates = [];

			init();

			function init() {
				loadImages();
				$(window).resize(onResize).resize();
				update();
			}

			function loadImages() {
				for (var i = 0; i < imagesSrc.length; i++) {
					images[i] = [];
					sectionsStates[i] = 0;

					for (var j = 0; j < imagesSrc[i].length; j++) {
						images[i][j] = new Image();
						images[i][j].onload = function() {};
						images[i][j].src = imagesSrc[i][j];
					}
				}

				blocks.each(function(index) {
					$(this).click(function() {
						changeState(index);
					});
				});
				blocks.find('img').mousedown(function(evt) {
					if (isDnd) return;

					evt.preventDefault();
					evt.stopPropagation();

					return false;
				});
			}

			function changeState(index) {
				var curState = sectionsStates[index];

				curState = curState + 1 >= imagesSrc[index].length ? 0 : curState + 1;
				sectionsStates[index] = curState;
				blocks.eq(index).find('img').attr('src', images[index][curState].src);
			}

			function onResize() {
				winWidth = $(window).width(),
				winHeight = $(window).height();

				if ($.browser.msie || $.browser.opera) {
					blocks.each(function() {
						correctBlock($(this));
					});
				}
			}

			function correctBlock(el) {
				var
					child = el.find('.wrap'),
					top = parseInt(child.css('top')),
					left = parseInt(child.css('left')),
					right = parseInt(child.css('right')),
					bottom = parseInt(child.css('bottom')),
					width = el.width(),
					height = el.height();

				el.find('img').css({
					height: height - top - bottom,
					width: width - left - right
				});
			}

			function update() {
				updatePositions();
				updateMatrix();
				updateLines();
			}

			function updatePositions() {

				positions = [];

				blocks.each(function() {
					var el = $(this);
					var offset = el.offset();

					positions.push({
						left: Math.round(offset.left / winWidth * 100),
						top: Math.round(offset.top / winHeight * 100),
						height: Math.round(el.height() / winHeight * 100),
						width: Math.round(el.width() / winWidth * 100)
					});

					if ($.browser.msie || $.browser.opera) {
						correctBlock(el);
					}
				});
			}

			function updateMatrix() {
				var
					leftPoses = {},
					topPoses = {},
					leftBorders = [],
					topBorders = [];

				/**
				 * Ищем горизонтальные и вертикальные границы, чтобы узнать размер матрицы и поставить туда
				 * ссылки на индексы элементов.
				 */
				for (var i = 0; i < positions.length; i++) {
					var pos = positions[i];

					if (undefined === leftPoses[pos.left]) {
						leftBorders.push(pos.left);
						leftPoses[pos.left] = 1;
					}
					if (undefined === topPoses[pos.top]) {
						topBorders.push(pos.top);
						topPoses[pos.top] = 1;
					}
				}

				leftBorders = leftBorders.sort(sortNumbers);
				topBorders = topBorders.sort(sortNumbers);

				/** Создаем матрицу. */
				matrix = [];

				for (var i = 0; i < leftBorders.length; i++) {
					var row = [];

					for (var j = 0; j < topBorders.length; j++) {
						row.push(-1);
					}

					matrix.push(row);
				}

				/** Заполняем матрицу индексами блоков. */
				for (var i = 0; i < positions.length; i++) {
					var
						pos = positions[i],
						minLeft = pos.left,
						maxLeft = pos.left + pos.width,
						minTop = pos.top,
						maxTop = pos.top + pos.height,
						lefts = [],
						tops = [];

					for (var j = 0; j < leftBorders.length; j++) {
						var l1 = compareNumbers(leftBorders[j], minLeft);
						var l2 = compareNumbers(leftBorders[j], maxLeft);

						-1 < l1 && 0 > l2 && lefts.push(j);
					}

					for (var j = 0; j < topBorders.length; j++) {
						var t1 = compareNumbers(topBorders[j], minTop);
						var t2 = compareNumbers(topBorders[j], maxTop);

						-1 < t1 && 0 > t2 && tops.push(j);
					}

					for (var j = 0; j < lefts.length; j++) {
						for (var k = 0; k < tops.length; k++) {
							matrix[lefts[j]][tops[k]] = i;
						}
					}
				}
			}

			function updateLines() {

				$('.line').remove();

				/** Создаем вертикальные линии */
				for (var i = 0; i < matrix.length - 1; i++) {
					var
						minIndex = 0,
						curIndex = 0,
						prevIndexes = {},
						nextIndexes = {};

					while (curIndex < matrix[i].length) {
						if (matrix[i][curIndex] == matrix[i + 1][curIndex]) {
							curIndex++;
							minIndex = curIndex;

							continue;
						}

						prevIndexes[matrix[i][curIndex]] = 1;
						nextIndexes[matrix[i + 1][curIndex]] = 1;

						if (curIndex < matrix[i].length - 1) {
							if (matrix[i][curIndex] == matrix[i][curIndex + 1] || matrix[i + 1][curIndex] == matrix[i + 1][curIndex + 1]) {
								curIndex++;

								continue;
							}
						}

						var
							prevClass = ['prev'],
							nextClass = ['next'];

						for (var index in prevIndexes) {
							prevClass.push(index);
						}
						for (var index in nextIndexes) {
							nextClass.push(index);
						}

						createLine({
							height: (positions[matrix[i][curIndex]].top + positions[matrix[i][curIndex]].height - positions[matrix[i][minIndex]].top) + '%',
							left: positions[matrix[i + 1][minIndex]].left + '%',
							top: positions[matrix[i][minIndex]].top + '%'
						}, 'line line_ver ' + prevClass.join('_') + ' ' + nextClass.join('_'));

						curIndex++;
						minIndex = curIndex;
						prevIndexes = {};
						nextIndexes = {};
					}
				}

				/** Создаем горизонтальные линии */
				for (var i = 0; i < matrix[0].length - 1; i++) {
					var
						minIndex = 0,
						curIndex = 0,
						prevIndexes = {},
						nextIndexes = {};

					while (curIndex < matrix.length) {
						if (matrix[curIndex][i] == matrix[curIndex][i + 1]) {
							curIndex++;
							minIndex = curIndex;

							continue;
						}

						prevIndexes[matrix[curIndex][i]] = 1;
						nextIndexes[matrix[curIndex][i + 1]] = 1;

						if (curIndex < matrix.length - 1) {
							if (matrix[curIndex][i] == matrix[curIndex + 1][i] || matrix[curIndex][i + 1] == matrix[curIndex + 1][i + 1]) {
								curIndex++;

								continue;
							}
						}

						var
							prevClass = ['prev'],
							nextClass = ['next'];

						for (var index in prevIndexes) {
							prevClass.push(index);
						}
						for (var index in nextIndexes) {
							nextClass.push(index);
						}

						createLine({
							left: positions[matrix[minIndex][i]].left + '%',
							top: positions[matrix[minIndex][i + 1]].top + '%',
							width: (positions[matrix[curIndex][i]].left + positions[matrix[curIndex][i]].width - positions[matrix[minIndex][i]].left) + '%'
						}, 'line line_hor ' + prevClass.join('_') + ' ' + nextClass.join('_'));

						curIndex++;
						minIndex = curIndex;
						prevIndexes = {};
						nextIndexes = {};
					}
				}

				if ($.browser.msie && 6 >= parseInt($.browser.version)) {
					$('.line').hover(function() {
						$(this).addClass('hover');
					}, function() {
						$(this).removeClass('hover');
					});
				}
			}

			function createLine(css, className) {
				//if (undefined === lines[className]) {
					$('<span></span>').css(css).addClass(className).appendTo('#main').mousedown(startDnd);
				//}
			}

			function startDnd(evt) {

				isDnd = true;

				dndLine = $(evt.target);
				isDndVer = dndLine.hasClass('line_ver');
				$('.line').not(dndLine).remove();
				dndPrevIndexes = getIndexes(dndLine, 'prev_');
				dndNextIndexes = getIndexes(dndLine, 'next_');

				var
					maxFromPrev = 0,
					minFromNext = 10000,
					lineOffset = dndLine.offset();

				if (isDndVer) {

					for (var i = 0; i < dndPrevIndexes.length; i++) {
						var index = dndPrevIndexes[i];

						if (maxFromPrev < positions[index].left) {
							maxFromPrev = positions[index].left;
						}
					}
					for (var i = 0; i < dndNextIndexes.length; i++) {
						var index = dndNextIndexes[i];

						if (minFromNext > positions[index].left + positions[index].width) {
							minFromNext = positions[index].left + positions[index].width;
						}
					}

					startMouse = parseInt(evt.pageX);
					startPos = lineOffset.left;
					startPos = Math.round(parseInt(dndLine.css('left')) / 100 * winWidth);
				} else {
					for (var i = 0; i < dndPrevIndexes.length; i++) {
						var index = dndPrevIndexes[i];

						if (maxFromPrev < positions[index].top) {
							maxFromPrev = positions[index].top;
						}
					}
					for (var i = 0; i < dndNextIndexes.length; i++) {
						var index = dndNextIndexes[i];

						if (minFromNext > positions[index].top + positions[index].height) {
							minFromNext = positions[index].top + positions[index].height;
						}
					}

					startMouse = parseInt(evt.pageY);
					startPos = lineOffset.top;
					startPos = Math.round(parseInt(dndLine.css('top')) / 100 * winHeight);
				}

				dndLine.addClass('hover');
				minPos = maxFromPrev + interval;
				maxPos = minFromNext - interval;

				if ('mobile' == browserType) {
					$(document).mousedown(mobileDnd);
				} else {
					$(document).mousemove(dnd).mouseup(stopDnd);
				}

				evt.stopPropagation();
				evt.preventDefault();
			}

			function mobileDnd(evt) {
				dnd(evt);
				stopDnd();
			}

			function dnd(evt) {

				var
					moved = isDndVer ? parseInt(evt.pageX) - startMouse : parseInt(evt.pageY) - startMouse,
					curPos = startPos + moved,
					isStop = false;

				if (isDndVer) {
					if (curPos < minPos / 100 * winWidth) {
						curPos = Math.ceil(minPos / 100 * winWidth);
						isStop = true;
					}
					if (curPos > maxPos / 100 * winWidth) {
						curPos = Math.floor(maxPos / 100 * winWidth);
						isStop = true;
					}

					moved = curPos - startPos;
					moved = Math.round(moved / winWidth * 100);

					for (var i = 0; i < dndPrevIndexes.length; i++) {
						var index = dndPrevIndexes[i];
						blocks.eq(index).css('width', (positions[index].width + moved) + '%');
						
						if ($.browser.msie || $.browser.opera) {
							correctBlock(blocks.eq(index));
						}
					}
					for (var i = 0; i < dndNextIndexes.length; i++) {
						var index = dndNextIndexes[i];
						blocks.eq(index).css({
							left: (positions[index].left + moved) + '%',
							width: (positions[index].width - moved) + '%'
						});
						
						if ($.browser.msie || $.browser.opera) {
							correctBlock(blocks.eq(index));
						}
					}
					dndLine.css('left', (Math.round(startPos / winWidth * 100) + moved) + '%');
				} else {
					if (curPos < minPos / 100 * winHeight) {
						curPos = Math.ceil(minPos / 100 * winHeight);
						isStop = true;
					}
					if (curPos > maxPos / 100 * winHeight) {
						curPos = Math.floor(maxPos / 100 * winHeight);
						isStop = true;
					}

					moved = curPos - startPos;
					moved = Math.round(moved / winHeight * 100);

					for (var i = 0; i < dndPrevIndexes.length; i++) {
						var index = dndPrevIndexes[i];
						blocks.eq(index).css('height', (positions[index].height + moved) + '%');
						
						if ($.browser.msie || $.browser.opera) {
							correctBlock(blocks.eq(index));
						}
					}
					for (var i = 0; i < dndNextIndexes.length; i++) {
						var index = dndNextIndexes[i];
						blocks.eq(index).css({
							height: (positions[index].height - moved) + '%',
							top: (positions[index].top + moved) + '%'
						});
						
						if ($.browser.msie || $.browser.opera) {
							correctBlock(blocks.eq(index));
						}
					}
					dndLine.css('top', (Math.round(startPos / winHeight * 100) + moved) + '%');
				}

				evt.stopPropagation();
				evt.preventDefault();

				if ('mobile' != browserType) {
					isStop && stopDnd();
				}
			}

			function stopDnd() {
				dndLine.removeClass('hover');

				if ('mobile' == browserType) {
					$(document).unbind('mousedown', mobileDnd);
				} else {
					$(document).unbind('mousemove', dnd).unbind('mouseup', stopDnd);
				}

				isDnd = false;

				update();
			}

			function compareNumbers(a, b) {
				if (Math.abs(a - b) < numberMistake) return 0;

				return 0 < a - b ? 1 : -1;
			}

			function sortNumbers(a, b) {
				return a - b;
			}

			function getIndexes(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).split('_');
					}
				}

				return false;
			}
		})();

		var control = (function() {

			var navEl = $('#navigation');

			$('.hide').click(hideNav);
			$('.description').click(function() {
				return update('description');
			});
			$('.examples').click(function() {
				return update('examples');
			});
			$('.exhibition').click(function() {
				return update('exhibition');
			});
			$('.video').click(function() {
				return update('video');
			});
			$('#navigation .refresh').click(function() {
				window.location.reload();
			});

			function hideNav() {
				navEl.addClass('hidden');
				$('#navigation .selected_pseudo').click();

				return false;
			}

			function update(name) {
				var descEl = $('#' + name);

				if (descEl.hasClass('hidden')) {
					showSection(name);

					if ('exhibition' == name) {
						hideSection('examples');
					} else if ('examples' == name) {
						hideSection('exhibition');
					}
				} else {
					hideSection(name);
				}

				return false;
			}

			function hideSection(name) {
				var descEl = $('#' + name);
				descEl.addClass('hidden');
				$('.' + name).removeClass('selected_pseudo');
			}

			function showSection(name) {
				var descEl = $('#' + name);
				descEl.removeClass('hidden');
				$('.' + name).addClass('selected_pseudo');
			}
		})();
	});
})();