/*
	This file requires that the variable requestRoot is set to point to the directory with the php file
*/

// Image height and width
var height = 286;
var width = 430;

var delay = 5;		// Seconds to delay between rotations
var fadeInc = 5;	// Percentage of opacity to increment by
var fadeDelay = 50;	// Delay between fade increments
var images;			// An array of the image URLs to be used
var i;				// The current image

var control;		// Interval controlling the slideshow rotation
var fader;			// Interval controlling image fading
var currentOpacity;	// Current opacity of the fading layer (usually top) 

var lastRotate;		// The last time we changed images
var remainingTime;	// Used when rotation is paused

// Flags to track paused state
var paused;
var unpausing;

var unpauser;		// Timeout for unpausing 

var topLayer;		// The top layer div for images
var bottomLayer;	// Bottom layer div for images

function rotate() {
	lastRotate = new Date().getTime();

	// Put the old images on the top layer
	//topLayer.innerHTML = bottomLayer.innerHTML;

	// Start fading the top layer
	if (topLayer.innerHTML == "") startFadeIn();
	else startFadeOut();
	
	// Get the new ones, and put them on the bottom layer
	bottomLayer.innerHTML = '<img src="' + images[i] + '" alt="" />';

	// Set the next image to be loaded
	moveIndex(1);
	(new Image(height, width)).src = images[i];
}

// Start the rotation
function startRotation() {
	control = setInterval("rotate()", delay*1000);
}

// Clear and restart rotation
function resetRotation() {
	clearInterval(control);
	startRotation();
}

// Pause rotation and save the current point of transition
function pauseRotation() {
	// Repause if an unpause was in process 
	if (unpausing) {
		clearTimeout(unpauser);
		unpausing = false;
		paused = true;
	}

	if (paused) return;

	// Calculate the remaining time until the next transition
	remainingTime = 1000 * delay - (new Date().getTime() - lastRotate);
	
	// Stop rotation	
	clearInterval(control);
	paused = true;
}

// Resume rotation after a pause
function unpauseRotation() {
	if (unpausing || !paused) return;

	// Wait the remaiting time to rotate again, and start the interval again
	unpauser = setTimeout("paused = false; unpausing = false; rotate(); resetRotation()",remainingTime);
	unpausing = true;	
}


// Stop the rotator from fading and snap to the appropriate image
function stopFading() {
	// Stop the interval if we're in the middle of fading
	clearInterval(fader);

	// If the previous image is more visible than the new one, make it the visible one
	if (currentOpacity > 50 && topLayer.innerHTML != "")
		moveIndex(-1);

	// Set layers to appropriate opacity
	changeOpacity(0,"topLayer");
	changeOpacity(100,"bottomLayer");

	// Set both layers to this image 
	topLayer.innerHTML = bottomLayer.innerHTML = '<img src="' + images[i] + '" alt="" />';

}

// Immediately move to the specified image (relative to the current)
function skipTo(n) {
	// Change the index
	moveIndex(n);

	// Stop any fading that's going on
	stopFading();

	// Reset the interval
	resetRotation();

}

// Move n steps relative to the current image
function moveIndex(n) {
	i = (i+n).mod(images.length);
}


// Start fading in from nothing
function startFadeIn() {
	clearInterval(fader);
	currentOpacity = 0;
	changeOpacity(currentOpacity, "bottomLayer");
	fader = setInterval("fadeIn()", fadeDelay);
}

// Increment the opacity for a fade-in
function fadeIn() {
	currentOpacity += fadeInc;
	changeOpacity(currentOpacity, "bottomLayer");
	if (currentOpacity >= 100) {
		clearInterval(fader);
		topLayer.innerHTML = bottomLayer.innerHTML;
	}
}

// Start fading out over another image
function startFadeOut() {
	clearInterval(fader);
	currentOpacity = 100;
	changeOpacity(currentOpacity, "topLayer");
	fader = setInterval("fadeOut()", fadeDelay);
}

// Increment the opacity for a fade-out
function fadeOut() {
	currentOpacity -= fadeInc;
	changeOpacity(currentOpacity, "topLayer");
	if (currentOpacity <= 0) {
		clearInterval(fader);
		// Put the bottom image in the top to prevent delay later
		topLayer.innerHTML = bottomLayer.innerHTML;
	}
} 

// Change the opacity of an element with cross-browser functionality
function changeOpacity(opacity, id) {
    var object = document.getElementById(id).style;
    object.opacity = (opacity / 100);
    object.MozOpacity = (opacity / 100);
    object.KhtmlOpacity = (opacity / 100);
    object.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + opacity + ")";
}

// Slideshow initialization - grab the list of filenames and start at a random point
function init(){

	// Get the layers used for the image transitions
	topLayer = document.getElementById("topLayer");	
	bottomLayer = document.getElementById("bottomLayer");	

	// Grab a list of images via ajax request
	var request = ajaxFunction();
	request.onreadystatechange = function(){
		if (request.readyState == 4) {
			if (request.status == 200 || request.status == 304) {

				// Get the flat list and parse it as an array
				var urls = request.responseText;
				images = urls.trim().split("\n");

				// Get a random starting point and preload that image
				i = Math.floor(Math.random() * images.length);
				(new Image(height, width)).src = images[i];

				// Start the rotation
				rotate();
				startRotation();	
				
				var container = document.getElementById("rotatorContainer");
				container.onmouseover = pauseRotation;
				container.onmouseout = unpauseRotation;
/*
				// Button bar
				var buttons = document.getElementById("buttons");
				buttons.style.display = 'block';
				
				// Next button
				var next = document.getElementById("next");
				next.onmouseover = pauseRotation;
				next.onmouseout = unpauseRotation;
				next.onclick = function(){skipTo(1)};

				// Previous button
				var prev = document.getElementById("prev");
				prev.onmouseover = pauseRotation;
				prev.onmouseout = unpauseRotation;
				prev.onclick = function(){skipTo(-1)};
*/
			}
		}
	}
	
	// Ajax request
	
    request.open("GET", requestRoot+"/slides.php", true);	
    request.send(null);

}

function ajaxFunction(){
	var xmlHttp;
	try {
	  // Firefox, Opera 8.0+, Safari
	  xmlHttp=new XMLHttpRequest();
	}catch (e) {
	  // Internet Explorer
	  try {
		xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
	} catch (e) {
		try {
		  xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
		} catch (e) {
		  alert("Your browser does not support AJAX!");
		  return false;
		}
	  }
	}
	return xmlHttp;
}

// Remove whitespace at the beginning and ends of a string
String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/g,"");
}

// Modulus which behaves properly with negatives
Number.prototype.mod = function(n) {
	return ((this%n)+n)%n;
}


