if(window.location.hash) {
	var newLocation = window.location.hash.replace('#','');
	window.location.href = window.location.href = newLocation;
}



;(function( $ ){
	$.fn.crossfade = function(_newElement, _settings, callback){
		var defaults = {
			duration: 1000,
			onFinish: function() {}
		};

		return this.each(function() {
			var settings = $.extend({}, defaults, _settings);

			var oldElement = $(this);
			var newElement = _newElement;
			newElement.hide();
			oldElement.parent().append(newElement);
			
			if($.browser.msie) {
				oldElement.find('*').fadeOut(settings.duration);
				newElement.find('*').fadeIn(settings.duration);
			} 
			
			oldElement.fadeOut(settings.duration, null, function() {
				$(this).remove();
				if(callback) callback();
			});
			newElement.fadeIn(settings.duration);
		});
		
	};
}(jQuery));

var fallbackNavigationActive = false;
var nLoadingElements = 0;
var loadingIndicator;
var preloadThreshold;
var loadingIndicatorNeedsUpdate = false;

fallbackNavigation = function(url) {
	if(!fallbackNavigationActive) {
		fallbackNavigationActive = true;
		window.setTimeout(function() {
			window.location.href = url;
		}, 500);
	}
}

updateLoadingIndicator = function() {
	// console.info('updateLoadingIndicator start ' + nLoadingElements);
	loadingIndicatorNeedsUpdate = false;
	if(nLoadingElements && nLoadingElements > 0) {
		$(loadingIndicator).stop(true).fadeIn();
	}	
	if(!nLoadingElements || nLoadingElements < 1) {
		$(loadingIndicator).stop(true).fadeOut();
	} 
	// console.info('updateLoadingIndicator end');
}
updateLoadingIndicatorDelayed = function() {
	if(loadingIndicatorNeedsUpdate) return;
	else {
		window.setTimeout(function() {updateLoadingIndicator();}, 500);
		loadingIndicatorNeedsUpdate = true;
	}
}
loading = function() {
	nLoadingElements++;
	updateLoadingIndicatorDelayed();
}
finishedLoading = function() {
	nLoadingElements--;
	updateLoadingIndicatorDelayed();
}



Slideshow = function() {
	var initialized = false;
	
	var images;
	var reflectionImages;

	var imageContainer;
	var reflectionImageContainer;
	
	var currentImage;
	var currentReflectionImage;
	var currentImageI;
	
	var nextButton;
	var prevButton;
		
		
	newHiddenImage = function(src) {
		var newImage = document.createElement('img');
		newImage.src = src;
		newImage = $(newImage);
		newImage.hide();
		return newImage;
	}
	
	goToImage = function(newImageI) {
		var newImage = newHiddenImage(images[newImageI]);
		var newReflectionImage = newHiddenImage(reflectionImages[newImageI]);
		
		currentImage.crossfade(newImage, {duration: 500});
		currentReflectionImage.crossfade(newReflectionImage, {duration: 500});

		currentImage = newImage;
		currentReflectionImage = newReflectionImage;
		currentImageI = newImageI;
	}
	
	previous = function() {
		goToImage(currentImageI > 0 ? currentImageI-1 : images.length-1);
	}
	
	next = function() {		
		goToImage((currentImageI + 1) % images.length);
	}
	
	this.init = function() {
		if(keyvisual_images.length < 2) return;
		
		// update local fields with global configuration variables
		images = keyvisual_images; 
		reflectionImages = keyvisual_images_reflections; 

		$.preload(
			images.concat(reflectionImages),
			{
				threshold: preloadThreshold,
				onFinish: function() {
					imageContainer = $('#imageContainer');
					reflectionImageContainer = $('#reflectionImageContainer')[0];

					currentImage = $('img', imageContainer);
					currentReflectionImage = $('img', reflectionImageContainer);
					currentImageI = 0;

					nextButton = $(document.createElement('div'));
					nextButton.addClass('slideshowNextButton');

					prevButton = $(document.createElement('div'));
					prevButton.addClass('slideshowPrevButton');

					imageContainer.append(nextButton);
					imageContainer.append(prevButton);

					nextButton.css('right', -27);
					prevButton.css('left', -27);
					
					prevButtonImageUrlCss = prevButton.css('background-image');
					nextButtonImageUrlCss = nextButton.css('background-image');

					prevButtonImageUrl = '/fileadmin/templates/main/img/icon_left.png';
					nextButtonImageUrl = '/fileadmin/templates/main/img/icon_right.png';

					$.preload(
						[
							prevButtonImageUrl,
							nextButtonImageUrl
						],
						{
							threshold: preloadThreshold,
							onFinish: function() {
								prevButton.animate({'left': 0});
								nextButton.animate({'right': 0});							
							},
							onRequest: function() {loading();},
							onComplete: function() {finishedLoading();}
						}
					)
					
					nextButton.click(function() {next()});
					prevButton.click(function() {previous();});

					initialized = true;
				},
				onRequest: function() {loading();},
				onComplete: function() {finishedLoading();}
			}
		);
	}
	
	this.stop = function() {
		if(this.initialized) {
			nextButton.remove();
			prevButton.remove();
			initialized = false;
		}
	}
}

animateBoxHeight = function(boxId, newHeight, callback) {
	var reflectionId = boxId + "Reflection";
	var box = $('#' + boxId);
	var reflection = $('#' + reflectionId);
	box.animate(
		{height: newHeight+16},
		{
			duration: 750,
			step: function(now, fx) {
				reflection.css({height: now});
			},
			complete: callback
		}
	);
}

collapseBox = function(boxId) {
	var box = $('#'+boxId);
	animateBoxHeight(boxId, 0);
	var arrow = $('.boxHeaderArrow', box);
	arrow.attr('src', '/fileadmin/templates/main/img/menu_container_top_arrow_upwards.gif');
	arrow.unbind();
	arrow.click(function() {expandBox(boxId)});
	box.attr('status', 'collapsed');
}

expandBox = function(boxId) {
	var box = $('#' + boxId);
	var content = $('.boxContent' , box);

	// determine content height
	content.css({height: 'auto'});
	var contentHeight = content.height();

	if(contentHeight) {
		animateBoxHeight(boxId, contentHeight, function() {
			box.attr('status', 'expanded');
			var arrow = $('.boxHeaderArrow', box);
			arrow.attr('src', '/fileadmin/templates/main/img/menu_container_top_arrow.gif');
			arrow.unbind();
			arrow.click(function() {collapseBox(boxId)});		
		});
	} else {
		hideBox(boxId);
	}
}

hideBox = function(boxId, callback) {
	animateBoxHeight(boxId, -16, callback);
	$('#' + boxId).attr('status', 'collapsed');
}



startOnLoadAnimations = function(callback) {
	expandBox('menuBox');
	expandBox('contentBox');

	var node = $('#mainContainer');
	var nodeHeightAuto = 405;
	node.css('height', 0);
	node.animate({
		height : nodeHeightAuto
	}, 750, null); 

	var reflectionImageContainer = $('#reflectionImageContainer');
	reflectionImageContainer.css({
		visibility: 'visible',
		position: 'absolute',
		top: -400
	});
	reflectionImageContainer.animate({
		top : 0
	}, 750, null, callback()); 
}


/** 
 * The image menu consists of a block of linked images 
 * (.imageMenu) and an optional list of text links. 
 * The images are invisible by default and 
 * only appear when they or a link with the same link 
 * are hovered over. 
 */
initializeImageMenu = function() {
	$('.imageMenu IMG').css({
		opacity: 0
	});
	
	$('.imageMenu A').each(function() {
		var href = this.href;
		
		// todo: check if there is a css statement which does this
		var linksInGroup = new Array();
		$('A').each(function() {
			if(this.href == href) {
				linksInGroup.push(this);
			}
		});
		linksInGroup = $(linksInGroup);
		
		var groupMouseOver = function() {
			$('.imageMenu .backgroundActive').stop(true).animate({
				opacity : 1
			});
			$('.imageMenu .backgroundInactive').stop(true).animate({
				opacity : 0
			});
			linksInGroup.each(function() {
				$(this).addClass('active');
				$('IMG', $(this)).stop(true).animate({
					opacity: 1
				});
			});
		};
		
		var groupMouseOut = function() {
			$('.imageMenu .backgroundActive').stop(true).animate({
				opacity : 0
			});
			$('.imageMenu .backgroundInactive').stop(true).animate({
				opacity : 1
			});
			linksInGroup.each(function() {
				$(this).removeClass('active');
				$('IMG', $(this)).stop(true).animate({
					opacity: 0
				});
			});
		};
		
		linksInGroup.each(function() {
			this.onmouseover = groupMouseOver;
			this.onmouseout = groupMouseOut;
		})
	});
}

registerLinkEventHandlers = function() {
	$('A').each(function() {
		var href = this.href;
		if(
			href 
			&& this.className != 'download'
			&& this.className != 'mail'
			&& this.className != 'external-link-new-window'
		) {
			this.onclick = function() {
				// if still loading, go directly to the new page
				if(nLoadingElements && nLoadingElements > 0) {
					fallbackNavigation(newUrl);
					return true;
				}
				
				window.History.pushState(null, null, href);
				// gotoPage(href);
				return false;
			}			
		} 
	});
}

crossfadeItems = function(newPage, duration, callback) {
	window.slideshow.stop();
	
	var nAnimationsFinished = 0;
	
	var itemsToCrossfade = [
		'#menuLevel3',
		'#mainContentContainer',
		'#imageContainer',
		'#reflectionImageContainer',
		'#metaMenu'
	]

	countFinishedActionAndCallBackIfAllComplete = function() {
		if(++nAnimationsFinished >= itemsToCrossfade.length) {
			if(callback) callback()
		}
	}

	/* crossfade items  */
	$.each(itemsToCrossfade, function(index, item) {
		$(item).crossfade($(item, newPage), {}, countFinishedActionAndCallBackIfAllComplete);
	});
}


replaceBoxContent_Content2Content = function(oldContentBox, newContentBox, duration) {
	if(oldContentBox.attr('status') == 'expanded') {
		oldContentBox.css({
			height: 'auto'
		});		
	}
	
	var oldContent = $('#boxContent');
	var newContent = $('#boxContent', newContentBox);
	var boxContentContainer = $('#boxContentContainer');
	
	$('#backLink').replaceWith($('#backLink', newContentBox));
			
	// fixate height of container
	boxContentContainer.css({'height': boxContentContainer.outerHeight()});				
	
	// fade out content
	oldContent.fadeOut(duration/3, function() {
		// replace content
		oldContent.replaceWith(newContent);

		//  content
		newContent.css({visibility: 'hidden'});

		boxContentContainer.animate(
			{height: newContent.outerHeight()}, 
			(duration/3), 
			null, 
			function(){
				// fade in new content
				newContent.hide();
				newContent.css({visibility: 'visible'});
				newContent.fadeIn(duration/3);
			}
		);			
	});
}

replaceBoxContent_Content2Empty = function(oldContentBox, newContentBox, duration) {
	hideBox('contentBox', function() {
		oldContentBox.replaceWith(newContentBox);
	});
}

replaceBoxContent_Empty2Content = function(oldContentBox, newContentBox, duration) {
	oldContentBox.replaceWith(newContentBox);
	newContentBoxAutoHeight = newContentBox.outerHeight();
	newContentBox.css({height: 0});
	expandBox('contentBox', newContentBoxAutoHeight);
}

/* 
 * replace contents in boxContentContainer 
 */
replaceBoxContent = function(newPage, duration) {
	var oldContentBox = $('#contentBox');
	var newContentBox = $('#contentBox', newPage);
	
	var replaceFunction = 
		oldContentBox.children().length > 0 ? 
			(
				newContentBox.children().length > 0 ?
					replaceBoxContent_Content2Content
					: replaceBoxContent_Content2Empty
			)
			: (
				newContentBox.children().length > 0 ?
					replaceBoxContent_Empty2Content
					: (function() {})
			)
	;
	replaceFunction(oldContentBox, newContentBox, duration);
}

/* 
 * replace elements of the current page with the corresponding 
 * elements of the given one
 */	
replaceElements = function(newPage, duration, callback) {
	crossfadeItems(newPage, duration, callback);
	replaceBoxContent(newPage, duration);
}

animateMenu = function(newPage, duration) {
	var menuBox = $('#menuBox');
	var oldMenu = $('#menu');
	var oldMenuItems = $('li', oldMenu)
	var newMenu = $('#menu', newPage);
	var newMenuItems = $('#menu LI', newPage);
	
	if(oldMenu.text() != newMenu.text()) {
		animateBoxHeight('menuBox', 0, function() {
			oldMenu.replaceWith(newMenu);
			expandBox('menuBox');
		});
	} else {
		if(menuBox.attr('status') == 'expanded') {
			menuBox.css({height: 'auto'});
			oldMenu.css({height: 'auto'});			
		}
		
		for(var i=0; i<oldMenuItems.length; i++) {
			oldMenuItem = $(oldMenuItems[i]);
			newMenuItem = $(newMenuItems[i]);

			if(oldMenuItem.attr('class') != newMenuItem.attr('class')) {
				// status changed

				var updateClassOfOldMenuItem = 
					function(oldMenuItem, newClass) {
						return (
							function() {oldMenuItem.attr('class', newClass);}
						);
					}(oldMenuItem, newMenuItem.attr('class'))
				;

				var subMenu = $('ul', oldMenuItem);
				if(subMenu.length) {
					// has submenu

					// fix menu item height
					var oldHeight = oldMenuItem.height();
					oldMenuItem.css({height: oldHeight});

					if(newMenuItem.hasClass('mainMenuItem_ACT')) {
						// expand submenu
						updateClassOfOldMenuItem();
						oldMenuItem.animate({
							height: oldHeight + subMenu.height()
						}, duration);				
					} else {
						// collapse submenu
						oldMenuItem.animate(
							{height: oldHeight - subMenu.height()}, 
							duration,
							updateClassOfOldMenuItem
						);										
					}
				} else {
					// no submenu
					updateClassOfOldMenuItem();
				}
			}
		}	
	}
}


pullJs = function(newPageHtml) {
	var regexp = (/<script type="text\/javascript" id="slideshowData">(.*?)<\/script>/);
	var regexpResult = regexp.exec(newPageHtml);
	var script = regexpResult[1];
	$.globalEval(script);
}

replacePage = function(newPageHtml, fallbackUrl) { 
   var newPage = $(newPageHtml);
	// new page sanity check
	if(! ($('#logoLink', newPage).length > 0)) {
		fallbackNavigation(fallbackUrl);
	} 
	$.preload(
		$('IMG', newPage),
		{
			threshold: preloadThreshold,
			onFinish: function() {
				/* 
				 * IE8 throws an "Stack overflow at line 0" error message
				 * if this function is executed directly. 
				 * To avoid this, the function is wrapped in a 0 sec timeout. 
				 */
				window.setTimeout(function() {
					var reinitializeVideos = function() {	
						$('.video-js').each(function() {
							VideoJS.setup(this.id, {});
						});
					}
				
					var reinitializeSlideshow = function() {
						window.slideshow.init();
					}
					var duration = 1000;

					replaceElements(newPage, duration, function() {
						reinitializeSlideshow();
						reinitializeVideos();
						registerLinkEventHandlers();				
					});
					initializeImageMenu();
					animateMenu(newPage, duration);
					pullJs(newPageHtml);
				}, 0);
			},
			onRequest: function() {loading();},
			onComplete: function() {finishedLoading();}
		}
	);
}

$(document).ready(function() {
	$('#menuBox, #contentBox, #mainContainer').css('height', 0);
	$('#reflectionImageContainer').css('visibility', 'hidden');
});


gotoPage = function(newUrl) {
	$.ajax({  
		url: newUrl,
	   success: function(newPage) {
			finishedLoading();
			replacePage(newPage, newUrl);
		}, 
		error: function() {
			fallbackNavigation(newUrl);
		}
	});
	loading();
}


$(window).load(function() { 
	$(window).bind('statechange', function(){ // Note: We are using statechange instead of popstate
		var state = window.History.getState(); // Note: We are using History.getState() instead of event.state
		gotoPage(state.url);
	});
	
	loadingIndicator = document.createElement('div');
	loadingIndicator.innerHTML = 'loading…';
	loadingIndicator.id = 'loadingIndicator';
	$('body').append(loadingIndicator);
	$(loadingIndicator).fadeOut();
	

	preloadThreshold = $.browser.safari ? 100: 2;
	
	registerLinkEventHandlers();
	initializeImageMenu();
	startOnLoadAnimations(function() {
		window.slideshow = new Slideshow();
		slideshow.init();
	});	
});
