(function($) {
	var getTargetPos = function (container) {
		var targets = container.data('targets');
		var width = container.width() - (66*2);
		
		if (width < 920) width = 920;
		else if (width > 920) width = 1200;
		var matrix = [[0,width,0]];
		var maxWidth = 0;
		var maxHeight = 0;
		
		targets.each(function(i) {
			var target = $(this);
			var size = getSize($(target));
			var point = getAttachPoint(matrix, size[0]);
			
			matrix = updateAttachArea(matrix, point, size);
			maxWidth = Math.max(maxWidth, point[0]+size[0]);
			maxHeight = Math.max(maxHeight, point[1]+size[1]);
			
			target.data('leftpos', point[0]);
			target.data('toppos', point[1]);
		});
		
		container.data('containerMaxWidth', maxWidth);
		container.data('containerMaxHeight', maxHeight);
		updateContainerSize(container);
	};
	
	var getAttachPoint = function (m, width) {
		var m = m.concat([]).sort(matrixSortDepth);
		var max = m[m.length - 1][2];
		
		for(var i=0, imax=m.length; i<imax; i++) {
			if(m[i][2] >= max) break;
			if(m[i][1] - m[i][0] >= width) {
				return ([m[i][0], m[i][2]]);
			}
		}
		
		return ([0, max]);
	};
	
	var updateAttachArea = function (m, point, size) {
		var m = m.concat([]).sort(matrixSortDepth);
		var cell = [point[0], point[0] + size[0], point[1] + size[1]];
		
		for(var i=0,imax=m.length; i<imax; i++) {
			if(cell[0] <= m[i][0] && m[i][1] <= cell[1]) {
				delete m[i];
			}
			else {
				m[i] = matrixTrimWidth(m[i], cell);
			}
		}
		
		return (matrixJoin(m, cell));
	};
	
	var matrixSortDepth = function (a, b) {
		return (((a[2] == b[2] && a[0] > b[0]) || a[2] > b[2]) ? 1 : -1);
	};
	
	var matrixSortX = function (a, b) {
		return ((a[0] > b[0]) ? 1 : -1);
	};
	
	var matrixJoin = function (m, cell) {
		var m = m.concat([cell]).sort(matrixSortX);
		var joined = [];
		
		for(var i=0,imax=m.length; i<imax; i++) {
			if(!m[i]) continue;
			if(joined.length > 0 && 
			   joined[joined.length - 1][1] == m[i][0] && 
			   joined[joined.length - 1][2] == m[i][2]) {
				joined[joined.length - 1][1] = m[i][1];
			}
			else {
				joined.push(m[i]);
			}
		}
		
		return (joined);
	};
	
	var matrixTrimWidth = function (a, b) {
		if(a[0] >= b[0] && a[0] < b[1] || a[1] >= b[0] && a[1] < b[1]) {
			if(a[0] >= b[0] && a[0] < b[1]) {
				a[0] = b[1];
			}
			else {
				a[1] = b[0];
			}
		}
		return (a);
	};
	
	var getSize = function (target) {
		var width = target.width();
		var height = target.height();
		
		width += Number(target.css('margin-left').replace('px', ''))
			+Number(target.css('padding-left').replace('px', ''))
			+Number(target.get(0).style.borderLeftWidth.replace('px', ''))
			+Number(target.css('margin-right').replace('px', ''))
			+Number(target.css('padding-right').replace('px', ''))
			+Number(target.get(0).style.borderRightWidth.replace('px', ''));
			
		height += Number(target.css('margin-top').replace('px', ''))
			+Number(target.css('padding-top').replace('px', ''))
			+Number(target.get(0).style.borderTopWidth.replace('px', ''))
			+Number(target.css('margin-bottom').replace('px', ''))
			+Number(target.css('padding-bottom').replace('px', ''))
			+Number(target.get(0).style.borderBottomWidth.replace('px', ''));
		
		return ([width, height]);
	};
	
	var updateContainerSize = function (container) {
		var delay = container.data('targets').length * (container.data('params').delay || 0) + container.data('params').time || 500;
		container.stop();
		
		if(container.height() < container.data('containerMaxHeight')) {
			if($.browser.msie) container.height(container.data('containerMaxHeight') + 90);
			else {
				container.animate({
						height: container.data('containerMaxHeight') + 90 + 'px'
					},
					(container.data('params').time || 500),
					'easeOutQuart'
				);
			}
		}
		else {
			clearTimeout(container.data('containerHeightTimeout'));
			container.data('containerHeightTimeout', setTimeout(function(){
				if($.browser.msie) container.height(container.data('containerMaxHeight') + 90);
				else {
					container.animate({
							height: container.data('containerMaxHeight') + 90 + 'px'
						},
						(container.data('params').time || 500),
						'easeOutQuart'
					);
				}
			}, delay));
		}
	};
	
	var targetAnimateToNewPos = function (targets, offsetX, easeing, time, delay) {
		targets.each(function(i) {
			var target = $(this);
			clearTimeout(target.data('timeout'));
			
			target.data('timeout', setTimeout(function() {
				target.animate({
					left: target.data('leftpos') + offsetX + 'px',
					top: target.data('toppos') + 45 + 'px'
				}, time, easeing);
			}, i * delay));
		});
	};
	
	var targetAnimateToFade = function (targets, shuffledNums, offsetX, easeing, time, delay) {
		targets.each(function(i) {
			var target = $(this);
			clearTimeout(target.data('timeout'));
			
			target.css({
				//'visibility':'visible', 
				//'display':'none', 
				//'display':'block', 
				'top':target.data('toppos') + 45 + 'px',
				'left':target.data('leftpos') + offsetX + 'px'
			});
				
			target.data('timeout', setTimeout(function() {
				target.fadeIn(800);
				//target.animate({
				//	opacity: 1
				//}, 800, easeing);
			}, shuffledNums[i] * 200));
		});
	};
	
	var updatePosition = function (container, delay) {
		clearTimeout(container.data('timeout'));
		getTargetPos(container);
		
		var offsetX = (container.width() - container.data('containerMaxWidth'))/2;
		
		container.data('timeout', setTimeout(function() {
			targetAnimateToNewPos(
				container.data('targets'),
				offsetX,
				container.data('params').easeing || 'linear',
				container.data('params').time || 500,
				container.data('params').delay || 0
			);
		}, delay||200));
	};
	
	var initPosition = function (container, delay) {
		//clearTimeout(container.data('timeout'));
		getTargetPos(container);
		
		var offsetX = (container.width() - container.data('containerMaxWidth'))/2;
		var numbers = new Array();
		for (var i=0; i<container.data('targets').length; i++) {
			numbers.push(i);
		}
		
		var shuffledNums = shuffle(numbers);
		var t = setTimeout(function() {
			targetAnimateToFade(
				container.data('targets'),
				shuffledNums, 
				offsetX,
				container.data('params').easeing || 'linear',
				container.data('params').time || 2000,
				container.data('params').delay || 0
			);
		}, delay||200);
		//container.data('timeout', t);
		
		$('#header').fadeIn(4000);
		$('#footer').fadeIn(2000);
	};
	
	var shuffle =  function(list) {
		var n = list.length;
		
		while (n--) {
			var i = Math.floor(Math.random() * (n + 1));
			var t = list[n];
			list[n] = list[i];
			list[i] = t;
		}
		
		return (list);
	}
	
	$.fn.extend({
		grid: function(option) {
			var container = $(this);
			var params = option || {};
			
			var left = Math.floor(($(window).width() - $("#loading").width()) / 2);  
   	 		var top  = Math.floor(($(window).height() - $("#loading").height()) / 2);
    		
			$('#loading').css({'display':'block', 'zIndex':'1000', 'position':'absolute', 'top':top+'px', 'left':left+'px'});
			$('#header').css('display', 'none');
			$('#footer').css('display', 'none');
			$('#shadow1, #shadow2').css({'zIndex':'1000', 'position':'absolute'}).hide();
			
			container.data('params', params);
			container.data('targets', container.find('> .target'));
			
			container.css({'position':'relative', 'width':'auto'});
			
			//container.data('targets').css({opacity: 0, 'position':'absolute', 'cursor':'pointer'});
			container.data('targets').css({'position':'absolute', 'cursor':'pointer'});
			
			container.data('targets').hover(
				function(){
					var has = $(this).hasClass('nofocus');
					if (has) return;
					
					var pos = $(this).position();
					var cname = '';
					
					var has2 = $(this).hasClass('gap');
					if (has2) cname = '#shadow1';
					else cname = '#shadow2';
					$(this).append($(cname));
					$(cname).css({'top':'11px', 'left':'11px', 'display':'block'});
					$(cname).show();
				},
				function(){
					var has = $(this).hasClass('nofocus');
					if (has) return;
					
					has = $(this).hasClass('gap');
					if (has) cname = '#shadow1';
					else cname = '#shadow2';
					$(cname).hide();
					$(cname).css({'display':'none'});
				}
			).click(
				function() {
					if ($(this).hasClass('nofocus')) return;
					location.href = $(this).find('a').attr('href');
				}
			);
			$(window).resize(function(event) {
				updatePosition(container);
			});
			setTimeout(function() {
			$('#loading').fadeOut('slow', function(){
					initPosition(container, 1000);
			});
			}, 1000);
/*			
			$(window).resize(function(event) {
				updatePosition(container);
			});
			setTimeout(function() {
			$('#loading').fadeOut('500', function(){
					initPosition(container, 500);
			});
			}, 500);
//			initPosition(container, 0);
*/
			return (container);
		}
	});
})(jQuery);

$(function(){
	$("#content").grid({
		easeing: "easeOutQuint",
		time: 400,
		delay: 200
	});
});
/*
$(document).ready(function() {
	$("#content").grid({
		easeing: "easeOutQuint",
		time: 400,
		delay: 200
	});
});
*/
var trace = function(arg) {
	console.log(arg);
}

