/*
This code is to convert <div>s in a web page into a slide show
by writing the code for a popup automatically

To use it, set up divs in the parent page with the id of 'slide_' and the id of each slide title
e.g. <div id="slide_Guidelines"> gives a slide called 'Guidelines'
e.g. <div id="slidei_Guidelines"> gives a slide called 'Guidelines' with incremental display of bullet points

template:
</div>
<div id="slide_">

*/
function printme(text,name){ // opens a new window to start the slideshow
	winID = window.open('',name);
	with(winID.document){
		write(text);
		close();
	} // end with
	winID.focus();
} // end fn printme

/* The following function 
returns an array of objects with correct class name
See http://www.netlobo.com/javascript_getelementsbyclassname.html

But FireFox 3 has function getElementsByClassName, but returns nodeNames, not array, 
so need to change name.
See http://www.drunkenfist.com/304/2008/07/02/say-hello-to-javascripts-native-getelementsbyclassname/
*/
document.myGetElementsByClassName = function(clsName){
    var retVal = new Array(); // the return value as an array
    var elements = document.getElementsByTagName("*"); // gets all the elements
    for(var i = 0;i < elements.length;i++){ // loop through elements
        if(elements[i].className.indexOf(" ") >= 0){ // if there is more than one class for this element
            var classes = elements[i].className.split(" "); // split the class name at the space
            for(var j = 0;j < classes.length;j++){ // check all the class names
                if(classes[j] == clsName) // if there is a match
                    retVal.push(elements[i]); // add the element to the return value
            }
        }
        else if(elements[i].className == clsName) // only one class name, and it matches
            retVal.push(elements[i]); // add the element to the return value
    }
    return retVal;
} // end function

var slideHTML = '';
var splitTableHereRegExp = /(?:\<tr)[^\<]+class="?[^\<]*slideshowTableSplit"?/gi;
var tableHeaderRegExp = /<tr[^\<]+id="?table-header(.|\n)+?\<\/tr>/gi;

function startSlideShow(){
	slideHTML = ''; // set up the variable to hold the HTML
	slideHTML += '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
	slideHTML += '<html xmlns="http://www.w3.org/1999/xhtml">';
	slideHTML += '<head>';
	slideHTML += '<title>' + document.title + ' Slideshow<\/title>';
	slideHTML += '<meta name="version" content="S5 1.1" />';
	slideHTML += '<meta name="defaultView" content="slideshow" />'
	slideHTML += '<link rel="stylesheet" href="http://elc.polyu.edu.hk/cill/staff/ui51/default/slides2.css" type="text/css" media="projection" id="slideProj" />';
 	slideHTML += '<link rel="stylesheet" href="http://elc.polyu.edu.hk/cill/staff/ui51/default/outline.css" type="text/css" media="screen" id="outlineStyle" />'
 	slideHTML += '<link rel="stylesheet" href="http://elc.polyu.edu.hk/cill/staff/ui51/default/opera.css" type="text/css" media="projection" id="operaFix" />';
	slideHTML += '<link rel="stylesheet" href="http://elc.polyu.edu.hk/cill/staff/ui51/default/print.css" type="text/css" media="print" id="slidePrint" />';
	slideHTML += '<script src="http://elc.polyu.edu.hk/cill/staff/ui51/default/slides.js" type="text/javascript"><\/script>';
	slideHTML += '<script src="http://elc.polyu.edu.hk/cill/staff/ui51/default/deselect.js" type="text/javascript"><\/script>';
	// style to hide things in slides
	slideHTML += '<style TYPE="text/css">';
	slideHTML += ' .hideInSlideshow {';
	slideHTML += ' display: none;';
	slideHTML += ' } </style>';

	slideHTML += '<scr' + 'ipt type="text/javascript">';
	slideHTML += '	function popupWin(text){ ';
	//slideHTML += '  alert("Popping up " + text);';
	slideHTML += '		winID = window.open(\'\',\'PopupWindow\');';
	slideHTML += '		with(winID.document){';
	slideHTML += '			write(\'<html><head><title="Popup"><style type="text/css">table {font-size: 100%;}</style><\/head><body style="font-size: 200%;">\' + unescape(text) + \'<\/body><\/html>\');';
	slideHTML += '			close();';
	slideHTML += '		} ';
	slideHTML += '		winID.focus();';
	slideHTML += '	}  ';
	
	slideHTML += '<\/script>';
	slideHTML += '<\/head>';
	slideHTML += '<body>';
	slideHTML += '<div class="layout">';
	slideHTML += '<div id="currentSlide"><\/div>';
	slideHTML += '<div id="header">';
	slideHTML += '<div><img  style="width: 100%; height: 100%;" src="http://elc.polyu.edu.hk/cill/staff/ui51/default/ppt_top3.jpg" alt="Top Image"></div>';
	slideHTML += '<table id="headerTable" border="0" width="100%" style="position: absolute; top: 0; left 0; height: 2.5em;">';
	slideHTML += '<tr>';
	slideHTML += '<td  valign="top">';
	slideHTML += '<img src="http://elc.polyu.edu.hk/cill/logo/polyUlogo6.gif" style="position: absolute; top: 0px; left: 0px; margin-bottom: 0.3em;" alt="PolyU Logo">';
	slideHTML += '</td>';
	slideHTML += '<td style="height: 2.5em; border-right: 1.5em;" align="right">';
	slideHTML += '<img src="http://elc.polyu.edu.hk/cill/logo/elclogo42.gif" alt="ELC Logo" valign="middle" style="margin-bottom: 0.5em;">';
	slideHTML += '</td><td style="width: 2em;">';
	slideHTML += '</td>';
	slideHTML += '</tr>';
	slideHTML += '</table>'; 
	slideHTML += '<\/div>';
	slideHTML += '<div id="footer">';
	slideHTML += '<img  style="position: relative; top: -1em; width: 100%; height: 100%;" src="http://elc.polyu.edu.hk/cill/staff/ui51/default/ppt_footer_yellow_triangle.jpg" alt="Footer Image">';
	slideHTML += '<h2>' + document.title + '<\/h2>';
	slideHTML += '<div id="controls">';
	slideHTML += '<\/div>';
	slideHTML += '<\/div>';
	slideHTML += '<\/div>';

	slideHTML += '<div class="presentation">';

	// Title slide (not included in the slide show page numbering)
	slideHTML += ' <div class="slide">';
	slideHTML += '<h1 style="visibility: hidden;">';
	slideHTML += 'Title';  // slide title
	slideHTML += '<\/h1>';
	slideHTML += '<h1 align = "center">';
	slideHTML += document.title; 
	slideHTML += '<\/h1>';
	slideHTML += '<div class="handout">';
	slideHTML += '<\/div>';
	slideHTML += '<\/div>';	

	// get a list of the divs on the page
	var divList = document.myGetElementsByClassName('slide');
	//alert(divList[0]['class']);
	// make a list of slideDivs
	
	for(sd=0;sd<=divList.length;sd++){
		if((divList[sd] && divList[sd]['id'])){
			//alert(divList[sd]['id']);
			thisDivId = divList[sd]['id'];
			//alert('thisDivId =' + thisDivId );
			if(thisDivId.substring(0,6) == "slide_"){ // it's a slide
				//alert('Making slide' + thisDivId);
				slideHTML += createSlide(thisDivId.substring(6), document.getElementById(thisDivId).innerHTML);
			} // end if it's a slide
			
			if(thisDivId.substring(0,7) == "slidea_"){ // it's a slide with a href links to be removed
				//alert('Removing links from slide' + thisDivId);
				slideHTML += createSlide(thisDivId.substring(7), removeLinks(document.getElementById(thisDivId).innerHTML));
			} // end if it's a slide			

			if(thisDivId.substring(0,7) == "slidef_"){ // needs an iframe
				//alert('Making frame slide' + thisDivId);
				thisFrameName = thisDivId.substring(7); // 'iframe' + sd;
				thisFrameCode = '<iframe id="' + thisFrameName + '" src="' + document.getElementById(thisDivId).innerHTML + '" style="width: 100%; height: 16em; "></iframe>';
				if(document.all){ // in IE the frame shows on all slides, so hide it until needed
					//alert('Doing document.all');
					thisFrameCode = '<iframe id="' + thisFrameName + '" src="' + document.getElementById(thisDivId).innerHTML + '" style="width: 100%; height: 16em; display: none;" onmousemove=expandMe(\'' + thisFrameName + '\')></iframe>';
					thisFrameCode += '<a href="javascript: expandMe(\'' + thisFrameName + '\')">Show Exercise<\/a>';
				} // end if
				slideHTML += createSlide(thisDivId.substring(7),thisFrameCode);
			} // end if it's a slide
			
			if(thisDivId.substring(0,7) == "slidei_"){ // it's a slide with bullets to show incrementally
				//alert('Making incremental slide' + thisDivId);
				slideHTML += createIncrementalSlide(thisDivId.substring(7), document.getElementById(thisDivId).innerHTML);
			} // end if it's a slide

			if(thisDivId.substring(0,7) == "slidet_"){ // it's a slide from a single table row
				//alert('Making slide from table' + thisDivId);
				thisTableCode = '<table border="1" cellspacing="1" cellpadding="5" align="center" style="margin-top: 10px;"> ' + document.getElementById(thisDivId).innerHTML + '</table>';
				slideHTML += createSlide(thisDivId.substring(7), thisTableCode );
			} // end if it's a slide
			
			if(thisDivId.substring(0,7) == "slideT_"){ 
				// it's the innerHTML of a whole table to be split into slides
				// split the table at the rows with class slideshowTableSplit
				// if there is a row with id = table-header, use this row on each slide
				//alert('Making slide from table ' + thisDivId);
				slidesCode = document.getElementById(thisDivId).innerHTML;
				headerCode = '';
				headerCode = slidesCode.match(tableHeaderRegExp);
				if(headerCode) slidesCode = slidesCode.replace(headerCode,'');
				//alert('headerCode = ' + headerCode);
				//alert('slidesCode = ' + slidesCode);
				var tableSlides = new Array();
				tableSlides = slidesCode.split(splitTableHereRegExp);
				//alert('tableSlides = ' + tableSlides);
				if(tableSlides && tableSlides.length > 0){
					for(ts = 0; ts <tableSlides.length ; ts++){
						thisTableSlideCode = tableSlides[ts];
						if(thisTableSlideCode && thisTableSlideCode.length > 1){ // has content
							if(thisTableSlideCode.match(/^\>/)) thisTableSlideCode = '<tr ' + thisTableSlideCode;
							if(headerCode) thisTableSlideCode = headerCode + thisTableSlideCode ;
							thisTableCode = '<table border="1" cellspacing="1" cellpadding="5" align="center" style="margin-top: 10px;"> ' + thisTableSlideCode + '</table>';
							slideHTML += createSlide((thisDivId.substring(7) + ' ' + (ts + 1)), thisTableCode );
						} // end if
					} // end for ts
				} // end if
			} // end if it's a slide			

			if(thisDivId.substring(0,7) == "slidep_"){ // uses popup in new window
				//alert('Making slide with popup ' + thisDivId);
				popupCode = document.getElementById(thisDivId).innerHTML;
				//alert('escape(popupCode) = ' + escape(popupCode));
				clickCode = '<p style="width: 100%; margin-top: 1em; text-align: center;"><span style=" padding-right: 3px; padding-left: 3px; color: black; background: #EAEAEA; border-style: outset; text-decoration: none; line-height: 170%; cursor: pointer;" onClick="popupWin(\'' + popupCode + '\')">Click here for the Exercise</span></p>';
				slideHTML += createSlide(thisDivId.substring(7), clickCode );
			} // end if it's a slide

			if(thisDivId.substring(0,7) == "slides_"){ // need to scroll something
				//alert('Making slide with scroll bars' + thisDivId);
				slideHTML += createSlide(thisDivId.substring(7), '<div style="width: 100%; height: 16em; overflow: auto;">' + document.getElementById(thisDivId).innerHTML + '</div>');
			} // end if it's a slide

			//alert('slideHTML = ' + slideHTML);

		} // end if
	} // end for 
	
	// End slide
	slideHTML += '<div class="slide">';
	slideHTML += '<h1 style="visibility: hidden;">';
	slideHTML += 'End';  // slide title
	slideHTML += '<\/h1>';
	slideHTML += '<h3 align = "center">';
	slideHTML += '&nbsp;<br / >&nbsp;<br / >The End';
	slideHTML += '<\/h3>';
	slideHTML += '<div class="handout">';
	slideHTML += '<\/div>';
	slideHTML += '<\/div>';

	//alert('slideHTML = ' + slideHTML);

	printme(slideHTML,'slidewin');


} // end fn startSlideShow

// the <li> list may be too long for the slide
// this RegExp gets the <li>s after the split point
// shown by the class  slideshowListSplit
//var restOfPointsRegExp = /\<li class="slideshowListSplit(.|\n)+?\<\/[uo]l\>/gi;
var restOfPointsRegExp = /\<li cl.ss\W+slideshowListSplit(.|\n)+?\<\/[uo]l\>/gi;

var splitClassName = /slideshowListSplit/gi;
var splitListHTML = '';
function splitList(stitle,s1,functionToCall){
// splits a list into separate slides
	splitListHTML = ''; // holds the resulting HTML
			firstSlideContent = s1.replace(restOfPointsRegExp,'');
				//alert('firstSlideContent = ' + firstSlideContent );
			if(s1.match(restOfPointsRegExp)){
				//alert('Found restOfPointsRegExp = ' + s1.match(restOfPointsRegExp));
			}
			else {
				//alert('Not found restOfPointsRegExp');
			}
			var secondSlideContentArray = new Array();
			var secondSlideContent = '';
			secondSlideContentArray = s1.match(restOfPointsRegExp);
			if(secondSlideContentArray && secondSlideContentArray.length > 0){
				secondSlideContent = secondSlideContentArray.join(''); // because match produces an array
					//alert('secondSlideContent v1 = ' + secondSlideContent );
				if(secondSlideContent && secondSlideContent.match(splitClassName)){
					secondSlideContent = secondSlideContent.replace(splitClassName,''); // stops it repeating
				} // end if
					//alert('secondSlideContent class removed = ' + secondSlideContent );
			} // end if		
			// remove all the elements to see what's left:
			firstSlideContentListString = removeElements(firstSlideContent);
			
			if(firstSlideContentListString.match('<ol>')){
				firstSlideContent = firstSlideContent + '<\/ol>';
				if(secondSlideContent) secondSlideContent = '<ol>' + secondSlideContent + '<\/ol>';
			} // end if 
			if(firstSlideContentListString.match('<ul>')){
				firstSlideContent = firstSlideContent +  '<\/ul>';
				if(secondSlideContent) secondSlideContent = '<ul>' + secondSlideContent;
			} // end if
			if(functionToCall == 'cs'){
					//alert('About to make firstSlideContent complete = ' + firstSlideContent );
				if(stitle && firstSlideContent) splitListHTML = createSlide2(stitle + ' 1',firstSlideContent);
					//alert('About to make secondSlideContent complete = ' + secondSlideContent );
				if(stitle && secondSlideContent) splitListHTML += createSlide2(stitle + ' 2',secondSlideContent);
			}
			else if(functionToCall == 'cis'){
					//alert('About to make firstSlideContent complete = ' + firstSlideContent );
				if(stitle && firstSlideContent) splitListHTML = createIncrementalSlide2(stitle + ' 1',firstSlideContent);
					//alert('About to make secondSlideContent complete = ' + secondSlideContent );
				if(stitle && secondSlideContent) splitListHTML += createIncrementalSlide2(stitle + ' 2',secondSlideContent);
			}
	return splitListHTML;
} // end fn splitList


function createSlide(stitle,s1,s2,s3){
	if(stitle || s1 || s2 || s3){
		cSlideHTML = '';
		s1 = removeBlockQuote(s1);
		if(s1.match('slideshowListSplit')){ // needs to be split
			//alert('s1 original = ' + s1);
			cSlideHTML = splitList(stitle,s1,'cs'); // cs means create slide, as opposed to create incremental slide
		} // end if
		else{ // not splitting	
			cSlideHTML += createSlide2(stitle,s1,s2,s3);
		} // end else
	} // end if
	//alert('cSlideHTML2 = ' + cSlideHTML);
	if(cSlideHTML) return cSlideHTML;
} // end fn createSlide

//var liRegExp = /^<li(>| )(.|\n)+<\/li>$/i; // matches list with missing <ul> or <ol>
var liRegExp = /^\s*<li/i; // matches list with missing <ul> or <ol> before it at start of string
var listTypeRegExp = /<(o|u)l(>|\s)/gi; // might end in a >, or a space if there is a class in the tag
function addListType(txt){
	//alert('Doing addListType, txt = ' + txt); 
	thisListType = '<ul>'; // default
	// Next find out what type of list was used last
	var thisListTypeArray = new Array();
	//alert('slideHTML = ' + slideHTML.substr((slideHTML.length - 1000)));
	thisListTypeArray = slideHTML.match(listTypeRegExp); // what types of list were used
	//alert('thisListTypeArray = ' + thisListTypeArray );
	if(thisListTypeArray.length > 0){
		thisListType = thisListTypeArray[(thisListTypeArray.length - 1)]; // the final match
	} // end if 
	//alert('thisListType = ' + thisListType );
	textToReturn = '<' + thisListType.substring(1,3) + '>' + txt; // add the first listType
	textToReturn += '</' + thisListType.substring(1,3) + '>'; // add the closing tag
	//alert('textToReturn = ' + textToReturn );
	if(textToReturn){
		return textToReturn; // function worked and data available
	} // end if
	else return txt; // something went wrong
} // end fn addListType


var tableStartCode = '<table align="center" border="0"><tr><td>';
var tableEndCode = '<\/td><\/tr><\/table>';
function createSlide2(stitle,s1,s2,s3){
	if(stitle || s1 || s2 || s3){
		cSlideHTML = '<div class="slide">'; 
		if(stitle) cSlideHTML += '<h1>' + stitle +'<\/h1>';  // slide title
		if(s1.match(liRegExp)) s1 = addListType(s1); // check if the <ul> or <ol> is missing
		//else alert('Not doing addListType for slide ' + stitle + 's1=' + s1);
		if(s1) cSlideHTML += tableStartCode + s1 + tableEndCode + '<br>'; // point one
		if(s2) cSlideHTML += tableStartCode +  s2 + tableEndCode + '<br>'; // point 2
		if(s3) cSlideHTML += tableStartCode +  s2 + tableEndCode + '<br>'; // point 3		
		cSlideHTML += '<div class="handout">';
		cSlideHTML += '<\/div>';
		cSlideHTML += '<\/div>';
	} // end if stitle,s1,s2,s3
	//alert('cSlideHTML2 = ' + cSlideHTML);
	if(cSlideHTML) return cSlideHTML;
} // end fn createSlide

// reg exps
var ulrx = /\<ul\>/gi;
var eulrx = /\<\/ul\>/gi;
var prx = /\<p\>/gi;
var eprx = /\<\/p\>/gi;

function createIncrementalSlide(stitle,s1,s2,s3){
	if(stitle || s1 || s2 || s3){
		cSlideHTML = '';
		s1 = removeBlockQuote(s1);
		if(s1.match(liRegExp)) s1 = addListType(s1); // check if the <ul> or <ol> is missing
		if(s1.match('slideshowListSplit')){ // needs to be split
			//alert('s1 original = ' + s1);
			cSlideHTML = splitList(stitle,s1,'cis'); // cs means create slide, as opposed to create incremental slide
		} // end if
		else{ // not splitting	
			cSlideHTML += createIncrementalSlide2(stitle,s1);
		} // end else
	} // end if
	//alert('cSlideHTML2 = ' + cSlideHTML);
	if(cSlideHTML) return cSlideHTML;
} // end fn createSlide

function createIncrementalSlide2(stitle,s1){
	if(stitle || s1){
		cSlideHTML = '';
		s1 = removeBlockQuote(s1);
		var bulletContents = new Array();
		bulletContents = s1.split('<li>');
		cSlideHTML += '<div class="slide">';
		if(stitle) cSlideHTML += '<h1>' + stitle +'<\/h1>';  // slide title
		//cSlideHTML += '<ul class="incremental"  style="display: table; margin-left: auto; margin-right: auto;">';
		cSlideHTML += tableStartCode;
		if(s1.match(ulrx)){ // there's a <ul> tag
			if(document.all) s1 = s1.replace(ulrx,'<ul class="incremental">');
			else s1 = s1.replace(ulrx,'<ul class="incremental" onmouseover="deselect()" style="display: table; margin-left: auto; margin-right: auto;">')
			//alert(s1);
			s1 = s1.replace(ulrx,'');
			s1 = s1.replace(eulrx,'');
		} // end if
		else{ // no <ul> tags
			// so add <ul> and replace <p> with <li>
			if(document.all) s1 = '<ul class="incremental">' + s1;
			else s1 = '<ul class="incremental" onmouseover="deselect()" style="display: table; margin-left: auto; margin-right: auto;">' + s1;
			s1 = s1.replace(prx,'<li>');
			s1 = s1.replace(eprx,'</li>');
		} // end else
		if(s1) cSlideHTML +=  s1 + '<br>'; // point one
		cSlideHTML += '<\/ul>';
		cSlideHTML += tableEndCode;
		cSlideHTML += '<div class="handout">';
		cSlideHTML += '<\/div>';
		cSlideHTML += '<\/div>';
	} // end if stitle,s1,s2,s3,s4,s5
	return cSlideHTML; 
} // end fn createSlide

var buttonCode = '<form name="slideshowButtonForm">';
buttonCode += '<p><b>View</b><br>This page can be viewed as a slideshow: ';
buttonCode += '<input type="button" style="font-size: 100%;" value="Start Slideshow" onClick="startSlideShow()">';
buttonCode += '</p></form>';
document.write(buttonCode);

var bqrx = /\<(\/)?blockquote\>/gi;
function removeBlockQuote(txt){ // because it messes things up
	txt = txt.replace(bqrx,'');
	return txt;
} // end fn removeBlockQuote

var ahrefRegExp = /\<(\/)?a.*?\>/gi;
function removeLinks(txt){
// removes <a href and </a> links
	if(txt){
		txt = txt.replace(ahrefRegExp,'');
		return txt;	
	} // end if
} // end fn removeLinks


//var eleRemoverRegExp = /<(\S+).*?(>| )(.|\n)*?<\/\1>/gi;
var eleRemoverRegExp = /<(\w{1,6}).*?>(.|\n)*?<\/\1>/gi;
// where the 1 is a back reference to the first group

function removeElements(ele){ 
// removes elements from a string
// e.g. a from opening to closing tag
	if(ele){
		if(ele.match(eleRemoverRegExp)){
			//alert('removed ' + ele.match(eleRemoverRegExp));
			ele = ele.replace(eleRemoverRegExp,'');			
			//alert('New ele = ' + ele);
			return ele;
		} // end if
		//else alert('Nothing removed');
		return '';
	} // end if
	else return '';
} // end fn removeElement

var lbRegExp = /(\n|\r)/gi;
var comRegExp = /'/gi;
var dcomRegExp = /"/gi;

document.write(' <style type="text/css">.hideInEx {display: none;}</style>');

