





(function($, undefined){
	
	$(window).load(function(){
		fullyLoaded.isLoaded = true;
		fullyLoaded();
	});
	
	/*$.fn.preload = function(options){
		options = $.extend({
			allDone: function(){},
			progress: function(info){}
		}, options);
		
		var _this = this, total = _this.length, loaded = 0;
		
		_this.load(function(){
			this.isLoaded = this.isLoaded || false;
			console.debug(this.isLoaded);
			if (!this.isLoaded) {
				this.isLoaded = true;
				loaded++;
				
				options.progress({
					loaded: loaded,
					total: total,
					$element: $(this)
				});
				
				if (loaded == total) {
					options.allDone.apply(_this);
				}
			}
			
		}).each(function(){
			if (this.complete) {
				$(this).trigger('load');
			}
		});
	};*/
	
	var fullyLoaded = function(callback){
		fullyLoaded.isLoaded = fullyLoaded.isLoaded || false;
		fullyLoaded.callbacks = fullyLoaded.callbacks || [];
		
		if (callback !== undefined) {
			if (fullyLoaded.isLoaded) {
				callback();
			} else {
				fullyLoaded.callbacks.push(callback);
			}
		} else {
			$.each(fullyLoaded.callbacks, function(){
				this();
			});
		}
	};
	
	var Vector = function(x, y){
		this.x = x;
		this.y = y;
	}
	
	var CarouselItem = function(o){
		var _this = this;
		var leftItem = o.leftItem;
		var viewportSize = o.viewportSize;
		var position = new Vector(0,0);
		var MARGIN = 80;
		
		var p, scale, originalSize, rightItem, depth;
		
		_this.$element = o.$element;
		_this.$img = _this.$element.children('img');
		_this.size = originalSize = new Vector(_this.$img.width(), _this.$img.height());
		_this.queuePosition = leftItem === null ? 0 : leftItem.queuePosition + 1;
		_this.selectedPosition = o.selectedPosition;
		
		/*var image = $img.attr('src');
		$img.remove();*/
		
		/*var maxHeight = 355;
		size = new Vector(size.x, maxHeight);*/
		
		_this.$element.css({
			position: 'absolute'
			/*width: size.x + 'px',
			height: size.y + 'px',
			backgroundImage: 'url(' + image +')'*/
		});
		
		_this.$element.attr('tabindex', -1);
		
		var updateSize = function(){
			depth = Math.abs(_this.queuePosition - _this.selectedPosition);
			scale = 1 / (1 + depth * 0.7);
			
			_this.size = new Vector(
				originalSize.x * scale,
				originalSize.y * scale
			);
			
			_this.$img.animate({
				width: _this.size.x + 'px',
				height:  _this.size.y + 'px'
			}, {
				queue: false
			});
		};
		
		var setPosition = function(p){
			position = p;
		};
		
		_this.getCurrentPosition = function(){
			return position;
		};
		
		/*var getPosition = function(){
			
		};*/
		
		_this.alignLeft = function(right){
			rightItem = right;
			
			p = rightItem.getCurrentPosition();
			
			updateSize();
			
			setPosition(new Vector(
				//p.x + o.prev.size.x,
				p.x - _this.size.x - MARGIN,
				viewportSize.y / 2 - _this.size.y / 2
			));
			
			_this.update();
			
			if (leftItem !== null) {
				leftItem.alignLeft(_this);
			}
		};
		
		_this.update = function(){
			//depth = Math.round((6 - this.p.z) * 50);    // 0-100
			if (_this.selectedPosition == _this.queuePosition) {
				updateSize();
				
				setPosition(new Vector(
					viewportSize.x / 2 - _this.size.x / 2,
					viewportSize.y / 2 - _this.size.y / 2
				));
				
				if (leftItem !== null) {
					leftItem.alignLeft(_this);
				}
			
			} else if (_this.queuePosition > _this.selectedPosition) {
				updateSize();
				
				p = leftItem.getCurrentPosition();
				
				setPosition(new Vector(
					p.x + leftItem.size.x + MARGIN,
					viewportSize.y / 2 - _this.size.y / 2
				));
			}
			/*if (o.prev !== null) {
				p = o.prev.getCurrentPosition();
				
				position = new Vector(
					p.x + o.prev.size.x,
					o.viewportSize.y / 2 - _this.size.y / 2
				);
				
			} else {
				position = new Vector(0, o.viewportSize.y / 2 - _this.size.y / 2);
			}*/
			
			_this.$element.css({
				//left: position.x + 'px',
				//top: position.y + 'px',
				'z-index': 100 - depth
				//opacity: (6 - this.p.z) /  2,
			});
			
			/*animX = oldPosition.x;
			vX = (position.x - oldPosition.x) / 20;
			console.debug(animX, vX);
			var i = 0;
			timerX = setInterval(function(){
				if (i++ == 20) {
					clearInterval(timerX);
					animX = null
					vX = null;
					return;
				}
				
				animX += vX;*/
				_this.$element.animate({
					left: position.x + 'px',
					top: position.y + 'px'
				}, {
					queue: false
				});
			//}, 13);
			
			
		};
		
		if (_this.queuePosition >= _this.selectedPosition) {
			_this.update();
		}
	};
	
	var Carousel = function($e, options){
		var _this = this;
		
		options = $.extend({
			$description: null
		}, options);
		
		$e.css({
			overflow: 'hidden',
			position: 'relative'
		});
		
		var viewportSize = new Vector(
			$e.width(),
			$e.height()
		);
		
		var items = [];
		var current = $e.children('a').length < 2 ? 0 : 1;
		/*var loadQueue = [];
		var loaded = 0;*/
		var $description;
		
		var updateDescription = function(){
			$description.html(items[current].$img.attr('alt'));
		};
		
		var updateAll = function(){
			$.each(items, function(){
				this.selectedPosition = current;
				this.update();
			});
			
			updateDescription();
		};
		
		_this.addItems = function($items){
			//loadQueue.push($i);
			//console.debug(new Date());
			$items.hide();  //.children('img').preload({
			
			fullyLoaded(function(){
				//loaded++;
				//console.debug(loaded + ' / ' + loadQueue.length + ' loaded');
				
				/*if (loaded == loadQueue.length) {
					for (var i in loadQueue) {*/
				$.each($items, function(){
					items.push(new CarouselItem({
						$element: $(this).show(),
						leftItem: items.length > 0 ? items[items.length - 1] : null,
						viewportSize: viewportSize,
						selectedPosition: current
					}));
				});
					//}
				updateDescription();
				//}
			});
		};
		
		_this.next = function(){
			current = current < items.length - 1 ? current + 1 : 0;
			updateAll();
		};
		
		_this.prev = function(){
			current = current > 0 ? current - 1 : items.length - 1;
			updateAll();
		};
		
		if ($e.children('a').length > 1) {
			// Create left and right arrows
			$('<a/>', {
				href: 'javascript:;',
				'class': 'left',
				css: {
					zIndex: 200
				}
			}).appendTo($e).click(_this.prev)
				.clone().attr('class', 'right')
				.appendTo($e).click(_this.next);
			
			// Attach events to arrows
			/*$e.find('a.left, a.right').mouseover(function(){
				$(this).addClass('hover');
			}).mouseout(function(){
				$(this).removeClass('hover');
			});*/
		}
		
		if (options.$description === null) {
			// Create description element
			$description = $('<div/>', {
				'class': 'description',
				css: {
					zIndex: 199
				}
			}).appendTo($e);
		} else {
			$description = options.$description;
		}
		
		// Add all images
		_this.addItems($e.children('a').not('.left, .right'));
		/*$.each($e.children('a'), function(){
			_this.addItem($(this));
		});*/
		
		// Attach scroll event
		/*$e.mousewheel(function(e,d){
			console.debug(e,d);
			return false;
		});*/
	};
	
	$.carouselHelper = {
		carousels: {}
	};
	
	$.fn.extend({
		carousel: function(argument){
			var options = argument !== undefined && typeof(argument) == 'object' ? argument : {};
			
			$.carouselHelper.carousels[$(this).attr('id')] = $.carouselHelper.carousels[$(this).attr('id')] || new Carousel($(this), options);
			
			if (argument !== undefined && typeof(argument) == 'string') {
				$.carouselHelper.carousels[$(this).attr('id')][command]();
			}
		}
	});
	
})(jQuery);
