if(typeof Widget == "undefined") Widget = {};
/**
 * The Widget.Fader class constructor. <br />
 * @constructor Widget.Fader
 * @param {string|img element} img The id of or actual image element to be faded
 * @param {array(string)} list  An array of paths (relative or absolute) of the images
 * @param {object} [options] An object of options.
 */
Widget.Fader = Class.create(/** @scope Widget.Fader **/{
	initialize: function(div, list, options) {
		this.div = $(div);
		this.list = list;

		/**
		 * The default options object.
		 * @class
		 * @param {string} [id] The id used as queue scope. (default: img.id)
		 * @param {float} [fadeInDuration] The time in seconds of the fade in. (default: 2.5)
		 * @param {float} [fadeOutDuration] The time in seconds of the fade out. (default: 1.5)
		 * @param {float} [displayDuration] The time in seconds that the image is not faded out after being faded in. (default: 2.5)
		 * @param {string} [dir] The directory that all images reside in. Used as a prefix for the image src. (default: null)
		 */
		this.options = Object.extend({
			id: this.div.id,
			fadeInDuration: 2.5,
			fadeOutDuration: 1.5,
			displayDuration: 2.5,
			dir: ""
		}, options || {});
		//this.options.attributes["id"] = this.options.id;

		this.index = 0;
		this.fadeInObserver = this.fadeIn.bind(this);
		this.nextObserver = this.next.bind(this);
		setTimeout(this.start.bind(this), this.options.displayDuration * 1000);
	},
	/**
	 * Starts the fading if the autoStart option was set to false or after a call to stop.
	 * @function
	 */
	start: function() {
		this.next();
	},
	
	/**
	 * Stops the fading and sets the opacity of the current image to 100%.
	 * @function
	 */
	stop: function() {
		this.stopped = true;
		try { clearTimeout(this.timeout); } catch(ex) { }
		try { Effect.Queues.get(this.options.id).each(function(effect) { effect.cancel() }) } catch(ex) { }
	},
	
	/**
	 * Loads the next image in list
	 * @private
	 * @function
	 */
	next: function() {
		new Effect.Opacity(this.div, { duration: this.options.fadeOutDuration, from: 1.0, to: 0.0, queue: { scope: this.options.id } });
		this.timeout = setTimeout(this.fadeInObserver, this.options.fadeOutDuration * 1000);
	},
	/**
	 * Event listener for fadeIn
	 * @private
	 * @function
	 */
	fadeIn: function() {
		//Ensure element is hidden and remove image style
		//Element.setOpacity(this.div, 0);
		$(this.div).toggleClassName(this.list[this.index]);
		
		++this.index;
		if(this.index >= this.list.length) {
			this.index = 0;
		}
		
		$(this.div).toggleClassName(this.list[this.index]);
		new Effect.Opacity(this.div, { duration: this.options.fadeInDuration, from: 0.0, to: 1.0, queue: { scope: this.options.id } });

		this.timeout = setTimeout(this.nextObserver, (this.options.fadeInDuration + this.options.displayDuration) * 1000);
	}
	
});