/* This script will produce the effect of a turning page in an open book. It requires at least four images and, if the pages are not to keep swopping sides, it requires an even number too.  Ideally, these images are the  same width and height. (In this display each image used is itself made up of different size pictures.) To ensure a smooth effect, all the images for the book are first downloaded, before the page-turn effect is applied, otherwise blank pages or partly loaded pages appear. The image.onload event is used to detect the successful loading of an image. The procedure used is to assign the src to an invisible test image. If the onload event for this image is fired, then it might be considered that the full image has been downloaded. Unfortunately IE browsers sometimes fail to download a full image. To check if this has happened, the image height is measured. If it exceeds a certain minimum, the image download is considered successful. If not, it is rechecked and if the height remains unchanged for a given number of measurements, the image is considered faulty and further downloading ceases.. 
	 If the download is a considered a success, its src is transferred to the appropiate element in 'imgBase', the array of images needed for the 'pageflip' and then the next download is initiated. The process continues until all images needed for the 'pageflip' are downloaded after which the function 'startFlip' is called. If the onerror event occurs, due to an image being wrongly named or missing or any image downloaded is considered faulty, then the function 'startFlip' is not called and no page turning ensues. 
	The function 'startFlip' cause one page-turn initially. Further turns can be made by clicking on the open book display. A notice giving instructions how to do this is displayed. Once all the images have been used, the sequence begins again.
	It is possible to have the book with its spine parallel to the top of the screen or parallel to the side of the screen by changing the value of the variable 'spineHorizontal'.*/

   //Define preset values for page turning of book
	var pgImgWidth=242; // width of one image. Book's width will be twice this
	var pgImgHt=564; // page and book height
	var pgBorder=true;  // If true,a border will be set round each page
	var pgBorderColor="black";// color of border
	var pgBorderWidth="1px"; //width of border
	var turnSpeed=16;// speed pages turn over - the bigger this value, the faster
	var spineHorizontal=false; //This indicates spine of book is vertical. Set to true if spine of book is horizontal
	
   //Create object imgSources
	imgSources=new Array(
	        'images/threePicsSmalla.jpg', //comma indicates more elements to come
           'images/threePicsSmallb.jpg',
           'images/threePicsSmallc.jpg',
           'images/threePicsSmalld.jpg',
           'images/threePicsSmalle.jpg',
           'images/threePicsSmallf.jpg',
		     'images/threePicsSmallg.jpg',
		     'images/threePicsSmallh.jpg',
		     'images/threePicsSmallii.jpg',
		     'images/threePicsSmallj.jpg' // no comma indicates last element in array
		);
	var noteDiv=document.createElement("div");
	
	var parag=document.createElement("p");
	var noteTxt ="";
	var noteNode=document.createTextNode(noteTxt);
   var bkLeftImg,bkMidImg,bkRightImg,imgSwop;// images used during page turning
   var pageElevation=0;
   var turningImg=3;  //this gives the index of the element in the imgBase array, which is used initially for bkMidImg or bkRightImg used in the 'turning page' display.
   var flipDirection=1;  //This changes to 0, when  turning page is at right angles to other pages.
	var turningImgSize; //width of visible turning page if spine vertical or height of turning page if spine horizontal
	var noTurn=false;
	var noteShown = false;
	imgBase=new Array(imgSources.length);// image base from which images for page turning display are chosen.
	loadingSideTracked=true;
	
	
	function getFlipImgs(){
	if(!document.getElementById){ return false;}
	if(!document.createElement){return false;}
	bkNoteData("In the process of getting more pictures.","340px");
	preloadImgs(0,imgSources.length);
	
	
	/*
	if(loadingSideTracked){
	startFlip();
	}
	*/
	
	} //eof getFlipImgs
	
	
	function startFlip(){	
		//This function is only called if all images needed for the 'book' are preloaded.
		var bkDiv=document.getElementById("book");
		var positn=	findPosn(bkDiv);
		 xCoord=positn[0]-362;	//values for Mozilla Firefox
		 yCoord=positn[1]-360;	
		 if(document.addEventListener && window.opera){ //if Opera
		  xCoord=positn[0]-336;//343
		 yCoord=positn[1]-349;	
		 }
		   else if(document.all){ // if IE
		  xCoord=positn[0]-359;
		 yCoord=positn[1]-348;	//358
		 }
		oldImg=bkDiv.getElementsByTagName("img");
		oldImg[0].style.visibility="hidden";
		bkLeftImg=document.createElement("img");
		bkDiv.appendChild(bkLeftImg);	
		bkRightImg=document.createElement("img");
		bkDiv.appendChild(bkRightImg);
		bkMidImg=document.createElement("img");
		bkDiv.appendChild(bkMidImg);	
		bkLeftImg.style.position=bkMidImg.style.position=bkRightImg.style.position="absolute";
		bkLeftImg.style.zIndex=bkRightImg.style.zIndex=0;bkMidImg.style.zIndex=1;
			
			bkLeftImg.style.left=xCoord+"px";
			bkMidImg.style.top=yCoord+"px";
			bkRightImg.style.top=yCoord+"px";
			
		if(spineHorizontal){
		bkLeftImg.style.top=pgImgHt+yCoord+1 +"px";
		bkMidImg.style.left=xCoord+"px";
		bkRightImg.style.left=xCoord +"px";
		
		}else{
		bkLeftImg.style.top=yCoord+"px";
		bkMidImg.style.left=pgImgWidth+xCoord+1+"px";
		bkRightImg.style.left=pgImgWidth+xCoord+1+"px";
		}
		
		/* The following ternary conditional operators could be used instead of the if/else statement above.
		bkLeftImg.style.top=(spineHorizontal?pgImgHt+yCoord+1:yCoord)+"px";
		bkMidImg.style.left=(spineHorizontal?xCoord:pgImgWidth+xCoord+1)+"px";
		bkRightImg.style.left=(spineHorizontal?xCoord:pgImgWidth+xCoord+1)+"px";
	  */

			bkLeftImg.style.height=pgImgHt+"px";
			bkMidImg.style.height=pgImgHt+"px";
			bkRightImg.style.height=pgImgHt+"px";
			bkLeftImg.style.width=pgImgWidth+"px";
			bkMidImg.style.width=pgImgWidth+"px";
			bkRightImg.style.width=pgImgWidth+"px";
			if(pgBorder){ //if b
				bkLeftImg.style.borderStyle=bkMidImg.style.borderStyle=bkRightImg.style.borderStyle="solid";
				bkLeftImg.style.borderWidth=pgBorderWidth;
				bkMidImg.style.borderWidth=pgBorderWidth;
				bkRightImg.style.borderWidth=pgBorderWidth;
				bkLeftImg.style.borderColor=bkMidImg.style.borderColor=bkRightImg.style.borderColor=pgBorderColor;
			} //end if b
			
			bkMidImg.src=imgBase[0].src;
			bkLeftImg.src=imgBase[1].src; 
			bkRightImg.src=imgBase[2].src; 
			
			bkLeftImg.onclick=bkMidImg.onclick=bkRightImg.onclick=pgTurnIfOK;
			bkImgs();
	} //eof startFlip


	function pgTurnIfOK(){
		if(pageElevation<Math.PI){return false;
		}else{
		nextTurn();
		}
	}

	function bkImgs(){
		if(!noTurn){ //if1
			if(spineHorizontal){ //if2
				turningImgSize=Math.abs(Math.round(Math.cos(pageElevation)*pgImgHt));
				MidOffset=!flipDirection?pgImgHt+1:pgImgHt-turningImgSize;
				bkMidImg.style.top=MidOffset+yCoord+"px";
				bkMidImg.style.height=turningImgSize+"px";
				} //end if2
				else{ 
				turningImgSize=Math.abs(Math.round(Math.cos(pageElevation)*pgImgWidth));
				MidOffset=flipDirection?pgImgWidth+1:pgImgWidth-turningImgSize;
				bkMidImg.style.left=MidOffset+xCoord+"px";
				bkMidImg.style.width=turningImgSize+"px";
				} //end else
			pageElevation+=turnSpeed/720*Math.PI;
			if(pageElevation>=Math.PI/2&&flipDirection){ //if3
				flipDirection=0;
				if(turningImg==imgSources.length){ // if4
				turningImg=0;
				} // end if4
				bkMidImg.src=imgBase[turningImg].src;
				turningImg++;
				 } //end if3
			if(pageElevation>=Math.PI){ //if5
				flipDirection=1;
				imgSwop=bkLeftImg;
				bkLeftImg=bkMidImg;
				bkMidImg=imgSwop;
				if(spineHorizontal){ //if6
				bkMidImg.style.top=yCoord+"px";
			} // end if 6
			else{
				 bkMidImg.style.left=pgImgWidth+1+xCoord+"px";	
			 }	 // end else	
				bkMidImg.src=bkRightImg.src;
				stopPgTurn;
				if(!noteShown){ // if7
					bkNoteData("Click on the pictures to turn them over.","330px");
					noteShown=true;
			} // end if7
		} //end if5
		else {
		setTimeout("bkImgs()",75);
		} //end else
		} // end if1
		else{
		setTimeout("bkImgs()",75);
	}//end else
} //eof bkImgs


function nextTurn(){
		if(turningImg==imgSources.length){
			turningImg=0;
		} //end if
		bkRightImg.src=imgBase[turningImg].src;
		bkMidImg.style.zIndex=2;
		bkLeftImg.style.zIndex=1;
		pageElevation=0;
		turningImg++;
		setTimeout("bkImgs()",75);
} //eof nextTurn

	
function stopPgTurn(){
	noTurn=true;
}  //eof stopPgTurn
	
	
function bkNoteData(note,noteWidth){

   noteDiv.id="note";
   noteDiv.style.zIndex=2;
   var noteTxt=note;
   noteNode=document.createTextNode(noteTxt);
   document.body.appendChild(noteDiv);
   parag.appendChild(noteNode);
   noteDiv.style.borderWidth="2px";
   noteDiv.style.borderColor="black";
   noteDiv.style.border="solid";
   noteDiv.style.backgroundColor="#dfd";
	noteDiv.style.color="#806";
	noteDiv.style.position="relative";
	noteDiv.style.zIndex=-1;
	noteDiv.style.top="-910px"; //Set the values for Firefox
	noteDiv.style.left="434px";
	 if(document.addEventListener && window.opera){ // ifz, Opera
	   noteDiv.style.top="-870px";
	   noteDiv.style.left="404px"; //404
	 } //end ifz
	 else if(document.all){ //IE
	    noteDiv.style.top="-900px";
	    noteDiv.style.left="434px"; 
	 }//end else if
	 
	noteDiv.style.width=noteWidth;
	noteDiv.style.height="24px";
   parag.style.fontSize="14pt";
   parag.style.position="relative";
   parag.style.left=5 +"px";
   parag.style.top=-19 +"px"; 
   noteDiv.appendChild(parag);
} //eof bkNoteData
	
	
function findPosn(obj){
  var topCoor=leftCoor=0;
  while(obj!=null)
  {topCoor+=obj.offsetTop;
  leftCoor+=obj.offsetLeft;
  obj=obj.offsetParent;}
  return [leftCoor,topCoor] ; //return left and top co-ordinates in an array.
} //eof findPosn
  

function preloadImgs(index,maxIndex){
	i=index;
	/*An invisible test image is created and added to the document. It is then assigned the required src. Its height is checked. If it is satisfactory, the test image is removed from the document and the src assigned to imgBase[i], knowing that it has been successfully preloaded.*/

	var testImgElem=document.createElement("img");
	document.body.appendChild(testImgElem);
	testImgElem.style.visibility="hidden"; 
	
	 //Apply src of image to be downloaded.
  
   
   testImgElem.onload = function(){//enlargement has been loaded into cache

	//reset onload event to null
   this.onload=null;
   
	/*Check that height of image is satisfactory before proceeding. Image.onload is fired when the image finishes loading. Unfortunately IE browsers can sometimes stop downloading an image before it is completed. To check for this, the height of the image is measured. If it is below a set minimum (minImgHt) and remains unchanged for a further number of measurements, given by the value of 'equalHtsAllowed', then an error is signalled.
	*/
	lastHt=-1;
	htNow=0;
	noEqualHts=0
	equalHtsAllowed=4;
	minImgHt=3*pgImgHt/4;
	do{
	lastHt=htNow;
  	  htNow = testImgElem.offsetHeight;
     htNow = parseInt(htNow, 10); // base 10
     if(htNow==lastHt){
     noEqualHts++;
     }
	} //end do
   while((htNow<minImgHt)&&(noEqualHts<=equalHtsAllowed));
   if(noEqualHts<=equalHtsAllowed){ //if1
	
	/* At this point a test image has been downloaded and its height checked successfully. We can now proceed with removing the test image and putting its equivalent as an element in imgBase array. */
	loadingSideTracked=true;
   testImgElem.parentNode.removeChild(testImgElem);
   imgBase[i]=new Image();
   imgBase[i].src=imgSources[i];
	if(i<maxIndex-1){// if2. Preload next image 
	i++;
	preloadImgs(i,maxIndex);
	}else{  // elseto if2. All images are preloaded, so start flip.
	
	//Remove 'Getting more pictures' sign
	noteDiv.parentNode.removeChild(noteDiv); 
	parag.parentNode.removeChild(parag);
	noteNode.parentNode.removeChild(noteNode);
	startFlip();
	} //end else to if2
	} //end if1
	else{ //else to if1
	//Replace 'Getting more pictures' sign
	noteDiv.parentNode.removeChild(noteDiv); 
	parag.parentNode.removeChild(parag);
	noteNode.parentNode.removeChild(noteNode);
	bkNoteData("No more pictures, as an error occured.","332px");
	
	return false;  //Because of an error, the function startFlip is not called.
	} //end else to if1
	} //eof testImgelem.onload


	testImgElem.onerror=function(){// assign onerror event, which will occur if an image url is wrong or an image is missing.
	this.onload=null;
	htElem=0;  //This value is set to zero in case refence is made to it later. (It is only updated when testImgElem.onload is fired.)
	
	testImgElem.parentNode.removeChild(testImgElem); // remove temporary image
	
	//Replace 'Getting more pictures' sign
	noteDiv.parentNode.removeChild(noteDiv); 
	parag.parentNode.removeChild(parag);
	noteNode.parentNode.removeChild(noteNode);
	bkNoteData("No more pictures, as an error occured.","332px");
	
	return false;  //Because of an error, the function startFlip is not called.
	} // eof testImg.onerror
	
	 testImgElem.setAttribute("src",imgSources[i]); //assign image source. This is done after assigning the onload and on error event
	
} //eof preloadImgs



 
addLoadEvent(getFlipImgs);



