/*
 * 
 * $bbc.co.uk	:: BBC Weather
 * $title	:: Map Presenter SlideShow Engine
 * $version	:: 2.1
 * $author	:: BBC Weather
 * $date	:: 01.04.05
 * $notes 	:: Main slide show engine.
 * $updates	:: 
 * 
*/

// Slideshow page hooks/event handlers
/***********************************************************************************************/
function slideplay() { aSlideShow.Play(); }
function slidestop() { aSlideShow.Stop(); }
function slideback() { aSlideShow.Back(); }
function slidenext() { aSlideShow.Next(); }
/**********************************************************************************************
 * Slideshow object
 * displays images and captions. Uses paradigm of a slide projector, shining images onto a screen
 * Constructor takes:
 * 		imgArray - array of images(or path strings)
 * 		strScreenName - name of HTML element to use as screen, 
 * 		offset - offset thru array at which to start showing images, 
 * 		captions - array of captions to go with images
 *		loopMode - boolean: loop the animation or not?
 *		showInitial - boolean: at the end of the loop, show the initial image?
 * Dependancies: newSetInterval - an alternative to setInterval that provides facilities to 
 * pass parameters to the repeatedly called function
 * (all found getElement - a x-browser HTML element finder in tools.js)
 * writeText - an x-browser text/html writing function
*/

function Slideshow( imgArray, strScreenName, offset, captions, loopMode, showInitial )
{
	// initialise members
	this.slideShowTimer = 0;
	this.slides = imgArray;
	this.captions = captions;
	this.len = this.slides.length;
	this.initial = offset;

	this.slideIndex = typeof offset != "undefined" ? (offset = offset > this.slides.length-1? this.slides.length-1: offset): 0; // if there's an offset, and it's not bigger than the length of the Array, use the offset, otherwise start at slide 0
	this.screen = getElement( strScreenName ); // the screen - "screen" in the sense of a blank sheet onto which a slideshow can be projected
	this.hourCaption = getElement('imageHour');
	this.dayCaption = getElement('imageDay');
	this.playState = this.len > 1? 0: 2;
	this.loopMode = typeof loopMode != 'undefined'? loopMode: false;
	this.showInitial = typeof showInitial != 'undefined'? showInitial: false;

	// show first slide
	if ( g_bPreload ) { 
		this.screen.src = this.slides[this.slideIndex].src;
	} else { 
		this.screen.src = this.slides[this.slideIndex];
	}
}

// kicks off the slide show animation, one frame per second - this function toggles play and stop
function _play() 
{
	if (playing == true){
		// the "playing" variable is set to true, so this function will stop the animation.
		this.playState = 0;
		this.checkButtons();
		newClearInterval( this.slideShowTimer );
		playing = false;
		
	} else {
		// the animation is currently stopped; resume playing from here
	if( this.playState != 1) {
		this.playState = 1;
		this.slideIndex = 0;
		playing = true;
		if( g_bPreload )
			this.screen.src = this.slides[this.slideIndex].src;
	 	else
			this.screen.src = this.slides[this.slideIndex];
		this.showCaption();
		this.checkButtons();
		this.slideShowTimer = newSetInterval( animate, 1000, this );
		}
	}
}

// this function is still referred to in other places
function _stop()
{
	this.playState = 0;
	this.checkButtons();
	newClearInterval( this.slideShowTimer );
}

// steps back through the slides
function _back() 
{
	if( this.slideIndex-1 > -1 )
		if( g_bPreload )
			this.screen.src = this.slides[--this.slideIndex].src;
		else
			this.screen.src = this.slides[--this.slideIndex];

	this.showCaption();
	this.checkButtons();
}

// advances to the next slide
function _next() 
{
	if( this.slideIndex+1 < this.len )
	{
			if( g_bPreload )
				this.screen.src = this.slides[++this.slideIndex].src;
			else
				this.screen.src = this.slides[++this.slideIndex];
	}
	this.showCaption();
	this.checkButtons();
}

// shows the slide caption, if there are any to show
function _showCaption()
{
	if( this.captions && this.captions.length != 0 ) {
		var bg = getElement( 'captionbg' );

		if( this.captions[this.slideIndex][HOUR] == '' ) {
			bg.src = bg.src.replace( 'two', 'one' );
		} else {
			bg.src = bg.src.replace( 'one', 'two' );
		}

		writeText( this.captions[this.slideIndex][DAY], this.dayCaption );
		writeText( this.captions[this.slideIndex][HOUR], this.hourCaption );
	}
}

// sets buttons inactive or active
function _checkButtons()
{
	// set play/stop higlight/lowlight
	switch( this.playState )
	{
	case 0:
//		activateButton('stop','off');
		activateButton('play','on');
		break;
	case 1:
	//	activateButton('stop','on');
		activateButton('play','stop');
		break;
	case 2:
		//activateButton('stop','off');
		activateButton('play','stop');
		break;
	}

	// set back/next higlight/lowlight
	if( this.slideIndex-1 < 0 )
		activateButton('back','off');
	else
		activateButton('back','on');	

	if( this.slideIndex+1 >= this.len )
		activateButton('next','off');
	else
		activateButton('next','on');	
}

Slideshow.prototype.Play = _play;
Slideshow.prototype.Stop = _stop;
Slideshow.prototype.Next = _next;
Slideshow.prototype.Back = _back;
Slideshow.prototype.showCaption = _showCaption;
Slideshow.prototype.checkButtons = _checkButtons;

// Shows the next slide in the array, looping to the start if the end is reached
// The first tiem this is called, it's passed a reference to the slideshow object from whcih it was called
function animate( show ) 
{

	// if there's a "next" frame
	if( show.slideIndex + 1 < show.len )
	{
		// load the next frame
		if(!g_bPreload) 
		{
			if(navigator.appVersion.indexOf("Mozilla/4.0") == -1) {
				if(!show.cImage) 
					show.cImage = new Array();
	
				if(!show.cImage[show.slideIndex + 1]) {
					show.cImage[show.slideIndex + 1] = new Image();
					show.cImage[show.slideIndex + 1].src = show.slides[show.slideIndex + 1];
				}
				if(!show.cImage[show.slideIndex + 1].complete) {
					return;
				}
				else {
					show.cImage = undefined;
				}
			}
		}

		// ... show it
		if( g_bPreload )
			show.screen.src = show.slides[++show.slideIndex].src;
	 	else
			show.screen.src = show.slides[++show.slideIndex];
		show.showCaption();
	}
	else
	{
		// back to the start?
		if( show.loopMode )
		{
			show.slideIndex = 0;
			if( g_bPreload )
				show.screen.src = show.slides[++show.slideIndex].src;
		 	else
				show.screen.src = show.slides[++show.slideIndex];
			show.showCaption();
		}
		// if not looping
		else 
		{
			// show "last" or show "initial" image?
			if( show.showInitial )
				show.slideIndex = show.initial;
			else
				show.slideIndex = show.len-1;

			if( g_bPreload )
				show.screen.src = show.slides[show.slideIndex].src;
		 	else
				show.screen.src = show.slides[show.slideIndex];
			show.showCaption();
			show.playState = 0;
			newClearInterval( show.slideShowTimer );
		}
	}
	show.checkButtons();
}


/* make buttons active/inactive
 *************************/
function activateButton( whichButton, whatState )
{
	var imgButton = getElement( whichButton +'Img' );
	switch( whatState )	
	{
	case 'on':
		imgButton.src = imgButton.src.replace('_off','_on');
		if(DOM)
			imgButton.style.cursor = 'pointer';
		else if( NETFOUR )
			imgButton.cursor = 'pointer';
		break;
	case 'off':
		imgButton.src = imgButton.src.replace('_on','_off');
		if(DOM)
			imgButton.style.cursor = 'default';
		else if( NETFOUR )
			imgButton.cursor = 'default';
		break;
	case 'stop':
		imgButton.src = imgButton.src.replace('_on','_off');
		if(DOM)
			imgButton.style.cursor = 'pointer';
		else if( NETFOUR )
			imgButton.cursor = 'pointer';
		break;
	default:
		alert("can't find Button or didn't get expected state");
	}
}
