
var Fader = Class.create({
	
	initialize: function(element, images, options)
	{
		this.element = $(element);
		this.images = $A(images);
		this.preloaded = $A();
		this.index = 0;

		this.initializeOptions(options);
		this.initializeElement();
		
		this.preload();
		
		// create overlay
		var container = this.element.up();
				
		this.overlay = new Element('img', { style: 'display: none; z-index: 17; position: absolute;'});
		this.overlay.addClassName('foreground');
		this.overlay.src = this.preloaded[1].src;
		this.overlay.style.top = '0px';
		this.overlay.style.left = '0px';
		
		this.element.insert({after: this.overlay});
		
		this.start();
	}
	
	,initializeElement: function()
	{
		var position = this.getImagePosition(this.element);
		this.element.setStyle(position);	
	}
	
	,start: function()
	{
		this.next.bind(this).delay(
			this.getOption('delay')
		);
	}
	
	,next: function()
	{
		var self = this;
		
		this.index++;
		
		if (this.index >= this.preloaded.length)
			this.index = 0;
			
		var image = this.preloaded[this.index];
		var style = this.getImagePosition(image);
		
		this.overlay.src = image.src;
		this.overlay.setStyle(style);
		
		this.getOption('beforeEffect')(this.index);
		
		new Effect.Appear(
			this.overlay
			,{ 
				duration: 2
				,afterFinish: function() {
					self.element.setStyle(style);
					self.element.src = self.overlay.src;
					self.overlay.hide();
					
					self.getOption('afterEffect')(self.index);
					
					self.start();
				}
			}	
		);
	}
	
	,getImagePosition: function(image)
	{
		var style = {
			marginLeft: '0'
			,marginTop: '0'
			,width: image.width + 'px'
			,height: image.height + 'px'
		};
		
		// calculate the width
		if (this.getOption('width') > 0)
		{
			var offset = 0;
			
			switch (this.getOption('position').x)
			{
				case 'right':
					offset = this.getOption('width') - image.width;
					break;
					
				case 'center':
					offset = this.getOption('width') / 2 - image.width / 2;
					break;
			}
			
			style.marginLeft = offset + 'px';
		}
		
		// calculate the height
		if (this.getOption('height') > 0)
		{
			var offset = 0;
			
			switch (this.getOption('position').x)
			{
				case 'right':
					offset = this.getOption('height') - image.height;
					break;
					
				case 'center':
					offset = this.getOption('height') / 2 - image.height / 2;
					break;
			}
			
			style.marginTop = offset + 'px';
		}
		
		return style;
	}
	
	,preload: function()
	{
		var self = this;
		
		this.images.each(function(url) {
			self.preloaded.push(new Element('img', { src: url }));
		})
	}
	
	,getOption: function(option)
	{
		return this.options.get(option);
	}
	
	,initializeOptions: function(options)
	{
		var defaults = {
			delay: 3
			,beforeEffect: Prototype.emptyFunction
			,afterEffect: Prototype.emptyFunction
			,position: 'top left'
			,width: 0
			,height: 0
		};
		
		this.options = $H(defaults).merge($H(options));
		
		// fetch the position
		var p = this.options.get('position').split(' ');
		this.options.set('position', { x: p[1], y: p[0] });
	}
});