//	JavaScript driven Slide Show, using a State Transition design approach
//	Colin Williams created 6th June 2006 - V4 1st November 2006
//	Modified to rotate page banners February 2009
//	This version of the slide show starts automatically and has no "controls"

var bannerList = new Array();	//	Contains the banner files when downloaded from the server
var bannerStatus = new Array();	//	An element contains the value "true" if the corresponding slide is loaded
var bannerHeight = 220;
var bannerWidth = 920;
//var framePadding = 4;
//var frameColour = "#0E3F6C";	// background colour for large banner
//var loadingColour = "#F8F8FF";	// font colour for "loading" message

var numBanners;	//	Set to the number of slides, once this has been determined

var currentBannerTimeout = 0;
var bannerLoadCount = 0;
var bannerSwapCount = 0;
var nextBanner = 0;	//	Next slide to be shown
var currentBanner = 0;	//	Banner currently being displayed
var curBannerState = 0;	//	Current state of the slide show
var bannerDelayValue;

var banneralphaval = 0;	// Used in fading in the large banner
var banneralphastep = 0.02;	// As for banneralphaval
var bannerFadeDelay = 15;	// delay between each "alpha step"
var bannerloaddelay = 100;	// delay between each test for banner loaded

var bannerLoadBusy0 = false;
var bannerLoadBusy1 = false;
var bannerLoad0 = 0;
var bannerLoad1 = 0;
//var nextBannerLoadCount;
var modifiedbannerdelay = 0;

//var bigbanner;
//var bigbannerloaded = false;
//var bigbannerrqst = false;
var bannerProcessing = false;
var bannerFirstPass = true;
//var bannerBigLoadCount = 0;

if(typeof bL == "object") {
	if(bL.length != 0) {
		addLoadEvent(initBanners);
	}
}

function initBanners() {
	//	This process is activated by the "window.onload" event	
	//	Find out if this browser supports the relevant W3C DOM APIs
	//	If not, exit from the initialisation
	if (!document.getElementsByTagName || !document.getElementById || !document.createElement) return false;
	bannerProcessing = true;
	numBanners = bL.length;
	for(i = 0; i < numBanners; i++) {
		//	Ensure that the bannerStatus array is initialised
		bannerStatus[i] = false;
	}
		//	Select the default banner to display on the screen
	nextBanner = 1;
	if(testIfBannerLoaded(nextBanner)) {
		//	Banner loaded, continue with initialisation
		clearTimeout(currentBannerTimeout);	//	Just in case
		currentBannerTimeout = setTimeout("timeoutBannerShow()", initbannerdelay);
		curBannerState = 1;
	} else {
		//	Banner not loaded, fetch it and wait until loaded
		fetchBanner(nextBanner);
		curBannerState = 3;
		bannerLoadCount = 0;
		bannerDelayValue = initbannerdelay;
		currentBannerTimeout = setTimeout("timeoutBannerLoad()", bannerloaddelay);
	}
	bannerProcessing = false;
}

function timeoutBannerLoad() {
	//	Timeout occurred during slide loading
	bannerProcessing = true;
	switch(curBannerState) {
		case 3: //	Loading next slide in show
			//	Loading in progress, first test if slide loaded
			if (testIfBannerLoaded(nextBanner)) {
				//	Banner loaded, start the timer for the next slide
				//	We need to subtract the time taken to load this slide from
				//	the normal slide change period
				modifiedbannerdelay = bannerDelayValue - (bannerLoadCount * bannerloaddelay);
				if (modifiedbannerdelay < 10) {
					modifiedbannerdelay = bannerloaddelay;
				}
				bannerLoadCount = 0;
				curBannerState = 1;
				currentBannerTimeout = setTimeout("timeoutBannerShow()", modifiedbannerdelay);
			} else {
				//	Banner still loading, increment count and start timer
				bannerLoadCount ++;
				currentBannerTimeout = setTimeout("timeoutBannerLoad()", bannerloaddelay);
			}
			break;
		case 0:	//	Initialisation - waiting for first banner to load - should already be there
			break;
		case 1: //	Idle state
		case 2: //	Banner swapping in progress
		case 4: //	Big banner displayed
			//	No action - timeout should not have occurred in this state
			break;
		default: //	Current state taken on prohibited value for some reason
			defaultBannerHandler('Loading Timeout');
			break;
	}
	bannerProcessing = false;
}

function timeoutBannerSwap() {
	//	Timeout occurred during slide swapping
	bannerProcessing = true;
	switch(curBannerState) {
		case 1: //	Banner show in progress, awaiting timeout
		case 3: //	Loading next slide in show
		case 4: //	Big banner displayed
			//	No action - timeout should not have occurred in this state
			break;
		case 2: //	Banner swapping in progress
			bannerSwapCount ++;
			if (swapBanners(currentBanner, nextBanner, bannerWidth, bannerHeight, bannerSwapCount, bannerswapdelay, bannerAltText)) {
//alert("banners swapped, current = " + currentBanner + "  next = " + nextBanner);
//alert("banner 0 status = " + bannerStatus[0] + "  banner 1 status = " + bannerStatus[1]);
				//	Swapping process is complete, change the slide counter and caption
				//updateBannerCaptions(nextBanner);
				//	set new slide numbers
				bannerSwapCount = 0;
				currentBanner = nextBanner;
				nextBanner = (nextBanner + 1) % numBanners;  // modulus arithmetic enables pointer wraparound
				if (testIfBannerLoaded(nextBanner)) {
					//	Banner loaded, set the slideshow timer
					bannerSwapCount = 0;
					currentBannerTimeout = setTimeout("timeoutBannerShow()",bannerdelay);
					curBannerState = 1;
				} else {
					//	Banner not loaded, send instruction to fetch it
					fetchBanner(nextBanner);
					curBannerState = 3;
					bannerLoadCount = 0;
					bannerDelayValue = bannerdelay;
					currentBannerTimeout = setTimeout("timeoutBannerLoad()", bannerloaddelay);
				}				
			} else {
				//	Banner swapping process incomplete, start timer for next step
				currentBannerTimeout = setTimeout("timeoutBannerSwap()", bannerswapdelay);
			}
			break;
		default: //	Current state taken on prohibited value for some reason
			defaultBannerHandler('Banner Swap Timeout');
			break;
	}
	bannerProcessing = false;
}

function timeoutBannerShow() {
	//	Timeout signalling that next slide needed
	bannerProcessing = true;
	switch(curBannerState) {
		case 1: //	Banner show in progress
//alert("about to swap, current = " + currentBanner + "  next = " + nextBanner);
			//	Time to swap slides, go to the slide swap process
			bannerSwapCount = 0; // Just to be sure, reset the count
			curBannerState = 2;
			currentBannerTimeout = setTimeout("timeoutBannerSwap()", bannerswapdelay);
			break;

		case 2: //	Banner swapping in progress
		case 3: //	Loading next slide in show
		case 4: //	Big banner displayed
			//	No action - this timeout should not have occurred in this state
			break;
		default: //	Current state taken on prohibited value for some reason
			defaultBannerHandler('Banner Show timeout');
			break;
	}
	bannerProcessing = false;
}

function fetchBanner(bannerindex) {
	//	Kick off the process of fetching the next slide
	if (bannerLoadBusy0 == false) {
		bannerList[bannerindex] = new Image();
		bannerLoad0 = bannerindex;
		bannerLoadBusy0 = true;
		bannerList[bannerindex].onload = bannerLoadEvt0;
	} else {
		if (bannerLoadBusy1 == false) {
			bannerList[bannerindex] = new Image();
			bannerLoad1 = bannerindex;
			bannerLoadBusy1 = true;
			bannerList[bannerindex].onload = bannerLoadEvt1;
		}
	}
	var tempsrc = bannerpath + bL[bannerindex] + bannerextn;
	bannerList[bannerindex].src = tempsrc;
	return true;
}

function testIfBannerLoaded(bannerindex) {
	//	Test if slide has been downloaded from server
	//	Returns true if slide has loaded, false if not
	return (bannerStatus[bannerindex]);
}

function bannerLoadEvt0() {
	//	This process is activated when a requested banner is completely loaded
	//	(i.e. the "onload" event has occurred)
	bannerStatus[bannerLoad0] = true;
	bannerLoadBusy0 = false;
}

function bannerLoadEvt1() {
	//	This process is activated when a requested banner is completely loaded
	//	(i.e. the "onload" event has occurred)
	bannerStatus[bannerLoad1] = true;
	bannerLoadBusy1 = false;
}

function testIfBannerError(bannerindex) {
	//	Test if download has failed for some reason
	//	Returns true if failed, false if not
	//	Check whether the default timeout limit has been exceeded
	//	Might change this to an "onerror" event handler in due course
	if ((bannerLoadCount * bannerloaddelay) > bannerloadTimeout) {
		return true;
	} else {
		return false;
	}
}

function bannerResetIdle() {
	//	Resets to the slide show Idle state, either due to a fault or by operator control
	clearTimeout(currentBannerTimeout);
	startstopRequest = false;
	nextBannerRequest = false;
	bannerLoadCount = 0;
	bannerSwapCount = 0;
	statusMessage(" ");
	curBannerState = 1;
}

function defaultBannerHandler(msg) {
	//	Handles the condition when curBannerState has a non-valid value
	//	Reset everything to the idle state
	bannerResetIdle();
}
