/**
 * Swaps two slide elements. If the new slide element is currently active, the
 * method call has no effect. After the slide elements are swapped, the active
 * navigation element is changed.
 * 
 * If the next slide index is not specified, the current active slide is swapped
 * with the next following.
 * 
 * @param timercount
 *            The quantity of timer runs (an integer increased with each timer
 *            event)
 * @param next
 *            The index of the next slide item or the command strings 'next' or
 *            'prev'
 * @param duration
 *            A customized transition duration in ms
 */
function swapSlides(timercount, next, duration) {
	// if next slide is current active slide do nothing
	if (!isNaN(next)
			&& jQuery("ul.slides li:eq(" + next + ")").hasClass("active")) {
		return;
	}

	// set default transition duration if not specified
	if (!duration) {
		duration = 1500;
	}

	var currentItem = jQuery("ul.slides li.active");
	var currIndex = jQuery("ul.slides li").index(currentItem);

	// calculate next slide index
	if (isNaN(next) && next == 'prev') {
		nextIndex = currIndex - 1;
	} else if (!isNaN(next)) {
		nextIndex = next;
	} else {
		// fallback if next contains no valid value or 'next'
		nextIndex = currIndex + 1;
	}
	// loop slide index, if out of bounds
	if (nextIndex < 0)
		nextIndex = (jQuery("ul.slides li").length - 1);
	if (nextIndex > (jQuery("ul.slides li").length - 1))
		nextIndex = 0;

	nextItem = jQuery("ul.slides li:eq(" + nextIndex + ")");

	// uncomment the following lines for for body background changing feature on
	// half-time of transition
	// jQuery("body").oneTime(duration / 2, 'changebg', function() {
	// jQuery(this).css("background-color", backgrounds[nextIndex]);
	// });

	// fade slides and change active navigation item
	currentItem.fadeOut(duration).removeClass("active");
	nextItem.fadeIn(duration).addClass("active");
	jQuery("ul.navigation li.active").removeClass("active");
	jQuery("ul.navigation li:eq(" + (nextIndex + 1) + ")").addClass("active");
};

/**
 * Sets the click event handler to all navigation items.
 */
function setSlideNavigationEvents() {
	jQuery("ul.navigation li.next").click(function() {
		return triggerSlideNavigation('next');
	});

	jQuery("ul.navigation li.prev").click(function() {
		return triggerSlideNavigation('prev');
	});

	jQuery("ul.navigation li.item").each(function(index) {
		jQuery(this).click(function() {
			return triggerSlideNavigation(index);
		});
	});
}

/**
 * Processes a manual swap of slide events, triggered by navigation clicks.
 * 
 * @param nextItem
 *            The next item index
 * @return
 */
function triggerSlideNavigation(nextItem) {
	// stop the slideshow swap timer
	jQuery("ul.slides").stopTime('slideshow');

	swapSlides(-1, nextItem, 500);

	// reactivate the slideshow timer after a short break
	jQuery(this).oneTime(3000, 'slideshow', function() {
		activateSlideShow();
	});

	return false;
}

/**
 * Starts the slideshow timer with the given duration. If no duration is
 * specified, 6000ms are used.
 * 
 * @param duration
 *            The duration when to swap slides in ms
 */
function activateSlideShow(duration) {
	if (!duration) {
		duration = 6000;
	}
	// start jQuery-timers Timer with ID slideshow
	jQuery("ul.slides").everyTime(duration, 'slideshow', swapSlides);
}

/**
 * Calculates a random start index for the slideshow and activates the slide
 * with the calculated index.
 * 
 * @param numberOfSlides
 *            The number of slides available
 */
function activateRandomSlide(numberOfSlides) {
	var activeSlideIndex = (Math.round(Math.random() * 100)) % numberOfSlides;

	// remove active class of currernt active slide and navigation item
	jQuery("ul.slides li.active").removeClass("active").hide();
	jQuery("ul.navigation li.active").removeClass("active");

	// uncomment the following line for body background changing feature
	// jQuery("body").css("background-color", backgrounds[activeSlideIndex]);

	// activate randomly choosen slide and navigation item
	jQuery("ul.slides li:eq(" + activeSlideIndex + ")").addClass("active")
			.show();
	jQuery("ul.navigation li:eq(" + (activeSlideIndex + 1) + ")").addClass(
			"active");
}
