/* --------------------------------------------------------------------------------------------
	Permalink Slideshow - Natalie Downe
	natalie.downe@torchbox.com 
	
	Version 0.20 (04/04/2006)
	
	RELATES TO:
	- permalinkSlideshow_v030.html
	- style.css <--- main stylesheet
	- style4.css <--- imported stylesheet

	UPDATES:
	- Added ability for different links per image
	- Fixed the major bug in Safari
	- Fixed memory leak in IE and old FF versions
	- automated the document title and made other starts to making less app specific, such as testing for pages and links needed
	- stoped the jump to element by dynamically changing id's
	- now works with more than one image (when the other image is not part of the slideshow) on the page
		
	STILL TODO: 
	- preload images so that it still works before the images load
	- Dynamically add next/previous links
	- more intensive browser testing 
	- make more componantised and less app spec
-------------------------------------------------------------------------------------------- */

var gCurrentImage; // index to images[] the actual image is 'gCurrentImage+1' any passing of href must minus 1
var gImages = [];
var gInitialDocTitle;
var URLchecker; // global variable so we can clear and reset interval
var fadingInProcess = false; // to stop unexpected behaviour if fading is interupted
var gCurrentCaption;
var gCaptions = [];

function debug(msg) {/*
	var debugDock = document.getElementById('debug');
	if(debugDock.innerHTML) {
		debugDock.innerHTML = msg + '<br /> \n' + debugDock.innerHTML ;
	} else {
		debugDock.innerHTML = msg
	}*/
}

// takes an array of images and the current image object
function listenForURLchange() {
	if(location.hash) {
		var requested = parseInt(location.hash.replace('#image', '')) - 1;

		if((requested != gCurrentImage) && (requested < gImages.length) && (requested >= 0)) {
			// correct image number trying to fade
			//debug('CAUGHT! ... changing from '+ gCurrentImage +' to '+ requested + ' | imageLength = ' + gImages.length);
			
			startFade(gImages[gCurrentImage], gImages[requested], gCaptions[gCurrentCaption], gCaptions[requested]);
		} else {
			// incorrect image number : requested = ' +requested+' : current = '+ gCurrentImage + ' : images.length = '+gImages.length);
		}
	}
}

function setOpacity(obj, opacity) {
	opacity = (opacity == 1)?0.99999:opacity;
	// IE/Win
	obj.style.filter = "alpha(opacity:"+(opacity*100)+")";
	// Safari<1.2, Konqueror
	obj.style.KHTMLOpacity = opacity;
	// Older Mozilla and Firefox
	obj.style.MozOpacity = opacity;
	// Safari 1.2, newer Firefox and Mozilla, CSS3
	obj.style.opacity = opacity;
}

function changeLinks(toLinks) {
	// takes an index number for the links to change to, 
	// tests to see if there are any associated links and then changes the visibility and z-indexes accordingly,
	// if there are no associated links for that image then nothing is displayed
	var l = 1;
	if(document.getElementById('links'+(toLinks + 1))) {
		var toLinkObj = document.getElementById('links'+(toLinks + 1));
	
		// set all links other than the one we want to be invisible, just incase
		for(l;l<=gImages.length;l++) {
			if(document.getElementById('links'+l)) {
				var currentLinkObj = document.getElementById('links'+l);
				if(currentLinkObj == toLinkObj) {
					// is the link set we are looking for
					currentLinkObj.style.zIndex = '5';
					currentLinkObj.style.visibility = 'visible';
					currentLinkObj.style.display = 'block';
				} else {
					// is not the link set we are looking for
					currentLinkObj.style.zIndex = '0';
					currentLinkObj.style.visibility = 'hidden';
					currentLinkObj.style.display = 'none';
				}
			}		
		}
	}
}

function endFade(imgFrom, imgTo, captionFrom, captionTo) {

	// the fade has finished so reset visiblity, display and opacity
	// zindex need to reset only for safari (might fix it)
	imgFrom.style.zIndex = '0';
	imgTo.style.zIndex = '5';
	imgFrom.style.visibility = 'hidden';
	imgFrom.style.display = 'none';
	captionFrom.style.visibility = "hidden";
	captionFrom.style.display = 'none';
	captionTo.style.visibility = "visible";
	captionTo.style.display = 'block';
	setOpacity(imgFrom, 1);
	
	// restart the url checker
	URLchecker = setInterval(listenForURLchange, 500);
	
	// reset current image
	gCurrentImage = parseInt(imgTo.id.replace('slideshowImage','')) - 1;
	gCurrentCaption = parseInt(captionTo.id.replace('caption','')) - 1;
	//debug('END FADE TO ' + imgTo.id +' / '+gCurrentImage);
	
	// reassign the navigation and URL
	assignNav();
	//location.href = location.pathname + '#image' + parseInt(imgTo.id.replace('slideshowImage', ''), 10);
	//debug(location.href);
	//document.title = "Slide "+ (gCurrentImage + 1) +" : "+ gInitialDocTitle;
	
	// write what page we are on at the moment
	if(document.getElementById('pages')) {
		document.getElementById('pages').innerHTML = (gCurrentImage + 1) + ' of ' + gImages.length;
	}
	
	// change the links to fit the image - passing index
	changeLinks(gCurrentImage);
	
	// officially end the fade
	fadingInProcess = false;
}

function fadeImages(imgFrom, imgTo, opacity, captionFrom, captionTo) {
	//debug('fadeImages('+parseInt(imgFrom.id.replace('image',''))+', '+opacity+')');
	if(opacity > 0.2) {
		// still fading, reduce imgFrom opacity and call again
		opacity = opacity - 0.1;
		setOpacity(imgFrom, opacity);
		setTimeout(function() {fadeImages(imgFrom, imgTo, opacity, captionFrom, captionTo); }, 50);
	} else {
		// image has finished fading
		endFade(imgFrom, imgTo, captionFrom, captionTo);
	}
}

function startFade(imgFrom, imgTo, captionFrom, captionTo) {

	//debug('** startFade('+imgFrom.id+', '+imgTo.id+')');
	
	//alert(imgFrom.id +' '+ imgTo.id);
	
	if(fadingInProcess) {
		//debug('fadingInProcess YES');
	} else  {
		//debug('fadingInProcess NO');
	}
	
	// check that we are not requested to move pages
	//TODO also check imageto and image from is defined
	if((imgFrom.id != imgTo.id) && (!fadingInProcess)) { 
	
		// using global varible from url checker
		clearInterval(URLchecker);
		
		// fadeFrom must have a higher zindex than fadeTo (need to reset only for safari)
		imgFrom.style.zIndex = '5';
		imgTo.style.zIndex = '4';
		
		// set visibility and display to show both images one on top of the other
		imgFrom.style.visibility = 'visible';
		imgTo.style.visibility = 'visible';
		imgFrom.style.display = 'block';
		imgTo.style.display = 'block';
		
		// fade the top image onto the bottom
		fadeImages(imgFrom, imgTo, 1, captionFrom, captionTo);
		
		//alert('** startFade('+imgFrom.id+', '+imgTo.id+')');
		
		// tell program we are fading so dont try doing it again
		fadingInProcess = true
	}
}

// uses array of images and index to that array
function assignNav() {

	// calculate next and previous page index
	var nextPage = gCurrentImage + 1;
	var previousPage = gCurrentImage - 1;
	var nextCaption = gCurrentCaption + 1;
	var previousCaption = gCurrentCaption - 1;
	//debug('currentIndex = '+gCurrentImage +' | gImages.length = '+gImages.length);
	if(gCurrentImage >= (gImages.length - 1)) {
		// on the last image
		nextPage = 0;
		nextCaption = 0;
		//debug('last');
	} else if(gCurrentImage <= 0) {
		// on the first image
		previousPage = gImages.length - 1;
		previousCaption = gCaptions.length - 1;
		//debug('first');
	} else {
		//debug('not');
	}
	//debug('<' + (previousPage) +' | '+(gCurrentImage)+' | '+(nextPage) +'>');
	//debug('<' + (previousPage + 1) +' | '+(currentImage +1)+' | '+(nextPage + 1) +'>');
	
	// initialise links links
	var nextPageLink = document.getElementById('nextLink');
	var previousPageLink = document.getElementById('previousLink');
	
	// set up listners for the forward and back links
	// NOTE: the code was throwing an error when I used links, hence currently using spans
	//nextPageLink.href = location.pathname + '#image' + nextPage;
	nextPageLink.title = 'Next (slide ' + (nextPage + 1) + ')';
	nextPageLink.onclick = function() {	
		//alert(images[nextPage].id);
		startFade(gImages[gCurrentImage], gImages[nextPage], gCaptions[gCurrentCaption], gCaptions[nextCaption]);
		return false;
	};
	//previousPageLink.href = location.pathname + '#image' + previousPage;
	previousPageLink.title = 'Previous (slide ' + (previousPage + 1) + ')';
	previousPageLink.onclick = function() {	
		startFade(gImages[gCurrentImage], gImages[previousPage], gCaptions[gCurrentCaption], gCaptions[previousCaption]);
		return false;
	};
	
	// Clear DOM references to avoid cycle (and resulting memoryleak)
    nextPageLink = null;
    previousPageLink = null;
}

function setupPage() {
	
	// initial document title
	gInitialDocTitle = document.title;
	
	// initialise arrays and set styleId to be #imageXX
	var allImages = document.getElementsByTagName('img');
	var allCaptions = document.getElementsByTagName('p');
	var i = 0;
	var tempSlideNo;
	for(i; i<allImages.length; i++) {
		allImages[i].id.display = 'none';
		if (allImages[i].className.indexOf('slideshowImage') != -1) {
		
			// what slide are we looking at
			tempSlideNo = parseInt(allImages[i].id.replace('image', ''), 10);
			
			// reslet slide id to avoid jumping but to maintain graceful degredation
			allImages[i].id = 'slideshowImage' + tempSlideNo;
			
			// put in our global array of slideshow images
			gImages[gImages.length] = allImages[i];
		}
	}
	var j = 0;
	for(j; j<allCaptions.length; j++) {
		allCaptions[j].id.display = 'none';
		if (allCaptions[j].className.indexOf('slideshowCaption') != -1) {
			gCaptions[gCaptions.length] = allCaptions[j];
		}
	}

	gCurrentImage = 0;
	gCurrentCaption = 0;
	// what page are we on? take hash and turn to index : #1 --> [0]
	if(location.hash) {
		gCurrentImage = parseInt(location.hash.replace('#image', ''), 10) - 1;
		if(gCurrentImage >= gImages.length) {
			debug('IMAGE TOO HIGH');
			gCurrentImage = 0;
			//location.href = location.pathname + '#image1';
		}
	} else {
		gCurrentImage = 0;
		//location.href = location.pathname + '#image1';
	}
	
	
	// scroll to the top as is currently jumping to bottom
	// window.scroll(0,0);
	
	// write what page we are on at the moment
	if(document.getElementById('pages')) {
		document.getElementById('pages').innerHTML = (gCurrentImage + 1) + ' of ' + gImages.length;
	}
	//document.title = "Slide "+ (gCurrentImage + 1) +" : "+ gInitialDocTitle;

	//debug('current image index' + gCurrentImage);
	
	// initialise and assign links
	assignNav();
	
	// display correct image and links to start with
	gImages[gCurrentImage].style.visibility = 'visible';
	gImages[gCurrentImage].style.display = 'block';

	gCaptions[gCurrentCaption].style.visibility = 'visible';
	gCaptions[gCurrentCaption].style.display = 'block';

	// change the links to fit the image - passing index
	changeLinks(gCurrentImage);
	
	// assign our listener to a global variable so we can purge it later
	URLchecker = setInterval(listenForURLchange, 700);
}

function setCSS(css) {
	try {
		// append stylesheet to alter
		document.getElementsByTagName("head")[0].appendChild(css);
	} catch (e) {
		setTimeout(function(){setCSS(css)}, 100);
	} 
}

// on load
addLoadEvent(setupPage);

// create CSS element to set up the page
// var css = document.createElement("link");
// css.setAttribute("href","style4.css");
// css.setAttribute("rel","stylesheet");
// css.setAttribute("type","text/css");

// attempt to add the css and then keep trying till we do
// setCSS(css);
// css = null;
