
// Create namespace ------------------------------------------------------------
if (!perpetuacms) {
	var perpetuacms = {};
}

// Eventbox class ------------------------------------------------------------
perpetuacms.eventbox = Class.create({
	initialize: function(element, settings) {
		var elementIsID = 1; // mark that we're passing an ID of an element
		this.isPaused = false;
		this.navigationIsPaused = false;
		this.isTransitioning = false;
		this.videoIsPlaying = false;
		this.flowplayerID = false;

		if (Object.isElement(element)) {
			elementIsID = 0; // mark that we're passing an actual element and not an ID
		}

		element = $(element);
		this.eventbox_container = element;
		this.eventbox_container.store("eventbox", this);

		// defaults
		var DefaultSettings = {
			delay: 3000,
			order: "sequential",
			type: "fade",
			duration: 0.50,
			showEmptyDescriptions: false,
			pauseOnMouseOver: true,
			effectDelay: 0,
			setAsBackground: false,
			transitionDescriptions: false,
			startPaused: false,
			firstSlide: 1,
			slider: {
				active: false,
				button_next: "", // class of the navigation's next button
				button_previous: "", // class of the navigation's previous button
				container: "", // class of the navigation's (ul's) parent
				orientation: "horizontal", // orientation of the slider [horizontal or vertical]
				step: 4,
				view: 4
			},
			video: {
				hideOverlay: false,
				popupSettings: {
					top: 50,
					padding: 10,
					backgroundColor: "#000",
					className: ""
				}
			}
		};

		if (!settings) { 
			settings = {};
		}

		this.settings = Object.extend(Object.extend({ }, DefaultSettings), settings);
		this.settings.slider = Object.extend(Object.extend({ }, DefaultSettings.slider), settings.slider);
		this.settings.video = Object.extend(Object.extend({ }, DefaultSettings.video), settings.video);
/*
		this.settings.video.popupSettings = Object.extend(Object.extend({ }, DefaultSettings.video.popupSettings), settings.video.popupSettings);
*/


		/* setup some call backs */
		this.onBeforeLoaded = this.settings.onBeforeLoaded || function(){};
		this.onLoaded = this.settings.onLoaded || function(){};
		this.onBeforePause = this.settings.onBeforePause || function(){};
		this.onPause = this.settings.onPause || function(){};
		this.onBeforeResume = this.settings.onBeforeResume || function(){};
		this.onResume = this.settings.onResume || function(){};
		this.onBeforeTransition = this.settings.onBeforeTransition || function(){};
		this.onTransition = this.settings.onTransition || function(){};
		
		this.onBeforeLoaded();
		
		// convert delay from seconds to milliseconds
		if (this.settings.delay < 100) {
			this.settings.delay = this.settings.delay / 0.001;
		}
		
		// load all the images into an object (makes manipulating the images easier)
		// if an ID of an element was passed
		if (elementIsID == 1) {
		    this.objWindowContainer = $(this.eventbox_container.identify() + "Window");
		    this.objWindow = this.objWindowContainer.select("div");

		    this.objNavigationContainer = $(this.eventbox_container.identify() + "Navigation");
		    this.objNavigation = this.objNavigationContainer.select("li");

		    this.objDescriptionsContainer = $(this.eventbox_container.identify() + "Descriptions");
		    this.objDescriptions = this.objDescriptionsContainer.select("div");
		    
		    if ($(this.eventbox_container.identify() + "Container")) {
		    	this.objContainer = $(this.eventbox_container.identify() + "Container");
		    }
		    
		    if ($(this.eventbox_container.identify() + "Overlay")) {
		    	this.objOverlay = $(this.eventbox_container.identify() + "Overlay");
		    }
		    
		    if ($(this.eventbox_container.identify() + "Anchor")) {
		    	this.objAnchor = $(this.eventbox_container.identify() + "Anchor");
		    }

			// get the dimensions of the window (for use later in setting the height of the images)
			this.windowDimensions = $(this.eventbox_container.identify() + "Window").getDimensions();

		// if an actual element was passed
		} else {
			this.base_class = $w(this.eventbox_container.className).first();

		    this.objWindowContainer = this.eventbox_container.down("." + this.base_class + "Window");
		    this.objWindow = this.objWindowContainer.select("div");

		    this.objNavigationContainer = this.eventbox_container.down("." + this.base_class + "Navigation");
		    this.objNavigation = this.objNavigationContainer.select("li");

		    this.objDescriptionsContainer = this.eventbox_container.down("." + this.base_class + "Descriptions");
		    this.objDescriptions = this.objDescriptionsContainer.select("div");

		    if (this.eventbox_container.down("." + this.base_class + "Container")) {
		    	this.objContainer = this.eventbox_container.down("." + this.base_class + "Container");
		    }

		    if (this.eventbox_container.down("." + this.base_class + "Overlay")) {
		    	this.objOverlay = this.eventbox_container.down("." + this.base_class + "Overlay");
		    }

		    if (this.eventbox_container.down("." + this.base_class + "Anchor")) {
		    	this.objAnchor = this.eventbox_container.down("." + this.base_class + "Anchor");
		    }

		    if (this.eventbox_container.down("." + this.base_class + "Play")) {
		    	this.objPlay = this.eventbox_container.down("." + this.base_class + "Play");
		    }

		    if (this.eventbox_container.down("." + this.base_class + "Stop")) {
		    	this.objStop = this.eventbox_container.down("." + this.base_class + "Stop");
		    }

		    if (this.eventbox_container.down("." + this.base_class + "Pause")) {
		    	this.objPause = this.eventbox_container.down("." + this.base_class + "Pause");
		    }

		    if (this.eventbox_container.down("." + this.base_class + "ControlNext")) {
		    	this.objNext = this.eventbox_container.down("." + this.base_class + "ControlNext");
		    }

		    if (this.eventbox_container.down("." + this.base_class + "ControlPrevious")) {
		    	this.objPrev = this.eventbox_container.down("." + this.base_class + "ControlPrevious");
		    }

			// get the dimensions of the window (for use later in setting the height of the images)
			this.windowDimensions = this.eventbox_container.down("." + this.base_class + "Window").getDimensions();
		}

		// content references
		this.previous_content = 0;		/* we use this to store the previous content we were on */
		this.active_content = -1;
		this.active_content = this.getNextImage(!isNaN(this.settings.firstSlide) ? parseInt(this.settings.firstSlide) - 1 : this.objWindow.size());		/* get the first (or random) content */
		
		// activate the slider
		if (this.settings.slider.active) {
			this._sliderInit();
		}

		/* loop through images in the window:
			turn off the image
			set an absolute position
			position image top/left
			set width and height to the window size
		*/
		this.objWindow.invoke("hide").invoke("absolutize").invoke("setStyle", {
			top: 0,
			left: 0,
			width: this.windowDimensions.width + "px",
			height: this.windowDimensions.height + "px"
		});

		/* loop through the descriptions
			turn off the description
			position description top/left
		*/
		this.objDescriptions.invoke("hide").invoke("setStyle", {
			top: 0,
			left: 0
		});
		
		if (this.settings.transitionDescriptions) {
			var description_container = this.objDescriptions.first().up("div");
			var description_width = description_container.getWidth() - parseInt(this.objDescriptions.first().getStyle("padding-left")) - parseInt(this.objDescriptions.first().getStyle("padding-right")) + "px";
			var description_height = description_container.getHeight() - parseInt(this.objDescriptions.first().getStyle("padding-top")) - parseInt(this.objDescriptions.first().getStyle("padding-bottom")) + "px";
			
			this.objDescriptions.invoke("absolutize").invoke("setStyle", {
				width: description_width,
				height: description_height
			});
		}

		/* loop through the navigation
			make sure none of the navigation buttons appear active
			turn all the onClicks on
		*/
		this.objNavigation.each(function(n, index) {
			n.removeClassName("on");
			this.toggleNavigation(index, 'on');
		}.bind(this));

		this.objWindow[this.active_content].show();					/* turn on the active image */
		this.objNavigation[this.active_content].addClassName("on");	/* turn on the navigation class */

		if (!this.objDescriptions[this.active_content].empty() || this.settings['showEmptyDescriptions']) {
			this.objDescriptions[this.active_content].show();				/* turn on the active description if applicable */
		}

		// update anchor href
		if (this.objAnchor) {
			this.updateAnchor(this.active_content);
		}

		// set the image as the background
		if (this.settings['setAsBackground']) {
			this.objWindow[this.active_content].setStyle({
				backgroundImage: "url(" + this.objWindow[this.active_content].down("img").hide().readAttribute("src") + ")"
			});

			if (this.objAnchor) {
				this.objAnchor.setStyle({
					width: this.windowDimensions.width + "px",
					height: this.windowDimensions.height + "px"
				});
			}
			
			Event.observe(window, "resize", function(event) {
				this.windowDimensions = this.eventbox_container.down("." + this.base_class + "Window").getDimensions();

				this.objWindow.invoke("setStyle", {
					width: this.windowDimensions.width + "px",
					height: this.windowDimensions.height + "px"
				});
				
				if (this.objAnchor) {
					this.objAnchor.setStyle({
						width: this.windowDimensions.width + "px",
						height: this.windowDimensions.height + "px"
					});
				}
			}.bind(this));
		}

		this.toggleNavigation(this.active_content, 'off');				/* deactivate the onClick for the active image */
			
		// set a timer to slide the images
		if (this.settings['type'] != '' && this.settings['type'] != 'static' && !this.isPaused && !this.isTransitioning) {
			this.interval = setTimeout(this.doTransition.bind(this, -1), this.settings['delay']);
		}
		
		// setup an event to pause the transition on mouse over on resume on mouse out
		if (this.settings.pauseOnMouseOver && this.interval) {
			this.addObservers();
		}
		
		// pause the rotation on startup
		if (this.settings.startPaused) {
			if (this.objPause) {
				this.objPause.fire("rotator:pause");
			} else {
				this.pause();
			}
		}
		
		// setup play, pause and stop buttons
		if (this.objPlay) {
			this.objPlay.observe("click", function(event) {
				event.stop();
				this.resume();
			}.bind(this));
		}
		if (this.objStop) {
			this.objStop.observe("click", function(event) {
				event.stop();
				this.pause();
			}.bind(this));
		}
		if (this.objPause) {
			this.objPause.observe("click", function(event) {
				event.stop();
				this.objPause.fire("rotator:pause");
			}.bind(this));
		}

		// setup next and previous buttons
		if (this.objNext) {
			this.objNext.observe("click", function(event) {
				event.stop();
				this.doTransition(-1);

				if (this.objPause && !this.isPaused) {
					this.objPause.fire("rotator:pause");
				}
			}.bind(this));
		}
		if (this.objPrev) {
			this.objPrev.observe("click", function(event) {
				event.stop();
				this.doTransition((this.active_content - 1 < 0) ? this.objWindow.size() - 1 : this.active_content - 1);

				if (this.objPause && !this.isPaused) {
					this.objPause.fire("rotator:pause");
				}
			}.bind(this));
		}

		this.onLoaded();
	},
	
	addObservers: function() {
		// if we have a Container div, set the mouse event on it
		var mouse_event_element = this.objContainer || this.eventbox_container;

		this.boundPause = this._pause.bind(this);
		this.boundResume = this._resume.bind(this);

		mouse_event_element.observe("mouseover", this.boundPause);
		mouse_event_element.observe("mouseout", this.boundResume);

		if (this.objPause) {
			this.objPause.stopObserving("rotator:pause").observe("rotator:pause", function(event) {
				if (this.isPaused) {
					this.resume();
					this.objPause.removeClassName("stopped").addClassName("playing");
					this.objPause.down("span").update("Pause");
				} else {
					this.pause();
					this.objPause.removeClassName("playing").addClassName("stopped");
					this.objPause.down("span").update("Resume");
				}
			}.bind(this));
		}
	},
	
	cancelObservers: function() {
		// if we have a Container div, set the mouse event on it
		var mouse_event_element = this.objContainer || this.eventbox_container;

		mouse_event_element.stopObserving("mouseover", this.boundPause);
		mouse_event_element.stopObserving("mouseout", this.boundResume);
	},
	
	afterTransition: function() {
		// mark that we're no longer transitioning
		this.isTransitioning = false;
		
		// turn on the navigation
		this.toggleNavigation('all', 'on');
		
		// turn off the previous content
		if (this.objWindow[this.previous_content] && this.objWindow[this.previous_content] != this.objWindow[this.active_content]) {
			this.objWindow[this.previous_content].hide();
			this.objDescriptions[this.previous_content].hide();
		}

		// set the timeout to transition the images
		if (this.settings['type'] != '' && this.settings['type'] != 'static' && !this.isPaused) {
			this.interval = setTimeout(this.doTransition.bind(this, -1), this.settings['delay']);
		}

		this.onTransition();
	},
	
	//
	// slide left and right
	//
	doTransition: function(nextImage) {
		this.onBeforeTransition();

		// clear the timeout in case of manual click
		clearTimeout(this.interval);
		
		this.isTransitioning = true;
		
		// turn off the onClicks for the navigation while doing transition
		this.toggleNavigation('all', 'off');
		
		// get the next image
		nextImage = this.getNextImage(nextImage);

		// turn off the previous image
		if (this.previous_content != this.active_content && this.previous_content != nextImage) {
			this.objWindow[this.previous_content].hide();					/* turn off the previous image */
			this.objWindow[this.previous_content].setStyle({
				left: 0													/* position the image all the way to the left */
			});
			this.objDescriptions[this.previous_content].hide();			/* turn off the previous description */
		}
		
		this.objWindow[nextImage].show();	/* turn on the next image */

		// turn on the description coming into focus
		if (!this.objDescriptions[nextImage].empty() || this.settings['showEmptyDescriptions']) {
			this.objDescriptions[nextImage].show();
		}
	
		if (!this.settings.transitionDescriptions) {
			this.objDescriptions[this.active_content].hide();			/* turn off the description */
		}

		if (this.objOverlay && !this.objOverlay.visible()) {
			this.objOverlay.show();
		}

		// update anchor href
		if (this.objAnchor) {
			if (!this.objAnchor.visible()) {
				this.objAnchor.show();
			}
			this.updateAnchor(nextImage);
		}

		// set the image as the background
		if (this.settings['setAsBackground']) {
			this.objWindow[nextImage].setStyle({
				backgroundImage: "url(" + this.objWindow[nextImage].down("img").hide().readAttribute("src") + ")"
			});
		}
			
		// call the transition function
		switch(this.settings['type']) {
			case 'slide_horizontal':
				this.doTransition_slideHorizontal(nextImage);
				break;

			case 'slide_vertical':
				this.doTransition_slideVertical(nextImage);
				break;

			case 'fade':
				this.doTransition_fade(nextImage);
				break;

			case 'fade_delay':
				this.doTransition_fadeDelay(nextImage);
				break;

			default:	/* does not do a transition */
				this.objWindow[this.active_content].hide();				
				this.objDescriptions[this.active_content].hide();
				this.afterTransition();
				break;
		}
		
		this.objNavigation[this.active_content].removeClassName("on");		/* remove the 'on' class for the navigation button */
		this.objNavigation[nextImage].addClassName("on");				/* add the 'on' class for the navigation button */
		
		// update the this.active_content and this.previous_content variables
		this.previous_content = this.active_content
		this.active_content = nextImage;

		
		if (this.settings.slider.active && !this.navigationIsPaused) {
			this._sliderMove();
		}
	},

	doTransition_slideHorizontal: function(nextImage) {

		// slide the images to the left
		if (nextImage > this.active_content) {
			this.objWindow[nextImage].setStyle({
				left: (this.windowDimensions.width - 2) + "px"			/* position the image all the way to the left */
			});
			
			new Effect.Move(this.objWindow[nextImage], {
				x: 0, 
				y: 0, 
				duration: this.settings['duration'], 
				mode: 'absolute', 
				afterFinish: this.afterTransition.bind(this)
			});
			new Effect.Move(this.objWindow[this.active_content], {
				x: -this.windowDimensions.width,
				y: 0, 
				duration: this.settings['duration'],
				mode: "absolute"
			});

			// if we're transitioning descriptions
			if (this.settings.transitionDescriptions) {
				// if the active slide has a description or we're displaying empty descriptions
				if (!this.objDescriptions[this.active_content].empty() || this.settings['showEmptyDescriptions']) {
					new Effect.Move(this.objDescriptions[this.active_content], {
						x: -this.windowDimensions.width, 
						y: 0, 
						duration: this.settings['duration'], 
						mode: "absolute"
					});
				}

				// if the next description is not empty or we're showing empty descriptions
				if (!this.objDescriptions[nextImage].empty() || this.settings['showEmptyDescriptions']) {
					this.objDescriptions[nextImage].setStyle({
						left: (this.windowDimensions.width - 2) + "px"			/* position the description all the way to the left */
					});

					new Effect.Move(this.objDescriptions[nextImage], {
						x: 0, 
						y: 0, 
						duration: this.settings['duration'], 
						mode: 'absolute'
					});
				}
			}

		// slide the images to the right
		} else {
			this.objWindow[nextImage].setStyle({
				left: (-this.windowDimensions.width) + 'px'				/* position the image all the way to the left */
			});

			new Effect.Move(this.objWindow[nextImage], {
				x: 0, 
				y: 0, 
				duration: this.settings['duration'],
				mode: "absolute", 
				afterFinish: this.afterTransition.bind(this)
			});

			new Effect.Move(this.objWindow[this.active_content], {
				x: this.windowDimensions.width,
				y: 0, 
				duration: this.settings['duration'], 
				mode: "absolute"
			});

			// if we're transitioning descriptions
			if (this.settings.transitionDescriptions) {
				// if the active slide has a description or we're displaying empty descriptions
				if (!this.objDescriptions[this.active_content].empty() || this.settings['showEmptyDescriptions']) {
					new Effect.Move(this.objDescriptions[this.active_content], {x: this.windowDimensions.width, y: 0, duration: this.settings['duration'], mode: "absolute"});
				}

				// if the next description is not empty or we're showing empty descriptions
				if (!this.objDescriptions[nextImage].empty() || this.settings['showEmptyDescriptions']) {
					this.objDescriptions[nextImage].setStyle({
						left: (-this.windowDimensions.width) + 'px'				/* position the description all the way to the left */
					});

					new Effect.Move(this.objDescriptions[nextImage], {x: 0, y: 0, duration: this.settings['duration'], mode: "absolute"});
				}
			}
		}

	},

	doTransition_slideVertical: function(nextImage) {

		// slide the images up
		if (nextImage > this.active_content) {
			this.objWindow[nextImage].setStyle({
				top: (this.windowDimensions.height) + "px"				/* position the image all the way to the left */
			});

			new Effect.Move(this.objWindow[nextImage], {
				x: 0, 
				y: 0, 
				duration: this.settings['duration'],
				mode: "absolute", 
				afterFinish: this.afterTransition.bind(this)
			});
			
			new Effect.Move(this.objWindow[this.active_content], {x: 0, y: -this.windowDimensions.height, duration: this.settings['duration'], mode: "absolute"});

			// if we're transitioning descriptions
			if (this.settings.transitionDescriptions) {
				// if the active slide has a description or we're displaying empty descriptions
				if (!this.objDescriptions[this.active_content].empty() || this.settings['showEmptyDescriptions']) {
					new Effect.Move(this.objDescriptions[this.active_content], {x: 0, y: -this.windowDimensions.height, duration: this.settings['duration'], mode: "absolute"});
				}

				// if the next description is not empty or we're showing empty descriptions
				if (!this.objDescriptions[nextImage].empty() || this.settings['showEmptyDescriptions']) {
					this.objDescriptions[nextImage].setStyle({
						top: (this.windowDimensions.height) + "px"				/* position the image all the way to the left */
					});

					new Effect.Move(this.objDescriptions[nextImage], {x: 0, y: 0, duration: this.settings['duration'], mode: "absolute"});
				}
			}

		// slide the images down
		} else {
			this.objWindow[nextImage].setStyle({
				top: -(this.windowDimensions.height) + 'px'			/* position the image all the way to the left */
			});

			new Effect.Move(this.objWindow[nextImage], {
				x: 0,
				y: 0, 
				duration: this.settings['duration'], 
				mode: "absolute", 
				afterFinish: this.afterTransition.bind(this)
			});
			
			new Effect.Move(this.objWindow[this.active_content], {x: 0, y: this.windowDimensions.height, duration: this.settings['duration'], mode: "absolute"});

			// if we're transitioning descriptions and the active slide has a description or we're displaying empty descriptions
			if (this.settings.transitionDescriptions) {
				// if the active slide has a description or we're displaying empty descriptions
				if (!this.objDescriptions[this.active_content].empty() || this.settings['showEmptyDescriptions']) {
					new Effect.Move(this.objDescriptions[this.active_content], {x: 0, y: this.windowDimensions.height, duration: this.settings['duration'], mode: "absolute"});
				}

				// if the next description is not empty or we're showing empty descriptions
				if (!this.objDescriptions[nextImage].empty() || this.settings['showEmptyDescriptions']) {
					this.objDescriptions[nextImage].setStyle({
						top: -(this.windowDimensions.height) + 'px'			/* position the image all the way to the left */
					});

					new Effect.Move(this.objDescriptions[nextImage], {x: 0, y: 0, duration: this.settings['duration'], mode: "absolute"});
				}
			}
		}

	},

	doTransition_fade: function(nextImage) {

		// adjust zIndexes to ensure the nextImage is on top of the activeImage
		this.objWindow[nextImage].style.zIndex = 1;
		this.objWindow[this.active_content].style.zIndex = 0;

		// turn off nextImage
		this.objWindow[nextImage].hide();
		
		// do effect
		Effect.Appear(this.objWindow[nextImage], {
			duration: this.settings['duration'],
			afterFinish: this.afterTransition.bind(this)
		});

		// if we're transitioning descriptions
		if (this.settings.transitionDescriptions) {
			
			// if the active slide has a description or we're displaying empty descriptions
			if (!this.objDescriptions[this.active_content].empty() || this.settings['showEmptyDescriptions']) {
				var description_opacity = this.objDescriptions[this.active_content].getStyle("opacity");
	
				this.objDescriptions[this.active_content].style.zIndex = 0;
		
				// do effect
				this.objDescriptions[this.active_content].fade({
					duration: this.settings['duration'],
					from: description_opacity
				});
			}

			// if the next description is not empty or we're displaying empty descriptions
			if (!this.objDescriptions[nextImage].empty() || this.settings['showEmptyDescriptions']) {
				var description_opacity = this.objDescriptions[nextImage].getStyle("opacity");
	
				this.objDescriptions[nextImage].style.zIndex = 1;
		
				// turn off next description
				this.objDescriptions[nextImage].hide();
				
				// do effect
				Effect.Appear(this.objDescriptions[nextImage], {
					duration: this.settings['duration'],
					to: description_opacity
				});
			}
		}

	},

	doTransition_fadeDelay: function(nextImage) {

		// adjust zIndexes to ensure the nextImage is on top of the activeImage
		this.objWindow[nextImage].style.zIndex = 1;
		this.objWindow[this.active_content].style.zIndex = 0;

		// turn off nextImage
		this.objWindow[nextImage].hide();
		
		// do effect
		this.objWindow[this.active_content].fade({
			duration: this.settings['duration'],
			afterFinish: function() {
				if (!this.isPaused) {
					this.cancelObservers();
				}
				new PeriodicalExecuter(function(pe) {
					Effect.Appear(this.objWindow[nextImage], {
						duration: this.settings['duration'],
						afterFinish: function() {
							this.afterTransition();
							if (!this.isPaused) {
								this.addObservers();
							}
						}.bind(this)
					});
					
					pe.stop();
				}.bind(this), this.settings['effectDelay']);
			}.bind(this)
		});
		
		// transition the description
		if (this.settings.transitionDescriptions) {
			var description_opacity = 0.8;

			if (!this.objDescriptions[this.active_content].empty() || this.settings['showEmptyDescriptions']) {
				description_opacity = this.objDescriptions[this.active_content].getStyle("opacity");

				this.objDescriptions[this.active_content].fade({
					duration: this.settings['duration'],
					from: description_opacity,
					to: 0,
					afterFinish: function() {
						this.objDescriptions[this.active_content].hide().setStyle({
							opacity: description_opacity
						});
					}.bind(this)
				});
			}

			if (!this.objDescriptions[nextImage].empty() || this.settings['showEmptyDescriptions']) {
				description_opacity = this.objDescriptions[nextImage].getStyle("opacity");
				this.objDescriptions[nextImage].hide();
	
				new PeriodicalExecuter(function(pe) {
					Effect.Appear(this.objDescriptions[nextImage], {
						duration: this.settings['duration'],
						from: 0,
						to: description_opacity
					});
					
					pe.stop();
				}.bind(this), this.settings['effectDelay'] + this.settings['duration']);
			}
		}
	},
	
	getNextImage: function(nextImage) {

		// get the next image based off of the "order" value
		switch(this.settings['order']) {
			case 'sequential':
				// if the nextImage is a negative number, then increment from the active image (the timer passes a -1)
				if (nextImage < 0) { nextImage = this.active_content + 1; }
		
				// if the 'nextImage' is greater than the amount of images we have, reset to 0
				if ((nextImage + 1) > this.objWindow.size()) { nextImage = 0; }
				break;

			case 'random':
				nextImage = this.getRandom();
				break;
		};

		return nextImage;
	},
	
	getRandom: function() {
		var random_number = Math.floor(Math.random() * this.objWindow.size());

		// if it's the same as the active image, try again
		if (random_number == this.active_content) {
			return this.getRandom();
		} else {
			return random_number;
		}
	},
	
	_pause: function() {
		clearTimeout(this.interval);
		this.isPaused = true;
	},
	
	_resume: function() {
		clearTimeout(this.interval);
		if (!this.isTransitioning) {
			this.interval = setTimeout(this.doTransition.bind(this, -1), this.settings['delay']);
		}
		this.isPaused = false;
	},
	
	pause: function() {
		this.onBeforePause();
		this._pause();
		this.cancelObservers();
		this.onPause();
	},
	
	resume: function() {
		this.onBeforeResume();
		this._resume();
		if (typeof $f == "function") {
			$f("*").each(function() {
				this.unload();
			});
		}
		this.addObservers();
		this.onResume();
	},
	
	flowplayer_init: function(player) {
		player.onBegin(function() {
			this.pause();
			this.objDescriptionsContainer.fade({duration: 0.5});
		}.bind(this));
		player.onFinish(function() {
			this.resume();
		}.bind(this));
		player.onUnload(function() {
			this.objDescriptionsContainer.appear({duration: 0.5});
		}.bind(this));
	},
	
	_flowplayer_play: function() {
		var popup_player = $(this.flowplayerID).cloneNode(true).writeAttribute("id", "");
		popup_player.identify();
		
		var orig_player = flowplayer(this.flowplayerID);

		this.pause();
		this.viewerCreate();
		
		this.viewer_container.setStyle({
			width: $(this.flowplayerID).getStyle("width"),
			height: $(this.flowplayerID).getStyle("height")
		});
		this.viewerShow();
		this.viewer_content.insert(
			popup_player.update()
		);
		
		var player_config = orig_player.getConfig(true);

		flowplayer(popup_player.identify(), {src: "/includes/videoplayers/flowplayer/flowplayer.swf", wmode: "opaque"}, player_config).ipad();
		flowplayer(popup_player.identify()).onFinish(function() {
			/* flowplayer(popup_player.identify()).unload(); */
			this.videoIsPlaying = false;
			this.resume();
			this.viewerDestroy();
		}.bind(this));

		this.videoIsPlaying = true;
	},
	
	_flowplayer_stop: function() {
		if (this.objAnchor) {
			this.objAnchor.stopObserving("click");
			this.objAnchor.observe("click", function(event) {
				event.stop();

				this._flowplayer_play();
			}.bind(this));
		}

		this.eventbox_container.select("a[rel*='flowplayer[']").each(function(f) {
			var flowplayer_rel = f.readAttribute("rel");
			var flowplayer_match = flowplayer_rel.match(/flowplayer\[(.*)\]/i);

			if (Object.isArray(flowplayer_match) && flowplayer_match.size() > 1) {
				var flowplayer_id = flowplayer_match.last();

				if (flowplayer(flowplayer_id).isLoaded()) {
					flowplayer(flowplayer_id).stop();
					flowplayer(flowplayer_id).unload();
					this.videoIsPlaying = false;
					this.resume();
				}
			}
		}.bind(this));
	},

	//
	// toggle on and off navigation (used during the transition)
	//
	toggleNavigation: function(buttonNumber, state) {
		// set defaults
		if (state == undefined) { state = 'on'; }
		if (buttonNumber == undefined) { buttonNumber = 'all'; }
		
		if (this.isPaused && !!this.flowplayerID) { this._flowplayer_stop(); }
	
		// change the navigation
		if (buttonNumber == 'all') {
	
			// loop through all the navigation buttons
			this.objWindow.each(function(w, index) {

				// don't turn on the button for the active image
				if (index != this.active_content) {
					this.toggleNavigation(index, state);
				}
			}.bind(this));

		} else {
			if (state == 'off') {
				this.objNavigation[buttonNumber].setStyle({
					cursor: "default"
				}).stopObserving("click");
			
			} else {
				this.objNavigation[buttonNumber].setStyle({
					cursor: "pointer"
				}).stopObserving("click").observe('click', function(event) {
					this.doTransition(buttonNumber);
				}.bind(this));
			}
		}
	},
	
	updateAnchor: function(content) {
		this.objAnchor.stopObserving("click");
		this.flowplayerID = false;

		if (this.objWindow[content].down("a")) {
			var anchor_rel = this.objWindow[content].down("a").readAttribute("rel");
			var flowplayer_match = "";
			
			if (anchor_rel) {
				flowplayer_match = anchor_rel.match(/flowplayer\[(.*)\]/i);
			}

			if (anchor_rel != "no_follow") {
				this.objAnchor.show().writeAttribute("href", this.objWindow[content].down("a").readAttribute("href"));
			} else {
				this.objAnchor.hide().writeAttribute("href", "");
			}
				
			// found a flowplayer object
			if (Object.isArray(flowplayer_match) && flowplayer_match.size() > 1) {

				this.flowplayerID = flowplayer_match[1];

				// if we're hiding the overlay
				if (this.settings.video.hideOverlay) {
					this.objAnchor.hide();
					if (this.objOverlay) {
						this.objOverlay.hide();
					}

				// otherwise, show an inline popup with the video
				} else {

					this.objAnchor.observe("click", function(event) {
						event.stop();

						this._flowplayer_play();
					}.bind(this));
				}
			}

		} else {
			this.objAnchor.hide().writeAttribute("href", "");
		}
	},
	
	_sliderInit: function() {
		this.slider_container = this.objNavigationContainer.up("." + this.settings.slider.container);
		this.slider_button_next = this.eventbox_container.down("." + this.settings.slider.button_next);
		this.slider_button_previous = this.eventbox_container.down("." + this.settings.slider.button_previous);
		this.slider_navigation_timeout = "";
		this.slider_handle = new Element("span", {style: "display: none;"});
		this.slider_container.insert(this.slider_handle);

		var additional_height_props = ["margin-top", "margin-bottom"];
		var additional_width_props = ["margin-left", "margin-right"];
		var additional_props = (this.settings.slider.orientation == "vertical") ? additional_height_props : additional_width_props;
		var slider_container_dimension = (this.settings.slider.orientation == "vertical") ? this.slider_container.getHeight() : this.slider_container.getWidth();
		var slider_elements_total_dimension = 0;

		this.objNavigation.each(function(ci) {
			slider_elements_total_dimension += (this.settings.slider.orientation == "vertical") ? ci.getHeight() : ci.getWidth();
			additional_props.each(function(p) {
				prop_value = parseInt(ci.getStyle(p));
				if (!isNaN(prop_value)) {
					slider_elements_total_dimension += prop_value;
				}
			});

		}.bind(this));
		
		if (this.settings.slider.orientation == "vertical") {
			this.objNavigationContainer.setStyle({height: slider_elements_total_dimension + "px"});
		} else {
			this.objNavigationContainer.setStyle({width: slider_elements_total_dimension + "px"});
		}
		
		this.settings.slider.item_dimension = slider_elements_total_dimension / this.objNavigation.size();
		this.settings.slider.max_range = slider_elements_total_dimension - slider_container_dimension + 1;
		this.settings.slider.current_value = 0; // update to account for "this.settings.firstSlide"
		
		this.slider_values = $R(0,this.settings.slider.max_range).partition(function(n) {
			return 0 == n % (this.settings.slider.item_dimension * this.settings.slider.step);
		}.bind(this)).first();
		
		(this.slider_values.last() != this.settings.slider.max_range) ? this.slider_values.push(this.settings.slider.max_range) : Prototype.emptyFunction ;
		
		this.slider_control = new Control.Slider(this.slider_handle, this.slider_container, {
			axis: this.settings.slider.orientation,
			range: $R(0,this.settings.slider.max_range),
			increment: this.settings.slider.item_dimension,
			values: this.slider_values,
			onChange: function(v) {
				var move_property = (this.settings.slider.orientation == "vertical") ? "top" : "left";
				new Effect.Morph(this.objNavigationContainer, {
					style: move_property + ": " + v * -1 + "px",
					duration: this.settings.duration
				});
			}.bind(this)
		});

		// setup slider navigation handlers
		if (this.slider_button_next) {

			if (this.objNavigation.size() > this.settings.slider.view) {
				this.slider_button_next.observe("click", function(event) {
					event.stop();

					this.settings.slider.current_value += this.settings.slider.item_dimension * this.settings.slider.step;

					if (this.settings.slider.current_value > this.settings.slider.max_range) {
						this.settings.slider.current_value = this.settings.slider.max_range;
					}

					this.slider_control.setValue(this.settings.slider.current_value);
				}.bind(this));
			}
		}
		
		if (this.slider_button_previous) {
			if (this.objNavigation.size() > this.settings.slider.view) {
				this.slider_button_previous.observe("click", function(event) {
					event.stop();

					this.settings.slider.current_value -= this.settings.slider.item_dimension * this.settings.slider.step;

					if (this.settings.slider.current_value < 0) {
						this.settings.slider.current_value = 0;
					} else if (this.slider_values.indexOf(this.settings.slider.current_value) < 0) {
						this.settings.slider.current_value = this.slider_values.detect(function(n) {
							return n > this.settings.slider.current_value;
						}.bind(this));
					}

					this.slider_control.setValue(this.settings.slider.current_value);
				}.bind(this));
			}
		}
		
		this._sliderMove();
	},
	
	_sliderMove: function() {
		var active_content_position = this.active_content * this.settings.slider.item_dimension;
		var slider_viewport_dimension = this.settings.slider.item_dimension * this.settings.slider.view;

		// see if we're moving to the next
		if (active_content_position - this.settings.slider.current_value >= slider_viewport_dimension) {
			this.settings.slider.current_value += this.settings.slider.item_dimension * this.settings.slider.step;

			if (this.settings.slider.current_value > this.settings.slider.max_range) {
				this.settings.slider.current_value = this.settings.slider.max_range;
			}
			
			if (active_content_position - this.settings.slider.current_value >= slider_viewport_dimension) {
				this._sliderMove();
			} else {
				this.slider_control.setValue(this.settings.slider.current_value);
			}


		// see if we're moving to the previous
		} else if (active_content_position < this.settings.slider.current_value) {
			this.settings.slider.current_value -= this.settings.slider.item_dimension * this.settings.slider.step;
			
			if (this.settings.slider.current_value < 0) {
				this.settings.slider.current_value = 0;
			}

			if (active_content_position < this.settings.slider.current_value) {
				this._sliderMove();
			} else {

				if (this.slider_values.indexOf(this.settings.slider.current_value) < 0) {
					this.settings.slider.current_value = this.slider_values.reverse(false).detect(function(n) {
						return n <= active_content_position;
					}.bind(this));
				}

				this.slider_control.setValue(this.settings.slider.current_value);
			}
		}
	},
	
	_detectMacXFF: function() {
		var userAgent = navigator.userAgent.toLowerCase();
		if (userAgent.indexOf('mac') != -1 && userAgent.indexOf('firefox')!=-1) {
			return true;
		}
	},
	
	viewerCreate: function() {
		this.viewer_parent = $(document.getElementsByTagName("body").item(0));
		this.viewer_backdrop = new Element("div", {style: "display: none;"});
		this.viewer_container = new Element("div", {style: "display: none;"});
		this.viewer_window = new Element("div");
		this.viewer_content = new Element("div");
		this.viewer_close = new Element("a", {href: "#"}).insert(
			new Element("img", {src: "/includes/eventbox/images/viewer_close.png"})
		);
		
		if (!this.settings.video.popupSettings.className.blank()) {
			this.viewer_container.addClassName(this.settings.video.popupSettings.className);
		}
		
		var d = this._detectMacXFF();
		if (d) {
			//osx ff css opacity + flash wmode transparent doesn't work
			this.viewer_backdrop.setStyle({
				backgroundImage: "url(/includes/login/trans.png)",
				backgroundRepeat: "repeat",
				backgroundColor: ""
			});
			
		} else {
			this.viewer_backdrop.setStyle({
				opacity: 0.7,
				backgroundColor: "#000"
			});
		}

		this.viewer_backdrop.setStyle({
			position: "fixed",
			top: 0,
			left: 0,
			width: "100%",
			height: "100%",
			zIndex: 9000
		});

		this.viewer_container.setStyle({
			position: "absolute",
			top: parseInt(this.settings.video.popupSettings.top) + "px",
			left: "100px",
			width: "500px",
			height: "500px",
			padding: parseInt(this.settings.video.popupSettings.padding) + "px",
			backgroundColor: this.settings.video.popupSettings.backgroundColor,
			zIndex: 9010
		});
		
		this.viewer_close.setStyle({
			position: "absolute",
			top: "-15px",
			right: "-15px",
			opacity: 0.8,
			zIndex: 9015
		});

		this.viewer_parent.insert({top: this.viewer_backdrop});
		this.viewer_backdrop.insert({after: this.viewer_container});
		this.viewer_container.insert(this.viewer_window);
		this.viewer_window.insert(this.viewer_close);
		this.viewer_window.insert(this.viewer_content);
		
		[this.viewer_backdrop, this.viewer_close].each(function(c) {
			c.observe("click", function(event) {
				event.stop();
				this.videoIsPlaying = false;
				this.resume();
				this.viewerDestroy();
			}.bind(this));
		}.bind(this));
	},
	
	viewerDestroy: function() {
		this.viewer_backdrop.fade({
			duration: 0.5,
			afterFinish: function() {
				this.viewer_backdrop.remove();
			}.bind(this)
		});
		this.viewer_container.fade({
			duration: 0.5,
			afterFinish: function() {
				this.viewer_container.remove();
			}.bind(this)
		});
	},
	
	_viewerMove: function() {
		var offset = document.viewport.getScrollOffsets();
	
		this.viewer_container.setStyle({
			top: offset.top + parseInt(this.settings.video.popupSettings.top) + "px",
			left: ((this.viewer_backdrop.getWidth() - this.viewer_container.getWidth()) / 2) + "px"
		});
	},

	viewerShow: function() {
		[this.viewer_backdrop, this.viewer_container].invoke("show");
		this._viewerMove();
	}
	
});


