var sidebarWidth = 50;
var columnWidth = 490;
var leftColumnWidth = 500; //clumnWidth+10px because of margin-left
var maxColumns = 4;
var sortedCards = [];
var $hiddenCards; // cards that are currently hidden and ignored by columns
var resizeAnimationLength = 200; //ms
var delayOnResize = 200; //ms, delay to split and center cards on resize, reduces js activity

var cols = 1;
var cardCount = 0;
var resizeTimeout = null;

//because of firefox bug, if 2 iframes are loaded in same page, both are displayed with same content.
// So fade out "like-button":
if ($(".contentiframe").length) {
	if($.browser.mozilla) {
	var userAgent = navigator.userAgent.toLowerCase();
		if(navigator.userAgent.toLowerCase().indexOf('firefox') != -1) {
			$("#facebooklike").remove();
		}
	}
}

/* ----------------- */
/* LAZY IMAGE LOADER */
/* ----------------- */

$(window).load(function() {
	var images = $('.lazyimg').toArray();
	
	var current = 0, count = images.length;

	var lazyload = function() {
		if (current >= count) {
			return;
		}

		var img = images[current++];
		img.onload = img.onerror = lazyload;
		img.src = $(img).metadata().src;
	};

	// start lazyloading
	lazyload();
});

// Facebook I-Like-Button
$(window).load(function() {
	var container = $('#ilike');
	var iframe = $('<iframe>', {
		id: 'facebooklike',
		name: 'facebooklike',
		src: 'http://www.facebook.com/plugins/like.php?href=' + container.metadata().href + '&layout=button_count&show_faces=false&width=90&action=like&font=lucida%2Bgrande&colorscheme=light&height=29',
		scrolling: 'no',
		frameborder: '0',
		css: {
			border: 'none',
			overflow: 'hidden',
			width: 90,
			height: 29
		},
		allowtransparency: 'true'
	}).appendTo(container);
});

/* ---------- */
/* GRID STYLE */
/* ---------- */

$(document).ready(function () {
	hideCard($('#cardcolumn1').find('.hiddencard').removeClass('hiddencard'));

	// cards get ids in order to sort them
	sortedCards = $("#cards .cardcolumn .card").toArray();
	
	var div = $('<div>', {css: {position: 'fixed', top: '10px', left: 0}}).appendTo(document.body);
	var supportFixed = div[0].offsetTop === 10;
	div.remove();

	var checkFixed = $.noop;
	if (supportFixed) {
		checkFixed = function () {
			var $element = $('#linkline');
			var neededHeight = $element.outerHeight();
			if ($element.css('position') == 'fixed') {
				neededHeight += parseInt($element.css('top'), 10);
			} else {
				neededHeight += $element.position().top;
			}
			if ($(window).height() >= neededHeight) {
				$('#nav, #thesis, #linkline').css('position', 'fixed');
			} else {
				$('#nav, #thesis, #linkline').css('position', 'absolute');
			}
		}
	}

	// check if fixed positioning is possible
	checkFixed();

	//Resize event
	$(window).resize(function() {
		if (resizeTimeout != null) {
			window.clearTimeout(resizeTimeout);
			resizeTimeout = null;
		}
		resizeTimeout = window.setTimeout(splitCardsIntoColumns, delayOnResize);
		checkFixed();
	});

	//Split on load
	splitCardsIntoColumns();

});

function calculateColumnCount() {
	var mainwidth = $("#main").width();
	var winwidth = $(window).width();
	var contentwidth = mainwidth - sidebarWidth - leftColumnWidth; //width available for content cards

	// choose column count based on available space
	cols = Math.floor(contentwidth / columnWidth);

	// limit columns to half of card count
	/*
	var maxUsefulColumns = Math.ceil(cardCount / 2);
	if (cols > maxUsefulColumns) cols = maxUsefulColumns;
	*/
	if (cols < 1) cols = 1;
	if (cols > maxColumns) cols = maxColumns;

}

/* CENTER CONTENT */
function centerall() {
	var mainwidth = $("#main").width();
	var cardswidth = $("#cards").width();

	var spacing = mainwidth - sidebarWidth - leftColumnWidth - cardswidth;

	var newleft = spacing / 2;
	if (newleft < 0) newleft = 0;
	newleft += sidebarWidth;

	/* re-position */
	$("#nav").stop().animate({"left":newleft}, resizeAnimationLength);
	$("#thesis").stop().animate({"left":newleft}, resizeAnimationLength);
	$("#linkline").stop().animate({"left":newleft}, resizeAnimationLength);
	$("#cards").stop().animate({"left":newleft + leftColumnWidth}, resizeAnimationLength);

	// setting cookies to correct position directly on load
	$.cookie('setleft', newleft);
}

/* RE-SORT CARDS */
function splitCardsIntoColumns() {

	if (resizeTimeout != null) {
		window.clearTimeout(resizeTimeout);
		resizeTimeout = null;
	}

	calculateColumnCount();

	// create necessary columns
	for (var i = 1; i <= cols; i++) {
		var column = $('#cardcolumn' + i);
		if (!column.length) {
			$('#cards').append('<div id="cardcolumn' + i + '" class="cardcolumn"></div>');
		}
	}

	// move cards to destination column
	$.each(sortedCards, function(index) {
		var $card = $(this);
		$('#cardcolumn' + ((index % cols) + 1)).append($card); //+1 because cards start with id 0 not 1
	});

	// remove obsolete columns. If existing column has higher index than cols, remove it
	for (var i = maxColumns; i > cols; i--) {
		var column = $('#cardcolumn' + i);
		if (column.length) {
			column.remove();
		}
	}

	// adjust width of parent container (in order to center content)
	$('#cards').width(cols * columnWidth);

	//after splitting, center everything
	centerall();
}

/* -------------- */
/* FILTER OVERLAY */
/* -------------- */

$(document).ready(function () {
	$("#submit").remove(); //Hide non-js submit button

	$('input:checkbox').checkbox(); //init checkboxes
	$('input:radio').radio(); //init radio buttons

	/* on load: adapts text to checkboxes, when they are active -> text becomes #000 */
	window.setTimeout(updateactive, 200); //Delay on load to wait til checkboxes are ready

	/* on click on anything: adapts text to checkboxes, when they are active -> text becomes #000 */
	$("#filteroverlay fieldset *").each(function() {
		$(this).click(function() {
			window.setTimeout(updateactive, 80);
		});
	});

	var getoverlaypos = $("#filteroverlay").css("top");
	var ishidden = $("#filteroverlaywrap").hasClass("overlayhidden"); //Class indicates if box is open	or closed on load

	/* Toggle Box on load */

	if (ishidden==false) {
		$("#togglefilter").toggleClass("open");
		if ($("#togglefilter").hasClass("open")) {
			$("#filteroverlaywrap").css({"z-index":"3"});
			$("#filteroverlay").animate({"top":"0"},1000);
		}else{
			$("#filteroverlay").css({"top":getoverlaypos}, function() {
				$("#filteroverlaywrap").css({"z-index":"-1"});
			});
		}
	}

	if (ishidden==true) {
		$("#togglefilter").addClass("closed");
		$("#filteroverlaywrap").css({"z-index":"-1"});
	}

	/* Toggle Box */

	$("#togglefilter").click(function() {
		$(this).toggleClass("open");
		$(this).toggleClass("closed");
		if ($(this).hasClass("open")) {
			$("#filteroverlaywrap").css({"z-index":"3"});
			$("#filteroverlay").stop().animate({"top":"0"}, 1000);
		}else{
			$("#filteroverlay").stop().animate({"top":getoverlaypos}, 1000, function() {
				$("#filteroverlaywrap").css({"z-index":"-1"});
			});
		}
		return false;
	});

	/* Hover Checkbox */
	$("#filteroverlay .jquery-checkbox").each(function() {
		$(this).mouseenter(function() {
			$(this).parent().find(".label").addClass("hover");
		});

		$(this).mouseleave(function() {
			$(this).parent().find(".label").removeClass("hover");
		});
	});

	/* Hover Radiobutton */
	$("#filteroverlay .jquery-radio").each(function() {
		$(this).mouseenter(function() {
			$(this).parent().find(".label").addClass("hover");
		});
		$(this).mouseleave(function() {
			$(this).parent().find(".label").removeClass("hover");
		});
	});

	/* Hover Text */
	$("#filteroverlay .label").each(function() {
		$(this).mouseenter(function() {
			$(this).addClass("hover");
		});
		$(this).mouseleave(function() {
			$(this).removeClass("hover");
		});
	});

	cards.init();
});

/* adapts text to checkboxes, when they are active -> text becomes #000 */
function updateactive() {
	$(".jquery-checkbox").each(function () {
		var wasactiveonclick = $(this).hasClass("jquery-checkbox-checked");
		if(wasactiveonclick==true) {
			$(this).parent().addClass("active");
		}else{
			$(this).parent().removeClass("active");
		}
	});
	$(".jquery-radio").each(function () {
		var wasactiveonclick = $(this).hasClass("jquery-radio-checked");
		if(wasactiveonclick==true) {
			$(this).parent().addClass("active");
		}else{
			$(this).parent().removeClass("active");
		}
	});
}

function hideCard($card) {
	if (!$hiddenCards) {
		$hiddenCards = $('<div id="hiddencards">').hide().appendTo('#cards');
	}
	$card.appendTo($hiddenCards);
}

function showCard($card) {
	$card.appendTo('#cardcolumn1');
}
$('#actualize').click(function(event) {
	event.preventDefault();
	$(this).addClass('loading').closest('form').submit();
});
$("#filter input").bind('enable disable check uncheck', function() {
	// get all checked categories
	var getValue = function(element) {
		return parseInt(element.value, 10);
	};

	// read the form values
	var leistungen = $.map($('input[name=leistungen\[\]]:checked'), getValue);
	var branchen   = $.map($('input[name=branchen\[\]]:checked'), getValue);
	var order      = $('input[name=order]:checked').val();
	var view       = $('input[name=view]:checked').val();
	
	var $projects;
	
	var cardsOffset = $('#cards').offset();
	
	if (view == 'image') {
		// hide the text card
		hideCard($('#projectlist').closest('.card'));
		$projects = $('.projectcard');
	} else {
		hideCard($('.projectcard'));
		showCard($('#projectlist').closest('.card'));
		$projects = $('#projectlist > li');
	}
	
	var filterIds = [];
	if (leistungen.length) filterIds.push(leistungen);
	if (branchen.length) filterIds.push(branchen);

	var shownProjects = [];
	var $hiddenProjects = $();

	// first: filter the projects
	$projects.each(function() {
		var $project = $(this);
		var categories = $project.metadata().categories;
		
		var show = true;

		$.each(filterIds, function() {
			var match = false;
			$.each(this, function(index, category) {
				if ($.inArray(category, categories) > -1) {
					match = true;
					return false;
				}
			});
			if (!match) {
				$hiddenProjects = $hiddenProjects.add($project);
				show = false;
				return false;
			}
		});
		
		if (show) {
			shownProjects.push($project);
		}
	});

	// now all cards are in card column1, sort them
	shownProjects.sort(function(card1, card2) {
		var sort1 = card1.metadata().sort[order];
		var sort2 = card2.metadata().sort[order];
		if (sort1 > sort2) {
			return 1;
		}
		if (sort1 < sort2) {
			return -1;
		}
		return 0;
	});

	if (view == 'image') {
		hideCard($hiddenProjects);
	} else {
		$hiddenProjects.hide();
	}

	var $noprojects = $('.noprojects');
	if (shownProjects.length) {
		if (view == 'image') {
			sortedCards = shownProjects;
		} else {
			var $projectlist = $('#projectlist');
			sortedCards = $projectlist.closest('.card');
			$.each(shownProjects, function() {
				$(this).show().appendTo($projectlist);
			});
		}
		hideCard($noprojects);
	} else {
		sortedCards = [$noprojects];
		hideCard($('#projectlist').closest('.card'));
	}

	splitCardsIntoColumns();
});

var cards = {

	init : function() {
		cards._initDynamicCards();
		cards._initCardOverlays();
	},


	/* public methods - dynamic cards */

	openCard : function(node) {
		cards._openCloseCard(node, true);
		return false;
	},
	closeCard : function(node) {
		cards._openCloseCard(node, false);
		return false;
	},

	/* protected methods - dynamic cards */

	_initDynamicCards : function() {
		$('.dynamiccard').each(function() {
			var dynamicCard = $(this);
			var cardContent = dynamicCard.find('.cardcontent');
			var cardText = dynamicCard.find('.cardtext');
			var contentFadeout = dynamicCard.find('.contentfadeout');

			if (cardContent.length != 1 || cardText.length != 1 || contentFadeout.length != 1) return;

			var openedHeight = cardContent.innerHeight();
			dynamicCard.addClass('closedcard');
			var closedHeight = cardContent.innerHeight();
			if (openedHeight > closedHeight && openedHeight < closedHeight + 10) {
				// convert dynamic card to staticcard if only a little bit larger than allowed (which effectivly disables the fade-out)
				dynamicCard.removeClass('closedcard');
				dynamicCard.removeClass('dynamiccard');
				dynamicCard.addClass('staticcard');
			} else if (openedHeight <= closedHeight) {
				// remove dynamic attributes for cards with fewer content than height of the card
				dynamicCard.removeClass('closedcard');
			} else {
				cardContent.data('closedHeight', closedHeight);
				cardContent.data('openedHeight', openedHeight);
				var closedTop = parseInt(contentFadeout.css('top'));
				contentFadeout.data('closedTop', closedTop);
				contentFadeout.data('openedTop', closedTop + openedHeight - closedHeight);
			}
		});
	},

	_openCloseCard : function(node, opening) {
		var buttonDiv = $(node).closest(opening ? '.opencard' : '.closecard');
		var dynamicCard = buttonDiv.closest('.cardtype');
		var cardContent = dynamicCard.find('.cardcontent');
		var cardText = dynamicCard.find('.cardtext');
		var contentFadeout = dynamicCard.find('.contentfadeout');

		var from = cardContent.data(opening ? 'closedHeight' : 'openedHeight');
		var to   = cardContent.data(opening ? 'openedHeight' : 'closedHeight');
		var fromFadeout = contentFadeout.data(opening ? 'closedTop' : 'openedTop');
		var toFadeout   = contentFadeout.data(opening ? 'openedTop' : 'closedTop');

		cardContent.height(from);
		contentFadeout.css('top', fromFadeout);
		dynamicCard.removeClass(opening ? 'closedcard' : 'openedcard');

		var fadeoutOffset = fromFadeout - from;

		cardContent.animate({height: to}, {
			duration: cards._getDuration(from, to),
			complete: (opening ? cards._openingCardFinished : cards._closingCardFinished),
			step: function(pos) {
				contentFadeout.css('top', pos + fadeoutOffset);
			}
		});
	},

	_openingCardFinished : function() {
		$(this).closest('.cardtype').addClass('openedcard');
	},
	_closingCardFinished : function() {
		$(this).closest('.cardtype').addClass('closedcard');
	},

	_getDuration : function(from, to) {
		var maxSinoidal = 1000;  // pixel
		var maxSinoidalDuration = 2500;  // miliseconds
		var maxSpeed = 500;  // pixel/seconds
		var minDuration = 800;  // miliseconds

		var delta = (from > to ? from - to : to - from);
		var duration = minDuration;
		if (delta > maxSinoidal) {
			duration += delta / maxSpeed / 1000;
		} else {
			var fraction = delta / maxSinoidal;
			var sinoidal = (-Math.cos(fraction * Math.PI) / 2) + 0.5;
			duration += maxSinoidalDuration * sinoidal;
		}
		return duration;
	},

	/* protected methods - card overlays */

	_initCardOverlays : function() {
		$('.overlay:not(.static)').each(function() {
			var cardOverlay = this;

			var cardContent = $(this).closest('.cardcontent');
			cardContent.bind('mouseenter', {enter: true}, cards._enterLeaveCard);
			cardContent.bind('mouseleave', {enter: false}, cards._enterLeaveCard);
		});
	},

	_enterLeaveCard : function(event) {
		var opening = event.data.enter;
		var cardOverlay = $(this).children('.overlay:first');
		if (!cardOverlay.data('overlayInit')) {
			var cardContent = cardOverlay.closest('.cardcontent');
			var overlayHeader = cardOverlay.find('.overlayheader');
			var overlayText = cardOverlay.find('.overlaytext');
			cardOverlay.data('overlayInit', true);
			cardOverlay.data('overlayHeight', cardOverlay.outerHeight());
			cardOverlay.data('overlayHeaderHeight', overlayHeader.outerHeight());
			cardOverlay.data('overlayTextHeight', overlayText.outerHeight());

			// move overlay to initial start position on first action
			var overlayHeight = cardOverlay.outerHeight();
			cardOverlay.css('bottom', -overlayHeight);
		}

		var canceledPrevious = cardOverlay.is(':animated');
		cardOverlay.stop(true); // stop previous animations

		var from = parseInt(cardOverlay.css('bottom'));
		var to = (opening ? 0 : -cardOverlay.data('overlayHeight'));
		if (to == from) return;

		var delay = (canceledPrevious ? 0.0 : (opening ? 300 : 100));
		if (opening) {
			var via = cardOverlay.data('overlayHeaderHeight') - cardOverlay.data('overlayHeight');
			var duration = 0;
			if (cardOverlay.data('overlayHeaderHeight') && from < via) {
				duration = cards._getOverlayDuration(from, to, true);
				cardOverlay.delay(delay).animate({bottom: via}, duration);
				delay = 0;
				from = via;
			}
			if (cardOverlay.data('overlayTextHeight') && from < to) {
				cardOverlay.delay(duration).animate({bottom: to}, cards._getOverlayDuration(from, to, true));
			}

		} else {
			cardOverlay.delay(delay).animate({bottom: to}, cards._getOverlayDuration(from, to, false));
		}
	},

	_getOverlayDuration : function(from, to, header) {
		var maxSinoidal = 1000;  // pixel
		var maxSinoidalDuration = 2500;  // miliseconds
		var maxSpeed = 500;  // pixel/seconds
		var minDuration = (header ? 300 : 800);  // miliseconds

		var delta = (from > to ? from - to : to - from);
		var duration = minDuration;
		if (delta > maxSinoidal) {
			duration += delta / maxSpeed / 1000;
		} else {
			var fraction = delta / maxSinoidal;
			var sinoidal = (-Math.cos(fraction * Math.PI) / 2) + 0.5;
			duration += maxSinoidalDuration * sinoidal;
		}
		return duration;
	}
};

