function debug(text) {
	if (!$('#debug').get(0)) $('body').append('<div id="debug" style="z-index:2000;position:absolute"><div>');
	$('#debug').html('<div>' + text + '</div>');
}


function Preloader(urls, callback, beforeLoadIfNotCached, waitForCacheTime){

//private properties
	var images = [];
	var howManyLoaded = 0;
	var currentCallback, timeout;

//private methods	
	var setCallback = function () {
		currentCallback = function(){
			clearTimeout(timeout);
			if (callback) callback();
		};
	};
	
	var onload = function () {
		howManyLoaded++;
		if (howManyLoaded == urls.length) currentCallback();
	};
	

//constructor
	if (typeof(urls) == 'string') urls = [urls];
	
	waitForCacheTime || (waitForCacheTime = Preloader.stdWaitTime);
	
	setCallback();
	if (beforeLoadIfNotCached) timeout = setTimeout(beforeLoadIfNotCached, waitForCacheTime);

	for (i = 0; i < urls.length; i++) {
		images[i] = new Image();
		images[i].onload = onload;
		images[i].onerror = currentCallback;
		images[i].src = urls[i];
	}
}

//static properties
Preloader.stdWaitTime = 100; // time to wait for file to be served from cache before assuming it is not cached (in milliseconds)









function Intro() {

	var waitDuration = 3000;
	var animDuration = 3000;
	var offsetImages = 2; //number of images to the left of the starting image
	var borderWidth = 200; //width of left and right border where mouseover won't start mouse action
	var scrollBorderWidth = 50; //distance from left and right border where scroll action should reach its maxima

	var self = this;
	var imageWidths = [];
	var numberOfImages = 0;
	var margin = parseInt($('#intro img').css('margin-right'));
	var totalWidth = 0;
	var easing = {
		easeOutExpo: function(x, t, b, c, d){
			return (t == d) ? b + c : c * (-Math.pow(Math.E, -10 * t / d) + 1) + b;
		}
	};
	var activeIndex = 0;
	var timeout;
	var offset = 0;
	var mouseActive = false;
	
	var manualAnimation = false;
	var ongoingAnimation = false;
	
	
	this.switchImage = function() {
		ongoingAnimation = true;
		$('#intro').css('cursor', 'default');
		var left = - offset - (imageWidths[activeIndex] + margin);
		$('#intro').animate({
			left: left
		}, animDuration, 'easeOutExpo', rearrangeImages);
	};
	
	var resetImages = function() {
		$('#intro').animate({
			left: - offset
		}, animDuration, 'easeOutExpo');
	};
	
	var rearrangeImages = function() {
		var img = $('#intro img:first').clone();
		$('#intro img:first').remove();
		offset = calculateOffset();
		$('#intro').append(img).css('left', - offset);
		var images = $('#intro img').clone();
		$('#intro').empty().append(images);
		activeIndex = (activeIndex + 1) % numberOfImages;
		if (!manualAnimation) setupAnimation();
		ongoingAnimation = false;
		$('#intro').css('cursor', 'pointer');
	};
	
	var setupAnimation = function() {
		stopMouseAction();
		timeout = setTimeout(self.switchImage, waitDuration);
	};
	
	var stopAnimation = function() {
		clearTimeout(timeout);
		$('#intro').stop();
	};
	
	var startMouseAction = function() {
		mouseActive = true;
		stopAnimation();
		var firstCall = true;
		var currentOffset = 0;
		var scrollWidth = 0;
		var mouseX = 0;
		var shortSide = 0;
		$('#intro').mousemove(function(event){
			scrollWidth = 2 * totalWidth - margin - $(window).width();
			if (firstCall) {
				mouseX = event.pageX;
				shortSide = mouseX < $(window).width() / 2 ? -1 : 1;
				currentOffset = parseInt($('#intro').css('left')) - (- ((scrollWidth) * getPositionFactor(event)));
				firstCall = false;
			}
			if (Math.abs(currentOffset) > 0) {
				var distanceFromBorder = getDistanceFromBorder(event);
				if (distanceFromBorder > 0) {
					if ((event.pageX - mouseX) / Math.abs(event.pageX - mouseX) == shortSide) {
						currentOffset -= 20 * (currentOffset / Math.abs(currentOffset));
						if (Math.abs(currentOffset) < 20) currentOffset = 0;
					}
					currentOffset = currentOffset - currentOffset / (distanceFromBorder / ($(window).width() - 2 * scrollBorderWidth) * scrollWidth);
				}
				else {
					currentOffset = 0;
				}
				if (Math.abs(currentOffset) < 5) currentOffset = 0;
				mouseX = event.pageX;
			}
			var left = Math.max(-scrollWidth, Math.min( 0, - ((scrollWidth) * getPositionFactor(event)) + currentOffset));
			$('#intro').css('left', left);
		});
	};
	
	var stopMouseAction = function() {
		$('#intro').unbind('mousemove');
	};
	
	var getPositionFactor = function(event) {
		var result = 
			Math.min(
				$(window).width() - scrollBorderWidth,
				Math.max(
					0, 
					parseInt(event.pageX - scrollBorderWidth)
				)
			) / (($(window).width() - scrollBorderWidth) - scrollBorderWidth);
		result = Math.min(1, result);
		return result;
	};
	
	var addImages = function() {
		var imageset = $('#intro img').clone();
		$('#intro').empty();
		var numberOfOffsetImagesets = Math.ceil(offsetImages / numberOfImages);
		for (var i = 0; i < numberOfOffsetImagesets; i++) {
			imageset.clone().prependTo('#intro');
		}
		for (var i = 0; i < numberOfImages - offsetImages; i++){
			$('#intro img:first').remove();
		}
		imageset.clone().appendTo('#intro');
		imageset.clone().appendTo('#intro');
		for (var i = 0; i < offsetImages; i++){
			$('#intro img:last').remove();
		}
		offset = calculateOffset();
		$('#intro').css('left', - offset);
	};
	
	var calculateOffset = function() {
		var offset = 0;
		$('#intro img').each(function(i){
			if (i < offsetImages) offset += $(this).width() + margin;
		});
		return offset;
	};
	
	var getDistanceFromBorder = function(event) {
//		return Math.min(parseInt(event.pageX), parseInt($(window).width() - event.pageX));
		return Math.min(
			Math.max(0, parseInt(event.pageX - scrollBorderWidth)),
			Math.min($(window).width() - scrollBorderWidth, parseInt($(window).width() - event.pageX - scrollBorderWidth))
		);
	};
	
	var borderLeaveListener = function(event) {
		if (getDistanceFromBorder(event) > borderWidth) {
			$('#intro').unbind('mousemove', borderLeaveListener);
			startMouseAction();
		}
	};
	
// constructor
	$('#intro').css('cursor', 'pointer');
	$.extend($.easing, easing);
	$('#intro img').each(function(i){
		imageWidths.push($(this).attr('width'));
		totalWidth += imageWidths[i];
		numberOfImages++;
	});
	totalWidth += numberOfImages * margin;
	addImages();
	setupAnimation();
	/*
	$('#intro').hover(
		function(event){
			var distanceFromBorder = getDistanceFromBorder(event);
			if (distanceFromBorder > borderWidth) {
				startMouseAction();
			}
			else {
				$('#intro').mousemove(borderLeaveListener);
			}
	}, 
		function(){
			if (mouseActive) {
				mouseActive = false;
				resetImages();
				setupAnimation();
			}
			$('#intro').unbind('mousemove', borderLeaveListener);
		}
	);*/
	$('#intro').click(function(event){
		if (!ongoingAnimation) {
			manualAnimation = true;
			stopAnimation();
			self.switchImage();
		}
	});

}



$(document).ready(function(){
	var imageNames = [];
	$('#intro img').each(function(i){
		imageNames.push($(this).attr('src'));
	});
	new Preloader(imageNames, function(){
		new Intro();
	});
});
