/*--------------------------------------------------------------------------*
 * 
 * Copyright (C) 2008 Brand Labs LLC
 * 
 * Sequential Banner
 * 
 * Version 1.2.1
 * 
 *--------------------------------------------------------------------------*/
var Banner = Class.create({
	/**
	 * 
	 * @param {Object} link
	 * @param {Object} imageSrc
	 */
	initialize: function(link, imageSrc) {
		this.link = link;
		this.imageSrc = imageSrc;
	},
	
	/**
	 * 
	 */
	getElement: function() {
		var anchorElement = null;
		var imageElement = null;
		
		anchorElement = new Element('a', {href: this.link});
		imageElement = new Element('img', {src: this.imageSrc});
		
		//Add the image under the anchor
		anchorElement.insert(imageElement);
				
		return anchorElement;
	}
});

var SingleEventBanner = Class.create(Banner, {
	/**
	 * 
	 * @param {Object} imageSrc
	 * @param {Object} eventName
	 * @param {Function} handler
	 */
	initialize: function(imageSrc, eventName, handler) {
		this.imageSrc = imageSrc;
		this.eventName = eventName;
		this.handler = handler;
	},
	
	/**
	 * 
	 */
	getElement: function() {
		var imageElement = null;
		
		imageElement = new Element('img', {src: this.imageSrc});
		
		//Add the event handler to the image
		imageElement.observe(this.eventName, this.handler.bind(this));
				
		return imageElement;
	}
});
	
var SequentialBanner = Class.create({
	/**
	 * 
	 * @param {Object} banners
	 * @param {Object} elementName
	 * @param {Object} delay
	 */
	initialize: function(banners, elementName, delay) {
		this.listeners = new Array();
		this.currentPosition = 0;
		this.element = null;
		
		this.banners = banners;
		this.delay = delay;
		
		Event.observe(window, 'load', this.load.bindAsEventListener(this, elementName));
		
		//Pre-load images
		this.banners.each(function(item){
			item.getElement();
		});
	},
	
	addListener: function(func) {
		//Only add if function
		if (Object.isFunction(func)) {
			//Push onto array
			this.listeners.push(func);
		}
	},
	
	/**
	 * 
	 */
	load: function() {
		var args = $A(arguments);
		args.shift();
		
		//Get the element
		this.element = $(args.first());
		
		//Start the executer
		this.start();
	},
	
	/**
	 * 
	 */
	start: function() {
		if(this.pe != null) {
			this.stop();				
		}
		this.pe = new PeriodicalExecuter(this.execute.bindAsEventListener(this), this.delay);			
	},
	
	/**
	 * 
	 */
	stop: function() {
		if(this.pe != null) {
			this.pe.stop();
			this.pe = null;
		}
	},
	
	/**
	 * 
	 */
	execute: function() {
		var index = null;
		var args = $A(arguments);
		
		//Check for an index argument
		if(args.size() > 0 && Object.isNumber(args.first())) {
			//Get the argument and set it as the current index
			index = args.first();
			this.currentPosition = index;
			this.stop();
			this.start();
		}
		else {
			this.currentPosition++;
			this.currentPosition = this.currentPosition % this.banners.size();			
		}		
	
		this.updateElement();
		
		//Inform listeners of change
		this.listeners.each(function(listener) {
			try {
				listener(this.currentPosition);
			}
			catch(e) {/*No-op*/}
		}, this);
	},
	
	/**
	 * 
	 */
	updateElement: function() {
		this.element.update(this.banners[this.currentPosition].getElement());
	}
});

var RandomBanner = Class.create(SequentialBanner, {
	/**
	 * 
	 * @param {Object} banners
	 * @param {Object} elementName
	 * @param {Object} delay
	 */
	initialize: function(banners, elementName) {
		this.listeners = new Array();
		this.currentPosition = 0;
		this.element = null;
		
		this.banners = banners;

		//On window load, display a random image		
		Event.observe(window, 'load', this.load.bindAsEventListener(this, elementName));
	},
	
	/**
	 * 
	 */
	load: function() {
		var args = $A(arguments);
		args.shift();
		
		//Get the element
		this.element = $(args.first());
		
		//Select random element
		this.currentPosition = Math.floor(Math.random() * this.banners.size());
		
		//Display element 
		this.execute();
	}	
});