


/*
 * Please notice carefully: This file is licensed only for use in providing whimsical.de,
 * whimsical3d.com, or any part thereof, and is subject to the Terms and Conditions provided
 * by Whimsical.
 * You may not port this file to another platform without Whimsical's written permission.
 */
 


// declare global variables
var language = 0;				// 0 = english (default), 1 = german
var isIE = false;				// Just like the name sais...
var isIPhone = false;			// Are we running on an iPhone, iPod Touch, etc.?
var images = new Array();
var imagePreloader = ["./img/whimsical_backdrop.jpg", "./img/whimsical_logo.png", "./img/images.png"];
var imagePreloaderCounter = 0;
var activatedCategory = 0;
var urlVars;
var scrollerInterval;
var preloaderInterval;
var preloaderCounter = 0;
var scrollerFPS = 60;
var prevMilliSeconds = 0;
var deltaTime = 0;

var mouseXPosition = 0;
var globalMouseXDelta = 0;
var mouseXStart = new Array();
var mouseXDelta = new Array();
var scrollingActivated = new Array();
var smoothedMouseXDelta = new Array();
var scrollingVelocity = new Array();
var scrollingDuration = new Array();
var scrollPosition = new Array();
var rebounding = new Array();
var reboundingVelocity = new Array();

var closeImgHandler;

var clickMouseDelta = 0;
var clickMouseXStart = 0;
var observeClicks = false;

var links = new Array();

var showingIntroLogo = true;

// Wait for scripts to run until document is fully loaded
document.observe('dom:loaded', function() {
	initializations();
	observeLanguageButtons();
	$('infoIcon').observe('click', infoButtonActions);
});

var infoButtonActions = function() {
	$('infoIcon').stopObserving('click').setStyle( { cursor: "default" } );
	if(isIE || isIPhone) {
		if(language == 0) {
			$('langDE').hide();
		} else {
			$('langUS').hide();
		}
		$('infoText').show();
	} else {
		stopObservingLanguageButtons();
		if(language == 0) {
			new Effect.Parallel( [
				new Effect.Fade('langDE'),
				new Effect.Appear('infoText')
			]);
		} else {
			new Effect.Parallel( [
				new Effect.Fade('langUS'),
				new Effect.Appear('infoText')
			]);
		}
	}
	window.setTimeout(function() {
		if(isIE || isIPhone) {
			if(language == 0) {
				$('langDE').show();
			} else {
				$('langUS').show();
			}
			$('infoText').hide();
			$('infoIcon').observe('click', infoButtonActions).setStyle( { cursor: "pointer" } );
		} else {
			if(language == 0) {
				new Effect.Parallel( [
					new Effect.Appear('langDE'),
					new Effect.Fade('infoText')
				], {
				afterFinish: function() {
					$('infoIcon').observe('click', infoButtonActions).setStyle( { cursor: "pointer" } );
					observeLanguageButtons();
				}});
			} else {
				new Effect.Parallel( [
					new Effect.Appear('langUS'),
					new Effect.Fade('infoText')
				], {
				afterFinish: function() {
					$('infoIcon').observe('click', infoButtonActions).setStyle( { cursor: "pointer" } );
					observeLanguageButtons();
				}});
			}
		}
	}, 5000);
}

// Library of custom functions
function initializations() {
	// Initialize required arrays for the scrolling funtionality. Takes the array size as the only parameter.
	initScrollingArrays(7);
	activateScrollers();
	initLinks();
	showLoadingbar(0);
	
	// Find out the language to start the user's visit with based on the browser's language settings
	var langInfo = navigator.language ? navigator.language : navigator.userLanguage;
	if(langInfo.substr(0,2) != "de" && langInfo.substr(0,2) != "DE") {
		language = 0;
	} else {
		language = 1;
	}
	
	// Set the apropriate visibility settings on the language buttons
	if(language == 1) {
		$('langUS').show();
	} else {
		$('langDE').show();
	}
	
	// Find out if we're running inside Internet Explorer
	if(/MSIE (\d+\.\d+);/.test(navigator.userAgent)) {
		var ieVersion = new Number(RegExp.$1);
		if(ieVersion <= 6) {
			alert("You are using an unsupported version of Internet Explorer.\n\nThis site might probably not work as expected. We are sorry for the inconvenience.");
			isIE = true;
		} else if(ieVersion >= 7 && ieVersion <= 8) {
			isIE = true;
		} else if(ieVersion >= 9) {
			isIE = false;
		}
	} else if(/iPhone/.test(navigator.userAgent) || /iPod/.test(navigator.userAgent) || /iPad/.test(navigator.userAgent)) {
		isIPhone = true;
	}
	
	$(document).observe('contextmenu', function(e) {
		if(!e.altKey) {
			e.stop();
		}
	});
	
	$(document).observe('mousemove', function(e) {
		mouseXPosition = e.pointerX();
		if(observeClicks) {
			clickMouseDelta = e.pointerX() - clickMouseXStart;
		}
		e.stop();
	});
	
	Event.observe(window, 'resize', function() {
		if(showingIntroLogo) {
			readjustLogoPlacement();
		}
	});
	
	// Find out if (and what) commands were given with the URL
	urlVars = getUrlVars();
	
	// hide all elements
	initMenuOpacity();
	initContentOpacity();
	
	// initialize the menu with the correct language
	changeMenuLanguage();
	
	// Add the texts to the preloader, respect the chosen language
	// ... and while we're at it, also load all the required additional
	// language based imagery.
	if(language == 1) {
		imagePreloader.push("./img/texts_de.png");
		imagePreloader.push("./img/lily_de.png");
		imagePreloader.push("./img/architectureDemo_de.png");
	} else {
		imagePreloader.push("./img/texts_en.png");
		imagePreloader.push("./img/lily_en.png");
		imagePreloader.push("./img/architectureDemo_en.png");
	}
	
	// Start preloading images
	preloadImages();
}

function readjustLogoPlacement() {
	var tmpDocWidth = document.viewport.getDimensions().width;
	var tmpDocHeight = document.viewport.getDimensions().height;
	var tmpImgWidth = 869;
	var tmpImgHeight = 539;
	var tmpMaxWidth = tmpImgWidth + 150;
	var tmpMaxHeight = tmpImgHeight + 150;
	if(tmpMaxWidth > tmpDocWidth || tmpMaxHeight > tmpDocHeight) {
		if((tmpDocWidth / tmpDocHeight) > (tmpMaxWidth / tmpMaxHeight)) {
			// Image aspect is higher than viewport - so the hight is what counts
			var newHeight = tmpDocHeight - 150;
			var newWidth = tmpImgWidth / (tmpImgHeight / newHeight);
		} else {
			// Image aspect is wider than viewport - so the width is what counts
			var newWidth = tmpDocWidth - 150;
			var newHeight = tmpImgHeight / (tmpImgWidth / newWidth);
		}
	} else {
		var newWidth = tmpImgWidth;
		var newHeight = tmpImgHeight;
	}
	var newRight = (tmpDocWidth/2) - (newWidth/2);
	var newTop = (tmpDocHeight/2) - (newHeight/2);
	$('whimsicalLogo').setStyle( { width: newWidth + 'px', height: newHeight + 'px', top: newTop + 'px', right: newRight + 'px' } );
}

function initLinks() {
	// Types of links (2nd array item)
	//		0 - external link, opens new window
	//		1 - image, opens image viewer (0 - standalone, 1 - bordered)
	//		2 - video, opens video viewer
	//		3 - external link, opens in SAME window
	links['cat5_p1_click1_en'] = ['mailto:contact@whimsical3d.com', 4, 0];
	links['cat5_p1_click1_de'] = ['mailto:contact@whimsical3d.com', 4, 0];
	links['cat5_p2_click1_en'] = ['mailto:contact@whimsical.de', 4, 0];
	links['cat5_p2_click1_de'] = ['mailto:contact@whimsical.de', 4, 0];
	
	links['cat6_p1_click1_en'] = ['mailto:contact@whimsical.de', 4, 0];
	links['cat6_p1_click1_de'] = ['mailto:contact@whimsical.de', 4, 0];
	links['cat6_p2_click1_en'] = ['mailto:contact@whimsical3d.com', 4, 0];
	links['cat6_p2_click1_de'] = ['mailto:contact@whimsical3d.com', 4, 0];
	
	links['cat2_p3_click1_en'] = ['img/architectureDemoPic1.png', 1, 0];
	links['cat2_p3_click1_de'] = ['img/architectureDemoPic1.png', 1, 0];
	links['cat2_p3_click2_en'] = ['img/architectureDemoPic2.png', 1, 0];
	links['cat2_p3_click2_de'] = ['img/architectureDemoPic2.png', 1, 0];
	links['cat2_p3_click3_en'] = ['img/architectureDemoPic3.png', 1, 0];
	links['cat2_p3_click3_de'] = ['img/architectureDemoPic3.png', 1, 0];
	links['cat2_p3_click4_en'] = ['img/architectureDemoPic4.png', 1, 0];
	links['cat2_p3_click4_de'] = ['img/architectureDemoPic4.png', 1, 0];
	links['cat2_p3_click5_en'] = ['img/architectureDemoPic5.png', 1, 0];
	links['cat2_p3_click5_de'] = ['img/architectureDemoPic5.png', 1, 0];

	links['cat2_p3_click6_en'] = ['downloads/ArchitectureDemoWindows.zip', 4, 0];
	links['cat2_p3_click6_de'] = ['downloads/ArchitectureDemoWindows.zip', 4, 0];
	links['cat2_p3_click7_en'] = ['downloads/ArchitectureDemoMacOSX.zip', 4, 0];
	links['cat2_p3_click7_de'] = ['downloads/ArchitectureDemoMacOSX.zip', 4, 0];

	links['cat7_p2_click1_en'] = ['http://whimsicallily.com', 0, 0];
	links['cat7_p2_click1_de'] = ['http://whimsicallily.com', 0, 0];
	links['cat7_p2_click2_en'] = ['img/lily1_en.png', 1, 0];
	links['cat7_p2_click2_de'] = ['img/lily1_de.png', 1, 0];
	links['cat7_p2_click3_en'] = ['img/lily2_en.png', 1, 0];
	links['cat7_p2_click3_de'] = ['img/lily2_de.png', 1, 0];
	links['cat7_p2_click4_en'] = ['http://whimsicallily.com', 0, 0];
	links['cat7_p2_click4_de'] = ['http://whimsicallily.com', 0, 0];

}

function showLoadingbar(depth) {
	$('preloader').show().setStyle({ zIndex: depth });
	preloaderInterval = setInterval(function() {
		$('preloader').setStyle( { backgroundPosition: '0px ' + -(preloaderCounter * 18) + 'px' } );
		preloaderCounter++;
		if(preloaderCounter > 19) {
			preloaderCounter = 0;
		}
	}, 100);
}

function hideLoadingbar() {
	$('preloader').hide().setStyle({ zIndex: '-1' });
	clearInterval(preloaderInterval);
}

function initScrollingArrays(num) {
	for(i=0; i<num; i++) {
		mouseXStart[i] = 0;
		mouseXDelta[i] = 0;
		scrollingActivated[i] = false;
		smoothedMouseXDelta[i] = 0.0;
		scrollingVelocity[i] = 0.0;
		scrollingDuration[i] = 0.3;
		scrollPosition[i] = 0.0;
		rebounding[i] = false;
		reboundingVelocity[i] = 0.0;
	}
}

function initRowWidth() {
	var rowWidth = 0;
	$$('.content').each(function(rowElement) {
		rowWidth = 0;
		$(rowElement).childElements().each(function(childElement) {
			rowWidth += Element.getWidth(childElement) + 30;
		});
		$(rowElement).setStyle( { width: rowWidth + "px" } );
	});
}

function initMenuOpacity() {
	var fadeInSpeed = 0.0;
	var pFrom = 1.0;
	var pTo = 0.0;
	
	$$('.menu').each(function(element) {
		new Effect.Opacity(element.id, { from: pFrom, to: pTo, duration: fadeInSpeed } );
	});
	$$('.wrapper').each(function(element) {
		new Effect.Opacity(element.id, { from: pFrom, to: pTo, duration: fadeInSpeed } );
	});
	new Effect.Opacity('menuEnd', { from: pFrom, to: pTo, duration: fadeInSpeed } );
	if(isIE) {
		$$('.menuBGleft').each(function(element) {
			new Effect.Opacity(element.id, { from: pFrom, to: pTo, duration: fadeInSpeed } );
		});
		$$('.menuBGright').each(function(element) {
			new Effect.Opacity(element.id, { from: pFrom, to: pTo, duration: fadeInSpeed } );
		});
		$$('.menuCaption').each(function(element) {
			new Effect.Opacity(element.id, { from: pFrom, to: pTo, duration: fadeInSpeed } );
		});
	}
}

function initContentOpacity() {
	var animationSpeed = 0;
	var opacity = 0;
	$$('.content').each(function(element) {
		new Effect.Opacity(element.id, { to: opacity, duration: animationSpeed } );
	});
}

function changeMenuLanguage() {
	if(language == 1) {
		$('aboutUsMenuCaption').setStyle( { backgroundPosition: "-536px -67px" } );
		$('realtime3dMenuCaption').setStyle( { backgroundPosition: "-536px -35px" } );
		$('softwareMenuCaption').setStyle( { backgroundPosition: " -536px -99px" } );
		$('threeDRenderingsMenuCaption').setStyle( { backgroundPosition: "-270px -99px" } );
		$('twoDDesignMenuCaption').setStyle( { backgroundPosition: "-270px -131px" } );
		$('contactMenuCaption').setStyle( { backgroundPosition: "-403px -131px" } );
		$('legalNoticeMenuCaption').setStyle( { backgroundPosition: "-403px -99px" } );
	} else {
		$('aboutUsMenuCaption').setStyle( { backgroundPosition: "-270px -35px" } );
		$('realtime3dMenuCaption').setStyle( { backgroundPosition: "-270px -67px" } );
		$('softwareMenuCaption').setStyle( { backgroundPosition: " -536px -99px" } );
		$('threeDRenderingsMenuCaption').setStyle( { backgroundPosition: "-270px -99px" } );
		$('twoDDesignMenuCaption').setStyle( { backgroundPosition: "-270px -131px" } );
		$('contactMenuCaption').setStyle( { backgroundPosition: "-403px -35px" } );
		$('legalNoticeMenuCaption').setStyle( { backgroundPosition: "-403px -67px" } );
	}
}

function animateMenues() {
	var targets = new Array(2,2,2,2,2,2,2,2,2);
	var opacity = new Array(0,0,0,0,0,0,0,0,0);
	if(isIPhone) {
		var animationSpeed = 0;
	} else {
		var animationSpeed = 1;
	}
	// style="height: 293px"
	switch(activatedCategory) {
		case 1:
			targets[0] = 293;
			opacity[0] = 1;
			break;
		case 2:
			targets[1] = 293;
			opacity[1] = 1;
			break;
		case 3:
			targets[2] = 293;
			opacity[2] = 1;
			break;
		case 4:
			targets[3] = 293;
			opacity[3] = 1;
			break;
		case 5:
			targets[4] = 293;
			opacity[4] = 1;
			break;
		case 6:
			targets[5] = 293;
			opacity[5] = 1;
			break;
		case 7:
			targets[6] = 293;
			opacity[6] = 1;
			break;
		default:
			
	}
	var animationArray = new Array();
	if(targets[0] != $('aboutUsWrapper').getHeight()) animationArray.push(new Effect.Morph('aboutUsWrapper', { style: { height: targets[0] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(targets[0] != $('aboutUsScroller').getHeight()) animationArray.push(new Effect.Morph('aboutUsScroller', { style: { height: targets[0] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(opacity[0] != $('aboutUsContent').getOpacity()) animationArray.push(new Effect.Opacity('aboutUsContent', { to: opacity[0], duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(targets[0] != $('aboutUsContent').getHeight()) animationArray.push(new Effect.Morph('aboutUsContent', { style: { height: targets[0] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	
	if(targets[1] != $('realtime3dWrapper').getHeight()) animationArray.push(new Effect.Morph('realtime3dWrapper', { style: { height: targets[1] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(targets[1] != $('realtime3dScroller').getHeight()) animationArray.push(new Effect.Morph('realtime3dScroller', { style: { height: targets[1] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(opacity[1] != $('realtime3dContent').getOpacity()) animationArray.push(new Effect.Opacity('realtime3dContent', { to: opacity[1], duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(targets[1] != $('realtime3dContent').getHeight()) animationArray.push(new Effect.Morph('realtime3dContent', { style: { height: targets[1] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	
	if(targets[6] != $('softwareWrapper').getHeight()) animationArray.push(new Effect.Morph('softwareWrapper', { style: { height: targets[6] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(targets[6] != $('softwareScroller').getHeight()) animationArray.push(new Effect.Morph('softwareScroller', { style: { height: targets[6] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(opacity[6] != $('softwareContent').getOpacity()) animationArray.push(new Effect.Opacity('softwareContent', { to: opacity[6], duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(targets[6] != $('softwareContent').getHeight()) animationArray.push(new Effect.Morph('softwareContent', { style: { height: targets[6] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
		
	if(targets[2] != $('3dRenderingsWrapper').getHeight()) animationArray.push(new Effect.Morph('3dRenderingsWrapper', { style: { height: targets[2] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(targets[2] != $('3dRenderingsScroller').getHeight()) animationArray.push(new Effect.Morph('3dRenderingsScroller', { style: { height: targets[2] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(opacity[2] != $('threeDRenderingsContent').getOpacity()) animationArray.push(new Effect.Opacity('threeDRenderingsContent', { to: opacity[2], duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(targets[2] != $('threeDRenderingsContent').getHeight()) animationArray.push(new Effect.Morph('threeDRenderingsContent', { style: { height: targets[2] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	
	if(targets[3] != $('2dDesignWrapper').getHeight()) animationArray.push(new Effect.Morph('2dDesignWrapper', { style: { height: targets[3] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(targets[3] != $('2dDesignScroller').getHeight()) animationArray.push(new Effect.Morph('2dDesignScroller', { style: { height: targets[3] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(opacity[3] != $('twoDDesignContent').getOpacity()) animationArray.push(new Effect.Opacity('twoDDesignContent', { to: opacity[3], duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(targets[3] != $('twoDDesignContent').getHeight()) animationArray.push(new Effect.Morph('twoDDesignContent', { style: { height: targets[3] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	
	if(targets[4] != $('contactWrapper').getHeight()) animationArray.push(new Effect.Morph('contactWrapper', { style: { height: targets[4] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(targets[4] != $('contactScroller').getHeight()) animationArray.push(new Effect.Morph('contactScroller', { style: { height: targets[4] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(opacity[4] != $('contactContent').getOpacity()) animationArray.push(new Effect.Opacity('contactContent', { to: opacity[4], duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(targets[4] != $('contactContent').getHeight()) animationArray.push(new Effect.Morph('contactContent', { style: { height: targets[4] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	
	if(targets[5] != $('legalNoticeWrapper').getHeight()) animationArray.push(new Effect.Morph('legalNoticeWrapper', { style: { height: targets[5] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(targets[5] != $('legalNoticeScroller').getHeight()) animationArray.push(new Effect.Morph('legalNoticeScroller', { style: { height: targets[5] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(opacity[5] != $('legalNoticeContent').getOpacity()) animationArray.push(new Effect.Opacity('legalNoticeContent', { to: opacity[5], duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	if(targets[5] != $('legalNoticeContent').getHeight()) animationArray.push(new Effect.Morph('legalNoticeContent', { style: { height: targets[5] + "px" }, duration: animationSpeed, transition: Effect.Transitions.hermite } ));
	
	new Effect.Parallel(animationArray), { sync: true };
}

function activateScrollers() {
	switch(activatedCategory) {
		case 1:
			var activeScroller = "aboutUsScroller";
			break;
		case 2:
			var activeScroller = "realtime3dScroller";
			break;
		case 3:
			var activeScroller = "3dRenderingsScroller";
			break;
		case 4:
			var activeScroller = "2dDesignScroller";
			break;
		case 5:
			var activeScroller = "contactScroller";
			break;
		case 6:
			var activeScroller = "legalNoticeScroller";
			break;
		case 7:
			var activeScroller = "softwareScroller";
			break;
		default:
			
	}
	$$('.scroller').each(function(scrollerElement) {
		if(scrollerElement.id == activeScroller) {
			scrollerElement.setStyle( { cursor: 'move' } );
		} else {
			scrollerElement.setStyle( { cursor: 'default' } );
		}
	});
}

function deactivateScrollers() {
	// if(isIE) return;
	$$('.scroller').each(function(scrollerElement) {
		scrollerElement.setStyle( { cursor: 'default' } );
	});
}

function changeMenu(command) {
	switch(command) {
		case "about":
		case "aboutUsMenuClickArea":
		case "aboutUs":
			activatedCategory = 1;
			break;
		case "realtime":
		case "realtime3dMenuClickArea":
		case "realtime3d":
			activatedCategory = 2;
			break;
		case "software":
		case "softwareMenuClickArea":
			activatedCategory = 7;
			break;
		case "3d":
		case "3dRenderingsMenuClickArea":
		case "3dRenderings":
			activatedCategory = 3;
			break;
		case "2d":
		case "2dDesignMenuClickArea":
		case "2dDesign":
			activatedCategory = 4;
			break;
		case "contact":
		case "contactMenuClickArea":
			activatedCategory = 5;
			break;
		case "legal":
		case "legalNoticeMenuClickArea":
		case "legalNotice":
			activatedCategory = 6;
			break;
		default:
			activatedCategory = 0;
	}
	activateScrollers();
	animateMenues();
}

function changeLanguage() {
	// Deactivate menu buttons
	stopObservingMenuButtons();
	// Hide the content
	contentAnimateOpacity(1, 0);
	// Change language button label
	if(isIE) {
		if(language == 1) {
			$('langDE').hide();
			$('langUS').show();
		} else {
			$('langDE').show();
			$('langUS').hide();
		}
	} else {
		stopObservingLanguageButtons();
		if(language == 1) {
			new Effect.Parallel( [ 
				new Effect.Fade('langDE'),
				new Effect.Appear('langUS')
			], {
			afterFinish: function() {
				observeLanguageButtons();
			}});
		} else {
			new Effect.Parallel( [
				new Effect.Appear('langDE'),
				new Effect.Fade('langUS')
			], {
			afterFinish: function() {
				observeLanguageButtons();
			}});
		}
	}
	window.setTimeout(function() {
		$('preloader').fade( { duration: 0 } ).setStyle( { zIndex: "999" } );
		// Show the loading bar
		if(isIE) {
			var transitionSpeed = 0;
		} else {
			var transitionSpeed = 0.5;
		}
		preloaderInterval = setInterval(function() {
			$('preloader').setStyle( { backgroundPosition: '0px ' + -(preloaderCounter * 18) + 'px' } );
			preloaderCounter++;
			if(preloaderCounter > 19) {
				preloaderCounter = 0;
			}
		}, 100);
		$('preloader').appear({ duration: transitionSpeed });
		window.setTimeout(function() {
			// Chance the menue's language
			changeMenuLanguage();
			// Preload the new language
			var languagePreLoader = new Image();
			languagePreLoader.onload = function() {
				var architectureDemo = new Image();
				architectureDemo.onload = function() {
					var lily = new Image();
					lily.onload = function() {
						if(language == 1) {
							$$('.text').each(function(textElement) {
								textElement.setStyle( { backgroundImage: "url(./img/texts_de.png)" } );
							});
							$('cat7_p2').setStyle( { backgroundImage: "url(./img/lily_de.png)" } );
							$('cat2_p3').setStyle( { backgroundImage: "url(./img/architectureDemo_de.png)" } );
						} else {
							$$('.text').each(function(textElement) {
								textElement.setStyle( { backgroundImage: "url(./img/texts_en.png)" } );
							});
							$('cat7_p2').setStyle( { backgroundImage: "url(./img/lily_en.png)" } );
							$('cat2_p3').setStyle( { backgroundImage: "url(./img/architectureDemo_en.png)" } );
						}
						$('preloader').fade( { duration: transitionSpeed, afterFinish: function() {
							// Show the content
							contentAnimateOpacity(0, 1);
							// Activate menu buttons
							observeMenuButtons();
					
							clearInterval(preloaderInterval);
						}});
					}
					if(language == 1) {
						// German language source image
						lily.src = "./img/lily_de.png";
					} else {
						// English language source image
						lily.src = "./img/lily_en.png";
					}
				}
				if(language == 1) {
					// German language source image
					architectureDemo.src = "./img/architectureDemo_de.png";
				} else {
					// English language source image
					architectureDemo.src = "./img/architectureDemo_en.png";
				}
			}
			if(language == 1) {
				// German language source image
				languagePreLoader.src = "./img/texts_de.png";
			} else {
				// English language source image
				languagePreLoader.src = "./img/texts_en.png";
			}
		}, 1000);
	}, 750);
}

function preloadImages() {
	if(images.length < 1) {
		images.length = imagePreloader.length;
	}
	if(imagePreloaderCounter < imagePreloader.length) {
		images[imagePreloaderCounter] = new Image();
		images[imagePreloaderCounter].onload = function() {
			imagePreloaderCounter++;
			preloadImages();
		}
		images[imagePreloaderCounter].src = imagePreloader[imagePreloaderCounter];
	} else {
		window.setTimeout(function() {
			readjustLogoPlacement();
			assignImages();
		}, 1000);
	}
}

function assignImages() {
	$('whimsicalWrapper').setStyle({ backgroundImage: "url(" + imagePreloader[0] + ")" });
	$('whimsicalLogo').src = imagePreloader[1];
	$('legalNoticeMenuCaption').setStyle({ backgroundImage: "url(" + imagePreloader[2] + ")" });
	$('contactMenuCaption').setStyle({ backgroundImage: "url(" + imagePreloader[2] + ")" });
	$('twoDDesignMenuCaption').setStyle({ backgroundImage: "url(" + imagePreloader[2] + ")" });
	$('threeDRenderingsMenuCaption').setStyle({ backgroundImage: "url(" + imagePreloader[2] + ")" });
	$('softwareMenuCaption').setStyle({ backgroundImage: "url(" + imagePreloader[2] + ")" });
	$('realtime3dMenuCaption').setStyle({ backgroundImage: "url(" + imagePreloader[2] + ")" });
	$('aboutUsMenuCaption').setStyle({ backgroundImage: "url(" + imagePreloader[2] + ")" });
	$('menuEnd').setStyle({ backgroundImage: "url(" + imagePreloader[2] + ")" });
	$$('.menuBGright').each(function(elemObject) {
		elemObject.setStyle( { backgroundImage: "url(" + imagePreloader[2] + ")" } );
	});
	$$('.menuBGleft').each(function(elemObject) {
		elemObject.setStyle( { backgroundImage: "url(" + imagePreloader[2] + ")" } );
	});
	$('langDE').setStyle({ backgroundImage: "url(" + imagePreloader[2] + ")" });
	$('langUS').setStyle({ backgroundImage: "url(" + imagePreloader[2] + ")" });
	$('infoText').setStyle({ backgroundImage: "url(" + imagePreloader[2] + ")" });
	$('infoIcon').setStyle({ backgroundImage: "url(" + imagePreloader[2] + ")" });
	$$('.text').each(function(textElement) {
		textElement.setStyle( { backgroundImage: "url(" + imagePreloader[3] + ")" } );
	});
	$('cat7_p2').setStyle({ backgroundImage: "url(" + imagePreloader[4] + ")" });
	$('cat2_p3').setStyle({ backgroundImage: "url(" + imagePreloader[5] + ")" });
	showSite();
}

function showSite() {
	var fadeInSpeed = 1.0;
	
	if(!isIE || true) {
		$('whimsicalWrapper').appear({ duration: fadeInSpeed, transition: Effect.Transitions.hermite, afterFinish: function() { hideLoadingbar(); }});
		window.setTimeout(function() {
			$('whimsicalLogo').appear({ duration: fadeInSpeed, transition: Effect.Transitions.hermite });
			window.setTimeout(function() {
				showingIntroLogo = false;
				new Effect.Morph('whimsicalLogo', { style: { width: '260px', height: '161px', top: '40px', right: '40px' }, duration: fadeInSpeed * 1.15, transition: Effect.Transitions.hermite2 });
				window.setTimeout(function() {
					contentAnimateOpacity(0, 1, function() {
						if(urlVars['content'] != null) {
							changeMenu(urlVars['content']);
						}
						showInfoArea(3.0);
						observeMenuButtons();
					});
					initRowWidth();
				}, (fadeInSpeed * 750));
			}, (fadeInSpeed * 2000));
		}, (fadeInSpeed * 500));
	}
}

function showInfoArea(pSpeedMultiplyer) {
	if(typeof(pSpeedMultiplyer) == 'undefined') pSpeedMultiplyer = 1.0;
	if(pSpeedMultiplyer < 0) pSpeedMultiplyer = 0.0;
	$('infoArea').appear({ duration: pSpeedMultiplyer, transition: Effect.Transitions.hermite });
}

function hideInfoArea(pSpeedMultiplyer) {
	if(typeof(pSpeedMultiplyer) == 'undefined') pSpeedMultiplyer = 1.0;
	if(pSpeedMultiplyer < 0) pSpeedMultiplyer = 0.0;
	$('infoArea').fade({ duration: pSpeedMultiplyer, transition: Effect.Transitions.hermite });
}

function contentAnimateOpacity(pFrom, pTo, pFunction) {
	if(isIE || isIPhone) {
		var fadeInSpeed = 0;
		var fadeInDelay = 50;
  
	} else {
		var fadeInSpeed = 0.5;
		var fadeInDelay = 125;
	}
	window.setTimeout(function() {
		new Effect.Opacity( 'aboutUsMenu', { from: pFrom, to: pTo, duration: fadeInSpeed } );
		new Effect.Opacity( 'aboutUsWrapper', { from: pFrom, to: pTo, duration: fadeInSpeed } );
		new Effect.Opacity( 'aboutUsContent', { from: pFrom, to: pTo, duration: fadeInSpeed } );
		window.setTimeout(function() {
			new Effect.Opacity( 'realtime3dMenu', { from: pFrom, to: pTo, duration: fadeInSpeed } );
			new Effect.Opacity( 'realtime3dWrapper', { from: pFrom, to: pTo, duration: fadeInSpeed } );
			new Effect.Opacity( 'realtime3dContent', { from: pFrom, to: pTo, duration: fadeInSpeed } );
			window.setTimeout(function() {
				new Effect.Opacity( 'softwareMenu', { from: pFrom, to: pTo, duration: fadeInSpeed } );
				new Effect.Opacity( 'softwareWrapper', { from: pFrom, to: pTo, duration: fadeInSpeed } );
				new Effect.Opacity( 'softwareContent', { from: pFrom, to: pTo, duration: fadeInSpeed } );
				window.setTimeout(function() {
					new Effect.Opacity( '3dRenderingsMenu', { from: pFrom, to: pTo, duration: fadeInSpeed } );
					new Effect.Opacity( '3dRenderingsWrapper', { from: pFrom, to: pTo, duration: fadeInSpeed } );
					new Effect.Opacity( 'threeDRenderingsContent', { from: pFrom, to: pTo, duration: fadeInSpeed } );
					window.setTimeout(function() {
						new Effect.Opacity( '2dDesignMenu', { from: pFrom, to: pTo, duration: fadeInSpeed } );
						new Effect.Opacity( '2dDesignWrapper', { from: pFrom, to: pTo, duration: fadeInSpeed } );
						new Effect.Opacity( 'twoDDesignContent', { from: pFrom, to: pTo, duration: fadeInSpeed } );
						window.setTimeout(function() {
							new Effect.Opacity( 'contactMenu', { from: pFrom, to: pTo, duration: fadeInSpeed } );
							new Effect.Opacity( 'contactWrapper', { from: pFrom, to: pTo, duration: fadeInSpeed } );
							new Effect.Opacity( 'contactContent', { from: pFrom, to: pTo, duration: fadeInSpeed } );
							window.setTimeout(function() {
								new Effect.Opacity( 'legalNoticeMenu', { from: pFrom, to: pTo, duration: fadeInSpeed } );
								new Effect.Opacity( 'legalNoticeWrapper', { from: pFrom, to: pTo, duration: fadeInSpeed } );
								new Effect.Opacity( 'legalNoticeContent', { from: pFrom, to: pTo, duration: fadeInSpeed } );
								new Effect.Opacity( 'menuEnd', { from: pFrom, to: pTo, duration: fadeInSpeed } );
								if(typeof(pFunction) == 'function') {
									window.setTimeout(function() { pFunction() },fadeInDelay);
								}
							}, fadeInDelay);
						}, fadeInDelay);
					}, fadeInDelay);
				}, fadeInDelay);
			}, fadeInDelay);
		}, fadeInDelay);
	}, fadeInDelay);
}

function observeLanguageButtons() {
	$('langUS').observe('click', function() {
		if(language != 0) {
			language = 0;
			changeLanguage();
		}
	}).setStyle( { cursor: "pointer" } );
	
	$('langDE').observe('click', function() {
		if(language != 1) {
			language = 1;
			changeLanguage();
		}
	}).setStyle( { cursor: "pointer" } );
}

function stopObservingLanguageButtons() {
	$('langDE').stopObserving('click').setStyle( { cursor: "default" } );
	$('langUS').stopObserving('click').setStyle( { cursor: "default" } );
}

function observeMenuButtons() {
	$$('.menuClickArea').each(function(menuElement) { 
        menuElement.observe('click', function() { 
            changeMenu(menuElement.id);
        }).setStyle( { cursor: "pointer" } );
    });
	
	$$('.clickArea').each(function(clickElement) {
		clickElement.observe('mousedown', function(e, clickID) {
			clickMouseDelta = 0;
			clickMouseXStart = e.pointerX();
			observeClicks = true;
		}).setStyle( { cursor: "pointer" } );
	});
	
	$$('.scroller').each(function(scrollerElement) {
		scrollerElement.observe('mousedown', function(e, scrollerID) {
			e.stop();
			var scrollerID = scrollerElement.readAttribute('scrollerID');
			scrollingActivated[scrollerID] = true;
			mouseXStart[scrollerID] = e.pointerX();
			mouseXDelta[scrollerID] = 0;

			if(scrollerInterval == null) {
				prevMilliSeconds = new Date().getTime();
				startScrolling(getScroller(scrollerElement), scrollerID);
			}
			
			document.observe('mouseup', function(e, scrollerID) {
				document.stopObserving('mouseup');
				stopScrolling();
				if(observeClicks) {
					observeClicks = false;
					if(Math.abs(clickMouseDelta) < 5) {
						var clickedID = e.findElement(".clickArea").id;
						clickLink(clickedID);
					}
				}
				e.stop();
			});
		});
	});
	
	$$('.scroller').each(function(scrollerElement) {
		scrollerElement.observe('mouseup', function(e) {
			stopScrolling();
			if(observeClicks) {
				observeClicks = false;
				if(Math.abs(clickMouseDelta) < 5) {
					var clickedID = e.findElement(".clickArea").id;
					clickLink(clickedID);
				}
			}
			e.stop();
		});
	});
}

function clickLink(clickedID) {
	switch(language) {
		case 0:
			var tmpClickedID = clickedID + "_en";
			break;
		case 1:
			var tmpClickedID = clickedID + "_de";
			break;
	}
	switch(links[tmpClickedID][1]) {
		case 0:
			window.open(links[tmpClickedID][0]);
			break;
		case 4:
			window.location = links[tmpClickedID][0];
			break;
		case 1:
			deactivateScrollers();
			stopObservingMenuButtons();
			stopObservingLanguageButtons();
			hideInfoArea(1.0);
			contentAnimateOpacity(1,0, function() {
				$('preloader').fade( { duration: 0 } ).setStyle( { zIndex: "998" } );
				if(isIE) {
					var transitionSpeed = 0;
				} else {
					var transitionSpeed = 0.5;
				}
				preloaderInterval = setInterval(function() {
					$('preloader').setStyle( { backgroundPosition: '0px ' + -(preloaderCounter * 18) + 'px' } );
					preloaderCounter++;
					if(preloaderCounter > 19) {
						preloaderCounter = 0;
					}
				}, 100);
				$('preloader').appear( { duration: transitionSpeed, afterFinish: function() {
					var imagePreloader = new Image();
					imagePreloader.onload = function() {
						$('imageViewer').fade( { duration: 0 } ).setStyle( { zIndex: "999" } );
						switch(links[tmpClickedID][2]) {
							case 0:
								var imgClass = "imgStandAlone";
								break;
							case 1:
								var imgClass = "imgClassBordered";
								break;
						}
						$('imageViewer').update('<img id=\"imageViewerPic\" class=\"' + imgClass + '\"> </img>');
						$('imageViewerPic').src = links[tmpClickedID][0];
						var maxWidth = imagePreloader.width + 50;
						var maxHeight = imagePreloader.height + 50;
						if(maxWidth > document.viewport.getDimensions().width || maxHeight > document.viewport.getDimensions().height) {
							if((document.viewport.getDimensions().width / document.viewport.getDimensions().height) > (maxWidth / maxHeight)) {
								// Image aspect is higher than viewport - so the hight is what counts
								var newHeight = document.viewport.getDimensions().height - 50;
								var newWidth = imagePreloader.width / (imagePreloader.height / newHeight);
								var paddingLeft = -(newWidth/2);
								var paddingTop = -(newHeight/2);
								$('imageViewerPic').setStyle( { width: newWidth + 'px', height: newHeight + 'px', margin: paddingTop + 'px 0px 0px ' + paddingLeft + 'px' } );
							} else {
								// Image aspect is wider than viewport - so the width is what counts
								var newWidth = document.viewport.getDimensions().width - 50;
								var newHeight = imagePreloader.height / (imagePreloader.width / newWidth);
								var paddingLeft = -(newWidth/2);
								var paddingTop = -(newHeight/2);
								$('imageViewerPic').setStyle( { width: newWidth + 'px', height: newHeight + 'px', margin: paddingTop + 'px 0px 0px ' + paddingLeft + 'px' } );
							}
						} else {
							var newWidth = imagePreloader.width;
							var newHeight = imagePreloader.height;
							var paddingLeft = -(newWidth/2);
							var paddingTop = -(newHeight/2);
							$('imageViewerPic').setStyle( { width: newWidth + 'px', height: newHeight + 'px', margin: paddingTop + 'px 0px 0px ' + paddingLeft + 'px' } );
						}
						$('preloader').fade( { duration: transitionSpeed, afterFinish: function() {
							clearInterval(preloaderInterval);
							$('imageViewer').appear( { duration: transitionSpeed, afterFinish: function() {
								closeImgHandler = function(e) {
									document.stopObserving('click', closeImgHandler);
									$('imageViewer').fade( { duration: transitionSpeed, afterFinish: function() {
										observeMenuButtons();
										observeLanguageButtons();
										activateScrollers();
										contentAnimateOpacity(0,1);
										showInfoArea(1.0);
									}});
									e.stop();
								}
								document.observe('click', closeImgHandler);
							}});
						}});
					}
					imagePreloader.src = links[tmpClickedID][0];
				}});
			});
			break;
		case 2:
			// Video Player not yet implemented
			break;
	}
}

function stopScrolling() {
	for(i=0; i<scrollPosition.length; i++) {
		scrollingDuration[i] = 0.3;
		scrollingActivated[i] = false;
	}
}

function startScrolling() {
	scrollerInterval = setInterval(function() {
		var stopInterval = -1;
		var newMilliSeconds = new Date().getTime();
		deltaTime = (newMilliSeconds - prevMilliSeconds) / 1000;
		prevMilliSeconds = newMilliSeconds;
		for(i=0; i<scrollPosition.length; i++) {
			if(scrollingActivated[i]) {
				if(reboundingVelocity[i] != 0) {
					reboundingVelocity[i] = 0.0;
				}
				mouseXDelta[i] = mouseXStart[i] - mouseXPosition;
				mouseXStart[i] = mouseXPosition;
				scrollingDuration[i] = 0.05;
				if(smoothedMouseXDelta[i] > 0.1 || smoothedMouseXDelta[i] < -0.1 || mouseXDelta[i] != 0) {
					smoothedMouseXDelta[i] = scrollDamped(i, smoothedMouseXDelta[i], mouseXDelta[i], 0);
					scrollPosition[i] -= smoothedMouseXDelta[i];
					scrollContent(i);
				}
				if(smoothedMouseXDelta[i] <= 0.1 && smoothedMouseXDelta[i] >= -0.1) {
					scrollingVelocity[i] = 0.0;
					smoothedMouseXDelta[i] = 0.0;
				}
			} else {
				mouseXDelta[i] = 0;
				if(smoothedMouseXDelta[i] > 0.1 || smoothedMouseXDelta[i] < -0.1) {
					scrollingDuration[i] = 0.3;
					smoothedMouseXDelta[i] = scrollDamped(i, smoothedMouseXDelta[i], mouseXDelta[i], 0);
					scrollPosition[i] -= smoothedMouseXDelta[i];
					scrollContent(i);
				} else if(smoothedMouseXDelta[i] <= 0.1 && smoothedMouseXDelta[i] >= -0.1) {
					if(!rebounding[i]) {
						stopInterval++;
					}
					scrollingVelocity[i] = 0.0;
					smoothedMouseXDelta[i] = 0.0;
				}
			}
			mouseXStart[i] = mouseXPosition;
			calcRebound(i);
		}
		if(stopInterval == scrollPosition.length-1) {
			var stopActually = true;
			for(i=0; i<scrollPosition.length; i++) {
				if(rebounding[i]) stopActually = false;
			}
			if(stopActually){
				clearInterval(scrollerInterval);
				scrollerInterval = null;
			}
		}
	}, (1000/scrollerFPS));
}

function calcRebound(scrollerID) {
	var elementWidth = parseInt($(getScroller(scrollerID)).getStyle('width'))+110 || 0;
	var documentWidth = document.viewport.getDimensions().width;
	rebounding[scrollerID] = false;
	if(scrollPosition[scrollerID] > 0 && !scrollingActivated[scrollerID]) {
		rebounding[scrollerID] = true;
		scrollPosition[scrollerID] = scrollDamped(scrollerID, scrollPosition[scrollerID], 0.0, 1);
		scrollContent(scrollerID);
		if(scrollPosition[scrollerID] < 0.5) {
			scrollPosition[scrollerID] = 0;
		}
	} else if(elementWidth > documentWidth && !scrollingActivated[scrollerID]) {
		if(scrollPosition[scrollerID] < (documentWidth - elementWidth)) {
			rebounding[scrollerID] = true;
			scrollPosition[scrollerID] = scrollDamped(scrollerID, scrollPosition[scrollerID], (documentWidth - elementWidth), 1);
			scrollContent(scrollerID);
		}
	} else if(scrollPosition[scrollerID] <= -0.5 && elementWidth <= documentWidth && !scrollingActivated[scrollerID]) {	
		rebounding[scrollerID] = true;
		scrollPosition[scrollerID] = scrollDamped(scrollerID, scrollPosition[scrollerID], 0.0, 1);
		scrollContent(scrollerID);
		if(scrollPosition[scrollerID] > -0.5) {
			scrollPosition[scrollerID] = 0;
		}
	}
}

function scrollDamped(scrollerID, current, target, mode) {
	var time = Math.max(0.0001, scrollingDuration[scrollerID]);
	var velocity = 0.0;
	switch(mode) {
		case 0:
			velocity = scrollingVelocity[scrollerID];
			break;
		case 1:
			velocity = reboundingVelocity[scrollerID];
			break;
	}
	
	var alpha = 2.0 / time;
	var beta = alpha * deltaTime;
	var pidControler = 1.0 / (((1.0 + beta) + ((0.5 * beta) * beta)) + (((0.25 * beta) * beta) * beta));
	var error = current - target;
	var tmpTarget = target;
	target = current - error;
	var gamma = (velocity + (alpha * error)) * deltaTime;
	velocity = (velocity - (alpha * gamma)) * pidControler;
	current = target + ((error + gamma) * pidControler);
	if(((tmpTarget - current) > 0.0) == (current > tmpTarget)) {
		current = tmpTarget;
		velocity = (current - tmpTarget) / deltaTime;
	}
	
	switch(mode) {
		case 0:
			scrollingVelocity[scrollerID] = velocity;
			break;
		case 1:
			reboundingVelocity[scrollerID] = velocity;
			break;
	}
	
	return current;
}

function stopObservingMenuButtons() {
	$$('.clickArea').each(function(clickElement) {
		clickElement.stopObserving('mousedown').setStyle( { cursor: " default" } );
	});
	$$('.menuClickArea').each(function(menuElement) { 
		menuElement.stopObserving('click').setStyle( { cursor: "default" } );
    });
}

function getScroller(scrollerID) {
	switch(scrollerID) {
		case 0:
			return 'aboutUsContent';
		case 1:
			return 'realtime3dContent';
		case 2:
			return 'softwareContent';
		case 3:
			return 'threeDRenderingsContent';
		case 4:
			return 'twoDDesignContent';
		case 5:
			return 'contactContent';
		case 6:
			return 'legalNoticeContent';
	}
}

function scrollContent(scrollerID) {
	var scrollString = scrollPosition[scrollerID] + "px";
	$(getScroller(scrollerID)).setStyle( { left: scrollString } );
}

function getUrlVars() {
	var vars = [], hash;
	var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');

	for(var i = 0; i < hashes.length; i++) {
		hash = hashes[i].split('=');
		vars.push(hash[0]);
		vars[hash[0]] = hash[1];
	}
	return vars;
}

function debug(pMessage) {
	try {
		console.log(pMessage);
	} catch(e) {
		alert(pMessage);
	}
}

































