/*
	JavaScript Slide-Show in a Single HTML Document
	by Craig M. Buchek

	Created: 2003.04.20
	Updated: 2003.07.06, 2003.07.16


USAGE:
	Reference this JavaScript file in one of 2 ways:
		Add this line in the HEAD section of your HTML file:
			<script language="JavaScript1.2" src="slide-show.js" type="text/JavaScript"></script>
		Or copy this whole file into the HEAD section of your HTML file between these tags:
			<script language="JavaScript1.2">
			</script>
		If you use this as a separate file, make sure it is in the same directory as the HTML file.
	The HTML BODY section must initialize the slide show and the keyboard handler:
		<body onload="initSlides()" onkeypress="handleKey()">
	Every slide must be contained in an element of class="slide".
		DIV is probably best enclosing element to use, but any block-type element should work.
		Slides will be shown one at a time.
			Anything not within a slide element will always be shown.
	Controls:
		There should be a set of controls (wherever you like) in the HTML as follows (the names are important):
			<form name="controls" action="">
			 <input name="Prev" value="Prev" type="button" onclick="showPrev()" />
			 <select name="Goto" onchange="show(this.selectedIndex-1)" onclick="this.selectedIndex=current+1;">
			  <option value="" selected="">Go to...</option>
			 </select>
			 <input name="Next" value="Next" type="button" onclick="showNext()" />
			</form>
		The Prev and Next buttons work as expected.
			The Next buttons is focused by default, so just hitting Space will move forward.
		The drop-down allows you to jump to any slide.
			At the bottom, there's also a choice to show all the slides at once.
		Keyboard controls:
			Next: N, =, +, cursor right
			Prev: P, B, -, cursor left
			(Cursor keys only work in IE.)
	Browser compatibility:
		This should work with IE 4+, Netscape 6+, and Mozilla 1.0+.
			It has not been thoroughly tested with all of them.
		For the most part, the code should be W3C DOM-compliant.
		JavaScript (obviously) must be enabled on the browser.
			 Without JavaScript, the browser should just show the whole document.

TODO:
	Position controls so they don't move around.
		Probably use CSS.
	Implement per-slide title-changing.
		And add it to the drop-down.
	Fix Mozilla (1.2b Win) problems:
		Getting error about e having no properties in e.which, although it still works OK.
		Bell rings when hitting keys sometimes.
	Allow myslides.html#1 type URLs.
		For external references.
		Also change URL when we change slides.
		May change the whole JavaScript concept.
		Will have to parse URL.
		Not sure if I prefer #1 or ?slide=1 syntax.
			Chose #1 initially, because it's easier to parse.
			#1 makes more sense to jump to a particular item within the page.
				But clicking on a link to anchor won't cause the browser to do anyhting(at least IE).
			?slide=1 makes it easier to reference a single slide from external sites.
				But it causes an entire page reload/render (at least in IE).
	Add license statement. (NOT GPL.)
	Steal stuff from KWikiSlideShow.
	Steal stuff from PHP Presentation system.
		http://talks.php.net/slides.js
		CSS styles.
		Slides - but they're not that great.
			Also add delayed display of items.
	Add per-slide JavaScript.
	Add wipes and fades.
		May be easier with the #slidenum URL method.
		See http://www.boogiejack.com/howx036.html
			IE only.
			Also http://www.macromedia.com/v1/documents/css2/css015.html
	Allow background image changing:
		document.body.background = 'whatelse.gif';
		Probably just use Mozilla's View | Use Style.
			Wonder if we can use LINK REF="next" etc.
				Would probably have to parse #slidenum from URL.
	Add Larger and Smaller font changing.
		Hook to some keys.

	Other DHTML/JS snippets:
		Sort a table: http://www.faqts.com/knowledge_base/view.phtml/aid/2098/fid/128
		Find elements containing an attribute value: http://www.faqts.com/knowledge_base/view.phtml/aid/2107/fid/128
*/


// Global variables

var IE = (document.all) ? 1 : 0;	// Flag whether we can use IE-specific functions.
var slides;		// Array of all our slides. Number of slides is in slides.length.
var current;		// Keep track of the current slide.


function initSlides ()
{
	// Get a list of all the slides (elements with class="slide").
	slides = getElementsByClass( "slide" );
	// Go to the slide specified in the URL.
//	var page = parseInt( location.hash.substring(1), 10 ) - 1;
	// TODO: This doesn't look for an actual 'slide=', just '='.
//	var page = parseInt( location.search.substring(location.search.indexOf('=')+1), 10 ) - 1;

//	// Make sure the requested slide exists, or default to 0.
//	if ( isNaN( page ) || page < 0 || page >= slides.length )
//	{
		page = 0;
//	}

	// Get the ID of the drop-down.
	var dropdown = document.controls.Goto;

	// Add an option to the drop-down for each slide.
	for ( var i = 0; i < slides.length; i++ )
	{
		slidenum = i+1;	// Show the slide numbers to the user 1-based.
		slidetitle = get_title(slides[i], i);
		addOptionToSelection( dropdown, slidetitle, i );
	}

	// Show just the requested page (or 1st if none specified) to start out.
	show( page );

	// Add an option to show all slides.
	addOptionToSelection( dropdown, "Show All Slides", "all" );

	// Focus the Next button so we can just hit Space to move forward.
	document.controls.Next.focus();

	// Set keyboard handler. (IE also requires it be set on the BODY in the HTML.)
	// NOTE: For some reason, execution does not seem to get past these lines, at least in IE.
	if ( !IE )
	{
		document.captureEvents( Event.KEYPRESS );
		document.onkeypress = handleKey;
	}
}

function show ( n )
// NOTE: This function is 0-based.
{
	if ( n == "all" )
	{
		showAll();
		return;
	}

	// Check to make sure we've got a slide like that.
	if ( n < 0 || n >= slides.length )
	{
		return;
	}

	// Remember this slide.
	current = n;

	// Show the requested slide.
	slide_to_show = slides[n];
	slide_to_show.style.display = "block";
	if ( IE )
	{
		// The following make sure our controls don't scroll off the window.
		slide_to_show.style.position = "absolute";
		slide_to_show.style.overflow = "auto";
		slide_to_show.style.height = "100%";
		slide_to_show.style.width = "100%";
	}

	// TODO: Show title in title bar.

	// Hide all the other slides.
	for (var i = 0; i < slides.length; i++ )
	{
		if ( i == n ) continue;
		slide_to_hide = slides[i];
		slide_to_hide.style.display = "none";
	}
}

function showNext ()
{
//location.search = "?slide=" + (current+1+1);
//location.hash = "#" + (current+1+1);
//return;

	show( current + 1 );

	// Set the drop-down to default choice and focus Next button.
	document.controls.Goto.selectedIndex = 0;
	document.controls.Next.focus();
}

function showPrev ()
{
//location.search = "?slide=" + (current-1+1);
//location.hash = "#" + (current-1+1);
//return;

	show( current - 1 );

	// Set the drop-down to default choice and focus Prev button.
	document.controls.Goto.selectedIndex = 0;
	document.controls.Prev.focus();
}

function showAll ()
{
	for (var i = 0; i < slides.length; i++ )
	{
		if ( i == current ) continue;
		slide_to_show = slides[i];
		slide_to_show.style.display = "block";
	}

	current = 0;

	// Reset the drop-down to the default choice and unfocus it.
	document.controls.Goto.selectedIndex = 0;
	document.controls.Goto.blur();
}

function handleKey ( e )
{
	if ( IE )
	{
		key = window.event.keyCode;
	}
	else
	{
		key = this.which;
	}

//	alert( "got event " + e + " keycode " + key );

	if ( key == 110 || key == 61 || key == 43 || key == 39 )	// N, =, +, right
	{
		showNext();
	}
	if ( key == 112 || key == 98 || key == 45 || key == 37 )	// P, B, -, left
	{
		showPrev();
	}
}

function getElementsByClass ( className )
// NOTE: Returns an array of elements.
// Got this from http://www.faqts.com/knowledge_base/view.phtml/aid/2193/fid/128
{
	var all = document.all ? document.all : document.getElementsByTagName('*');
	var elements = new Array();
	for ( var e = 0; e < all.length; e++ )
	{
		if ( all[e].className == className )
			elements[elements.length] = all[e];
	}
	return elements;
}

function addOptionToSelection ( selection, option, value )
// Got this from http://www.faqts.com/knowledge_base/view.phtml/aid/1181/fid/178:
{
	selection.options[selection.options.length] = new Option( option, value );
}

function get_title ( slide, slidenum )
{
	if ( IE )
	{
		slidetitle = slide.childNodes.item(0).innerText;
	}
	else
	{
		h2 = slide.getElementsByTagName('h2')[0];
		a = h2.getElementsByTagName('a')[0];
		slidetitle = a.textContent;
	}
	slidetitle = slidenum + ' - ' + slidetitle;
	return slidetitle;
}
