(function() {
	var
	Y = YAHOO.util,
	Animation = Y.Anim,
	Easing = Y.Easing,
	Event = Y.Event,
	Dom = Y.Dom;
	
	function Album(el) {
		this.el = Dom.get(el);
		
		this.tools = {};
		this.texts = {};
		
		this.thumbs = [];
		
		Dom.getElementsByClassName('image', 'img', this.el, this.initImage, this, this);
		Dom.getElementsByClassName('toolbar', 'div', this.el, this.initToolbar, this, this);
		Dom.getElementsByClassName('viewport', 'div', this.el, this.initViewport, this, this);
		
		this.slideAnimation = new Animation(this.slide, { left: { to: 0 } }, 1, Easing.easeBothStrong);
		
		this.slideAnimation.onStart.subscribe(this._onStart, null, this);
		this.slideAnimation.onComplete.subscribe(this._onComplete, null, this);
		
		Dom.getElementsBy(Album.All, 'img', this.slide, this.initImages, this, this);
		
		this._onComplete();
		
		this._opacity();
		
		this.repeat = (function(scope, fn) {
			return function() {
				fn.apply(scope);
			};
		})(this, this.next);
	}
	
	Album.prototype = {
		zIndex: 100,
		active: 0,
		smallWidth: 90,
		bigWidth: 121,
		smallHeight: 67,
		bigHeight: 90,
		padding: 5,
		firstFrame: true,
		initImage: function(img) {
			this.image = img;
		},
		initToolbar: function(div) {
			this.toolbar = div;
			
			Dom.getElementsBy(Album.All, 'a', this.toolbar, this.initControllers, this, this);
		},
		initControllers: function(a) {
			this.tools[a.className] = a;
			
			Event.on(a, 'click', this._method, a, this);
		},
		initViewport: function(div) {
			this.viewport = div;
			
			Dom.getElementsByClassName('slide', 'div', div, this.initSlide, this, this);
		},
		initSlide: function(div) {
			this.slide = div;
			
			Dom.getElementsBy(Album.All, 'a', this.slide, this.initThumbs, this, this);
		},
		initThumbs: function(a) {
			Dom.setStyle(a, 'left', this.thumbs.length * this.smallWidth + this.thumbs.length * this.padding + this.padding + 'px');
			
			this.thumbs.push(a);
			
			var preload = new Image();
			preload.src = a.href;
			
			Event.on(a, 'click', this._clickEvent, a, this);
			
			var img = Dom.getFirstChild(a), anim = new Animation(img, { width: { to: 0 }, left: { to: 0 }, top: { to: 0} });
			
			anim.onStart.subscribe(this._zHandler, this);
			
			Event.on(img, 'mouseover', this._overEvent, anim, this);
			Event.on(img, 'mouseout', this._outEvent, anim, this);
		},
		initImages: function(img) {
			
			
			if(img.alt) {
				var el = document.createElement('div');
				
				el.innerHTML = img.alt;
				
				Dom.setStyle(el, 'position', 'absolute');
				Dom.setStyle(el, 'bottom', 104 + 'px');
				Dom.setStyle(el, 'color', '#fff');
				Dom.setStyle(el, 'zIndex', 100);
				Dom.setStyle(el, 'height', 0 + 'px');
				Dom.setStyle(el, 'overflow', 'hidden');
				Dom.setStyle(el, 'width', 570 + 'px');
				Dom.setStyle(el, 'fontSize', 16 + 'px');
				Dom.setStyle(el, 'lineHeight', 31 + 'px');
				Dom.setStyle(el, 'textAlign', 'center');
				Dom.setStyle(el, 'background', 'url(/images/bildtext.png)');
				
				this.el.appendChild(el);
				
				this.texts[img.parentNode.href] = new Animation(el, { height: { to: 31 }}, 1, Easing.easeBothStrong);
				
				this.texts[img.parentNode.href].onStart.subscribe(function() {
					Dom.setStyle(this.getEl(), 'display', 'block');
				});
				
				if(this.firstFrame && this.texts[img.parentNode.href]) {
					this.texts[img.parentNode.href].animate();
				}
			}
			/*
			if(img.complete && typeof img.naturalWidth != "undefined" && img.naturalWidth == 0) {
				this._onLoad(null, img);
			} else if(!img.complete) {
				var image = new Image();
				
				image.src = img.src;
				
				img.src = '/images/blank.gif';
				
				Dom.addClass(img.parentNode, 'loading');
				
				Event.on(image, 'load', this._onLoad, img);
			}*/
			this.firstFrame = false;
		},
		_method: function(e, a) {
			if(a.className != 'stop') {
				this.pause();
			}
			Event.stopEvent(e);
			
			this[a.className == 'stop' ? 'play' : a.className]();
		},
		_onLoad: function(e, img) {
			if(!e || typeof this.naturalWidth != "undefined" && this.naturalWidth == 0) {
				Dom.replaceClass(img.parentNode, 'loading', 'broken');
			} else {
				img.src = this.src;
			}
		},
		_onStart: function(e) {
			Dom.setStyle(this.thumbs, 'display', 'block');
			
			Dom.setStyle(this.viewport, 'overflow', 'hidden');
		},
		_onComplete: function(e) {
			Dom.setStyle(this.thumbs, 'display', 'none');
			
			var i = 6, x = Math.floor(-this.slideAnimation.getAttribute('left') / (this.smallWidth + this.padding) );
			
			while(i--) {
				Dom.setStyle(this.thumbs[i + x], 'display', 'block');
			}
			
			Dom.setStyle(this.viewport, 'overflow', 'visible');
		},
		_zHandler: function(type, args, album) {
			Dom.setStyle(this.getEl().parentNode, 'zIndex', album.zIndex++);
		},
		_clickEvent: function(e, el) {
			this.pause();
			Event.stopEvent(e);
			
			for(var i = 0; i < this.thumbs.length; i++) {
				if(el == this.thumbs[i]) {
					this.active = i;
					
					break;
				}
			}
			
			this.setImage(el.href);
		},
		_overEvent: function(e, anim) {
			anim.stop();
			
			Dom.setStyle(anim.getEl(), 'opacity', 1);
			
			anim.method = Easing.elasticOut;
			anim.attributes.width.to = this.bigWidth;
			anim.attributes.left.to = -(this.bigWidth - this.smallWidth) / 2;
			anim.attributes.top.to = -(this.bigHeight - this.smallHeight) / 2;
			
			anim.animate();
		},
		_outEvent: function(e, anim) {
			anim.stop();
			
			Dom.setStyle(anim.getEl(), 'opacity', this.thumbs[this.active] == anim.getEl().parentNode ? 1 : 0.5);
			
			anim.method = Easing.bounceOut;
			anim.attributes.width.to = this.smallWidth;
			anim.attributes.left.to = 0;
			anim.attributes.top.to = 0;
			
			anim.animate();
		},
		_opacity: function() {
			Dom.setStyle(this.slide.getElementsByTagName('img'), 'opacity', 0.5);
			
			Dom.setStyle(Dom.getFirstChild(this.thumbs[this.active]), 'opacity', 1);
		},
		setImage: function(src) {
			if(!this.proxy) {
				this.proxy = document.createElement('div');
				
				Dom.addClass(this.proxy, 'proxy');
				
				this.proxyAnimation = new Animation(this.proxy, { opacity: { from: 1, to: 0 }});
				
				this.el.appendChild(this.proxy);
			}
			
			Dom.setStyle(this.proxy, 'backgroundImage', 'url(' + this.image.src + ')');
			Dom.setStyle(this.proxy, 'opacity', 1);
			
			if(this.texts[this.image.src]) {
				this.texts[this.image.src].stop();
				
				this.texts[this.image.src].attributes.height.to = 0;
				
				this.texts[this.image.src].animate();
			}
			
			this.proxyAnimation.stop();
			
			this.proxyAnimation.animate();
			
			this.image.src = src;
			
			if(this.texts[src]) {
				this.texts[src].stop();
				
				this.texts[src].attributes.height.to = 31;
				
				this.texts[src].animate();
			}
			
			
			this._opacity();
		},
		first: function() {
			this.pause();
			if(this.active != 0) {
				this.active = 0;
				
				this.move();
			}
		},
		previous: function() {
			this.pause();
			if(this.active > 0) {
				this.active--;
				
				this.move();
			} else {
				this.last();
			}
		},
		play: function() {
			if(!this.interval) {
				this.interval = setInterval(this.repeat, 3000);
			} else {
				clearTimeout(this.interval);
				
				this.interval = false;
			}
			
			this.tools.play.className = this.interval ? 'stop' : 'play';
		},
		pause: function() {
			clearTimeout(this.interval);
			this.interval = false;
			this.tools.play.className = 'play';
		},
		next: function() {
			/*if(this.active < this.thumbs.length - 1) {
				this.active++;
				
				this.move();
			} else {
				this.first();
			}*/
			
			if(this.active < this.thumbs.length - 1) {
				this.active++;
			}
			else {
				this.active = 0;
			}
			
			this.move();
		},
		last: function() {
			this.pause();
			if(this.active != this.thumbs.length - 1) {
				this.active = this.thumbs.length - 1;
				
				this.move();
			}
		},
		move: function() {
			var viewstate = Math.floor(-this.slideAnimation.getAttribute('left') / (this.smallWidth + this.padding) );
			
			if(viewstate + 5 < this.active || viewstate > this.active) {
				this.slideAnimation.stop();
				
				this.slideAnimation.attributes.left.to = -(this.active * (this.smallWidth + this.padding) - (viewstate > this.active ? 0 : (5 * (this.smallWidth + this.padding) - this.padding)));
				
				this.slideAnimation.animate();
			}
			
			this.setImage(this.thumbs[this.active].href);
		}
	};
	
	Album.All = function() {
		return true;
	};
	
	Event.onDOMReady(function() {
		Dom.getElementsByClassName('album-view', 'div', document, function(div) {
			var album = new Album(div).play();
		});
	});
})();
