(function() {
	var __rotators = [];
	Event.observe(window, 'load', function(){
		$$(".__rotator").each(function(obj){
			__rotators.push(new __rotator(obj));
		});
	});
	var __rotator = Class.create({
		options:{
			duration:3000,
			fadetime:1000,
			controls:true,
			autoplay:false,
			mode : "Fade",
			supportedModes : new Array("Squish", "Fade", "Puff", "Shrink","Fold"),
			currentBanner : -1
		},
		initialize: function(obj){
			that = this;
			this.rotatorID = __rotators.length;
			this.obj = obj;
			this.transition_in_progress=false;
			
			if (!obj.id) obj.id = "__rotator_banner_" + this.rotatorID;
			dummy = $("__rotator_banner_" + this.rotatorID);
			
			//get options from title of rotator obj an write them to this.options, remove title afterwards
			options = obj.title.getOptions();obj.title="";
			if (options.mode){this.options.mode=options.mode;}
			if (options.fadetime){this.options.fadetime=parseInt(options.fadetime);}
			if (options.duration){this.options.duration=parseInt(options.duration);}
			if (options.controls){this.options.controls=!!parseInt(options.controls);}
			
			this.banners = [];
			this.controls = [];
			banners = $A(obj.select("*"));
			
			// only allow direct children ... is there a better method therefore?	
			l=banners.length;		
			for (i=0;i<l;i++) if (banners[i].parentNode == that.obj) this.banners.push(banners[i]);
			
			//preformat the banners
			this.banners.each(function(obj){that.formatBanner(obj);});
			
			if(this.options.controls){
				var __controls = Builder.node('ul', { id:obj.id+'-controls',className:'__rotator_controls' });
				l=this.banners.length;		
				for (i=0;i<l;i++){
					target = "__rotator_controls_button_"+i;
					label = this.banners[i].label?this.banners[i].label:(i+1);
					button = Builder.node('li', {},[
						Builder.node('a', {id:target,name:i},label)
					]);
					
					__controls.appendChild(button);
				}
				obj.appendChild(__controls);
				
				$A(__controls.getElementsByTagName("a")).each(function(obj){
					to = obj.title;
					Event.observe(obj, 'click', function(){
						if(!that.transition_in_progress && that.options.currentBanner!=obj){
							window.clearTimeout(that.timeout);
							that.jump(obj.name);
						}
					});
					that.controls[that.controls.length] = obj;
				});
				
			}
			//start the show
			this.next();
			//Event.observe("home-headline", 'click', function(){window.clearTimeout(that.timeout);that.prev();});
			
			
			return this;
		},
		formatBanner: function(obj){
			width = this.obj.getWidth();
			height = this.obj.getHeight();

			obj.setStyle({
				position:"absolute",left:"0",top:"0",width:width+"px",height:height+"px",overflow:"hidden",zIndex:"1",display:"none"
			});
			obj.label = obj.title ? obj.title : false;
			// set default ids for elements without one and extend them by calling $(..)
			if (!obj.id) obj.id = "__rotator_banner_" + this.rotatorID + "_" + parseInt(Math.random()*100);
			dummy = $(obj.id);
		},
		next: function(){
			repeatAfter=this.options.duration+this.options.fadetime;
			this.play(1);
			that = this;
			if (repeatAfter>0) this.timeout = setTimeout(function(){that.next(repeatAfter)},repeatAfter);
		},
		prev: function(){
			repeatAfter=this.options.duration+this.options.fadetime;
			this.play(-1);
			that = this;
			if (repeatAfter>0) this.timeout = setTimeout(function(){that.prev(repeatAfter)},repeatAfter);
		},
		jump: function(to){
			current = this.options.currentBanner;
			next = this.banners[to] ? to : 0;
			this.transition(current,next);
			this.options.currentBanner = next;
		},
		play: function(step) {
			current = this.options.currentBanner;
			total = this.banners.length;
			next = current+step;
			next = next<0 || next>=total? next+Math.ceil(-next/total)*total : next;
			this.transition(current,next);
			this.options.currentBanner = next;
		},
		transition: function(current,next){
			if (current==next) return;
			that = this;
			this.controls[next].addClassName("current");
			next = this.banners[next];
			if (current<0){
				next.setStyle({zIndex:"10",display:"block"});
			}
			else{
				this.transition_in_progress=true;
				this.controls[current].removeClassName("current");
				current= this.banners[current];
				current.setStyle({zIndex:"11"});
				next.setStyle({zIndex:"10"});
				new Effect.Parallel([
					new Effect.Appear(next.id, { duration: this.options.fadetime/1000}),
					new Effect.Fade(current.id, { duration: this.options.fadetime/1000, afterFinish:function(){current.setStyle({zIndex:"1"});that.transition_in_progress=false;}})
					],{
					
					});
				
			}
		}
	});
	
	String.prototype.getOptions = function() {
		var data = this.match(/\[[a-zA-Z]+::[a-zA-Z0-9_;\+%\-# \.\?\!\\\/:=&\|\(\)\{\}]+\]/g);
		var tmp = [];
		var valArray = [];
		var params = {};
		for (var i=0; i<data.length; i++) {
			tmp = data[i].replace(/[\[\]]/g,"").split("::");
			if (tmp==undefined || tmp[0]==undefined || tmp[1]==undefined) continue;
			if (!tmp[1].match(/\|/g)) params[tmp[0]] = tmp[1];
			else {
				valArray = tmp[1].split("|");
				params[tmp[0]] = valArray;
			}
		}
		return params;
	}

})();