/*
	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SlideShow %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
	/**
	 *	SlideShow 
	 *
	 *	This class provides a slideshow like presentation
	 *
	 *	@param width the width of the slide show
	 *	@param height the height of the slide show
	 *
	 *	@constructor
	 */
	function SlideShow(width, height) {
		this.i_width = width;
		this.i_height = height;
		
		this.i_frames = Array();
	}
	
	/**
	 *	Get/Set the width of this slideshow
	 *
	 *	@param width (Optional) The new width of this slideshow
	 *
	 *	@return the current width of this slideshow
	 */
	SlideShow.prototype.width = function(width) {
		if (width != undefined) {
			this.i_width = width;
		}
		return this.i_width;
	}
	
	/**
	 *	Get/Set the height of this slideshow
	 *
	 *	@param height (Optional) The new height of this slideshow
	 *
	 *	@return the current height of the slideshow
	 */
	SlideShow.prototype.height = function(height) {
		if (height != undefined) {
			this.i_height = height;
		}
		return this.i_height;
	}
	
	/**
	 *	Get an array of all frames in this slideshow
	 *
	 *	@param index (Optional) An index into the slideshow frames array
	 *
	 *	@return the array of all slideshow frames, or a single frame if an index was provided
	 */
	SlideShow.prototype.frames = function(index) {
		if (index != undefined) {
			return this.i_frames[index];
		}
		return this.i_frames;
	}
	
	/**
	 *	Add a frame to the slideshow
	 *
	 *	@param frame The frame to add
	 *
	 *	@return the frame which was just added
	 */
	SlideShow.prototype.addFrame = function(frame) {
		this.i_frames[this.i_frames.length] = frame;
		frame.i_parent = this;
		return frame;
	}
	
	/**
	 *	Remove a frame from the slideshow
	 *
	 *	@param frame the frame to remove
	 *
	 *	@return true if the frame was removed, false otheriwse
	 */
	SlideShow.prototype.removeFrame = function(frame) {
		for (var x = 0; x < this.i_frames.length; x++) {
			if (this.i_frames[x] == frame) {
				this.i_frames.splice(x, 1);
				return true;
			}
		}
		return false;
	}
	
	/**
	 *	Advance to the next frame
	 *
	 *	@return true
	 */
	SlideShow.prototype.advance = function() {
		try {
			this.i_show.removeChild(this.i_frames[this.i_framex].getFrame());
		} catch (e) { }
	
		this.i_framex++;
		if (this.i_framex < this.i_frames.length) {
			var f = this.i_frames[this.i_framex];
			var fe = f.getFrame();
			fe.style.display = "none";
			fe.style.left = "5px"; //Math.floor(Math.random() * (this.width() - f.width())) + "px";
			fe.style.top = "5px"; //Math.floor(Math.random() * (this.height() - f.height())) + "px";
			this.i_show.appendChild(fe);
			fe.style.display = "";
			this.frames(this.i_framex).active(true, this.advance, this);
		}
		else {
			this.i_framex = -1;
			this.advance();
		}
	}
	
	/**
	 *	Get the DIV that contains this slide show
	 *
	 *	@return the DIV that contains this slide show
	 */
	SlideShow.prototype.getSlideShow = function() {
		if (this.i_show == undefined) {
			this.i_show = document.createElement('DIV');
			this.i_show.className = "SlideShow";
			this.i_show.style.width = this.width() + "px";
			this.i_show.style.height = this.height() + "px";
			
			this.i_framex = -1;
			this.advance();
		}
		return this.i_show;
	}
	
/*
	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SlideShowFrame %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
	/**
	 *	SlideShowFrame
	 *	This object provides a single frame in a slideshow
	 *
	 *	@param width The width of the frame
	 *	@param height The height of the frame
	 *	@param message The message to display for this frame
	 *
	 *	@constructor
	 */
	function SlideShowFrame(width, height, message) {
		this.i_width = width;
		this.i_height = height;
		this.i_message = message;
		this.i_frames = Array();
	}
	
	/**
	 *	Get the parent slide show
	 */
	SlideShowFrame.prototype.parent = function() {
		return this.i_parent;
	}
	
	/**
	 *	Get/Set the message to display for this frame
	 *
	 *	@param message (Optional) The new message to display for this frame
	 *
	 *	@return the current message for this frame
	 */
	SlideShowFrame.prototype.message = function(message) {
		if (message != undefined) {
			this.i_message = message;
		}
		return this.i_message;
	}
	
	/**
	 *	Get/Set the width of this frame
	 *
	 *	@param width (Optional) the new width of this frame
	 *
	 *	@return the current width of this frame
	 */
	SlideShowFrame.prototype.width = function(width) {
		if (width != undefined) {
			this.i_width = width;
		}
		return this.i_width;
	}
	
	/**
	 *	Get/Set the height of this frame
	 *
	 *	@param height (Optional) The new height of this frame
	 *
	 *	@return the current height of this frame
	 */
	SlideShowFrame.prototype.height = function(height) {
		if (height != undefined) {
			this.i_height = height;
		}
		return this.i_height;
	}
		
	/**
	 *	Get an array of all sub frames in this frame
	 *
	 *	@param index (Optional) An index into this frames sub frame array
	 *
	 *	@return the array of all sub frames in this frame, or a single sub frame if an index was provided
	 */
	SlideShowFrame.prototype.frames = function(index) {
		if (index != undefined) {
			return this.i_frames[index];
		}
		return this.i_frames;
	}
	
	/**
	 *	Add a sub frame to this frame
	 *
	 *	@param frame The sub frame to add
	 *
	 *	@return the sub frame which was just added
	 */
	SlideShowFrame.prototype.addFrame = function(frame) {
		this.i_frames[this.i_frames.length] = frame;
		return frame;
	}
	
	/**
	 *	Remove a sub frame from the slideshow
	 *
	 *	@param frame the sub frame to remove
	 *
	 *	@return true if the sub frame was removed, false otheriwse
	 */
	SlideShowFrame.prototype.removeFrame = function(frame) {
		for (var x = 0; x < this.i_frames.length; x++) {
			if (this.i_frames[x] == frame) {
				this.i_frames.splice(x, 1);
				return true;
			}
		}
		return false;
	}
	
	/**
	 *	Transition an image into the frame
	 */
	SlideShowFrame.prototype.trans = function(oldFrame, newFrame, callback) {
		if (this.i_in_trans == true) {
			this.i_trans_p-=1;
			if (this.i_trans_p < 0) {
				this.i_trans_p = 0;
			}
			this.i_frame2.style.filter = "alpha(opacity=" + this.i_trans_p + ")";
			this.i_frame2.style.MozOpacity = (this.i_trans_p / 100);
			this.i_frame2.style.opacity = (this.i_trans_p / 100);;
			this.i_frame2.style.KhtmlOpacity = (this.i_trans_p / 100);;
			

			if (this.i_trans_p == 0) {
				this.i_in_trans = false;
				callback();
			}
			else {
				var me = this;
				setTimeout(function() {
					me.trans(undefined, undefined, callback);	
				}, 1);
			}
		}
		else {
			this.i_frame.className = "SlideShowFrame " + newFrame.imageClass();
			if (oldFrame != undefined) {
				this.i_frame2.className = "SlideShowFrame_image " + oldFrame.imageClass();
				this.i_trans_p = 100;
				this.i_frame2.style.filter = "alpha(opacity=" + this.i_trans_p + ")";
				this.i_frame2.style.MozOpacity = (this.i_trans_p / 100);
				this.i_frame2.style.opacity = (this.i_trans_p / 100);;
				this.i_frame2.style.KhtmlOpacity = (this.i_trans_p / 100);;
				var me = this;
				this.i_in_trans = true;

				setTimeout(function() {
					me.trans(undefined, undefined, callback);	
				}, 1);
			}
			else {
				this.i_in_trans = false;
				callback();
			}
		}
	}
	
	/**
	 *	Advance to the next sub frame
	 *
	 *	@param callback The callback to execute when the last frame finishes
	 *	@param scope the scope to execute the callback in
	 *
	 *	@return true
	 */
	SlideShowFrame.prototype.nextFrame = function(callback, scope) {
		this.i_framex++;
		
		if (this.i_framex < this.i_frames.length) {
			var o = this.i_active_frame;
			this.i_active_frame = this.i_frames[this.i_framex];
			var me = this;
			if (this.i_framex == 0) {
				this.i_frame.className = "SlideShowFrame " + this.i_active_frame.imageClass();
				this.i_frame2.className = "SlideShowFrame_image";
			}
			setTimeout(function() {
				me.trans(o, me.i_active_frame, function() {
					me.nextFrame(callback, scope);
				});
			}, this.i_active_frame.delay());
			if (this.i_frame != undefined) {
				this.i_frameText.innerHTML = this.message();
				this.i_frame2.style.width = this.i_active_frame.imageWidth() + "px";
				this.i_frame2.style.height = this.height() + "px";
				this.i_frameText.style.width = (this.width() - this.i_active_frame.imageWidth()) + "px";
			}
		}
		else {
			var me = this;
			setTimeout(function() {
				me.fadeOut(callback, scope);
				me.i_active_frame = null;
			}, this.i_active_frame.delay());
			
		}
	}
	
	SlideShowFrame.prototype.fadeIn = function() {
		this.i_fade+=1;
		if (this.i_fade >= 100) {
			this.i_fade = 100;
		}
		this.i_frame.style.filter = "alpha(opacity=" + this.i_fade + ")";
		this.i_frame.style.MozOpacity = (this.i_fade / 100);
		this.i_frame.style.opacity = (this.i_fade / 100);;
		this.i_frame.style.KhtmlOpacity = (this.i_fade / 100);;
		if (this.i_fade != 100) {
			var me = this;
			setTimeout(function() {
				me.fadeIn();		
			}, 1);
		}
		
	}
	
	SlideShowFrame.prototype.fadeOut = function(callback, scope) {
		this.i_fade-=1;
		if (this.i_fade <= 0) {
			this.i_fade = 0;
		}
		this.i_frame.style.filter = "alpha(opacity=" + this.i_fade + ")";
		this.i_frame.style.MozOpacity = (this.i_fade / 100);
		this.i_frame.style.opacity = (this.i_fade / 100);
		this.i_frame.style.KhtmlOpacity = (this.i_fade / 100);
		if (this.i_fade == 0) {
			callback.call(scope);
		}
		else {
			var me = this;
			setTimeout(function() {
				me.fadeOut(callback, scope);
			}, 1);
		}
	}
	
	/**
	 *	Get/Set whether this frame should be running
	 *
	 *	@param state (Optional) The new running state of this frame
	 *	@param callback the function to execute when this frame completes
	 *	@param scope The scope to call the callback in
	 *
	 *	@return the current running state of this frame
	 */
	SlideShowFrame.prototype.active = function(state, callback, scope) {
		if (state != undefined) {
			this.i_active = state;
			if (this.i_active == true) {
				this.i_framex = -1;
				this.i_fade = 0;
				this.fadeIn();
				this.nextFrame(callback, scope);
				
			}
		}
		return this.i_active;
	}
	
	/**
	 *	Get the DIV that contains this frame
	 *
	 *	@return the DIV that contains this frame
	 */
	SlideShowFrame.prototype.getFrame = function() {
		if (this.i_frame == undefined) {
			this.i_frame = document.createElement('DIV');
			this.i_frame.className = "SlideShowFrame";
			this.i_frame.style.width = this.width() + "px";
			this.i_frame.style.height = this.height() + "px";
			this.i_frame.style.display = "none";
			
				this.i_frame2 = document.createElement('DIV');
				this.i_frame2.className = "SlideShowFrame_image";
				this.i_frame2.innerHTML = "&nbsp;";
				this.i_frame.appendChild(this.i_frame2);
				
				this.i_frameText = document.createElement('DIV');
				this.i_frameText.className = "SlideShowFrame_text";
				this.i_frame.appendChild(this.i_frameText);
		}
		return this.i_frame;
	}
	

/*
	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SlideShowSubFrame %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
	/**
	 *	SlideShowSubFrame
	 *
	 *	This class provides a sub frame object which will be dispalyed within a frame
	 *
	 *	@param delay The number of milliseconds to display this sub frame within the parent frame for
	 *	@param imageClass The CSS class name that defines the image for this frame
	 *	@param imageWidth The width of the image
	 *	@param message The message to display next to the image
	 *	@param orientation (Optional) Either "left" to have the image on left, or "right" to have the message on the left
	 *
	 *	@constructor
	 */
	function SlideShowSubFrame(delay, imageClass, imageWidth) {
		this.i_delay = delay;
		this.i_imageClass = imageClass;
		
		this.i_imageWidth = imageWidth;
	}
	
	/**
	 *	Get/Set the delay for this sub frame
	 *
	 *	@param delay (Optional) the number of miliseconds to display this frame for
	 *
	 *	@return the current number of miliseconds this frame will be displayed for
	 */
	SlideShowSubFrame.prototype.delay = function(delay) {
		if (delay != undefined) {
			this.i_delay = delay;
		}
		return this.i_delay;
	}
	
	/**
	 *	Get/Set the image class (css class name) that defines the image to display
	 *
	 *	@param imageClass (Optional) The new image class for this sub frame
	 *
	 *	@return the current image class for this sub frame
	 */
	SlideShowSubFrame.prototype.imageClass = function(imageClass) {
		if (imageClass != undefined) {
			this.i_imageClass = imageClass;
		}
		return this.i_imageClass;
	}
	
	/**
	 *	Get/Set the width of the image for this sub frame
	 *
	 *	@param width (Optioanl) The new width of the image
	 *
	 *	@return the current width of the image
	 */
	SlideShowSubFrame.prototype.imageWidth = function(width) {
		if (width != undefined) {
			this.i_imageWidth = width;
		}
		return this.i_imageWidth;
	}
	
	