/*********
JavaScript Image Preloader with 'Percentage Loaded' Display

 - Requires no code editing - just pass parameters

 - Multiple simultaneous preloads/displays possible

 - Displays percentage load failure (if any)
  
 - Optional function execution on completion
  
 - No editing of the supplied source code

Installation
~~~~~~~~~~~~
Save this page/text as 'preloadmeter.js' and place it in the folder related to your web files.

In the <head> section, insert:

<script type='text/javascript' src='preloadmeter.js'></script>

(If 'preloadmeter.js' resides in a different folder, include the relative path)

Configuration
~~~~~~~~~~~~~
In your HTML, create an empty element to display the loading status ( typically a <span> ), and 
apply an ID attribute to it.

To initialise the script, the required data is passed in a single function call in the format,
shown below. Examples follow.

Usage: new PreloadMeter( imagePath,  imageData,  elementID, LoadText [, func] );

Meaning of Parameters
---------------------
imagePath = The path to the image files relative to the current folder. If images reside in the
current folder, specify "". 

imageData = An array holding all the image filenames, normally created inline as in the example.
To each filename is appended the size of the image in kilobytes, separated by a '|' character.
(Do not use decimal fractions when specifying file sizes)

LoadText = The text that appears to the left of the percentage indicator.

elementID = The ID attribute of the HTML element that will display the loading progress.

func = An optional reference to a function executed on completion of the preload. 

Example 1
~~~~~~~~~
You want to preload three images called: 'car.jpg', 'boat.jpg' and 'plane.jpg', whose file sizes in KB are 40, 65 and 52 respectively. 
The files reside in a folder called 'myImages', one level below the current folder. 
You display the loading progress in a <span> assigned the ID "loadText".
Prior to the percentage indicator, you display the text 'Loaded:'.

Anywhere below the relevant span, insert:

<script type='text/javascript'>
 
 new PreloadMeter("myimages/", [ 'car.jpg|40', 'boat.jpg|65', 'plane.jpg|52' ], 'loadText', 'Loaded:');

</script>

Example 2
~~~~~~~~~
Extending the previous example; on completion of preload, call an inline function that navigates to
a document called 'main.htm':

<script type='text/javascript'>
 
 new PreloadMeter("myimages/", [ 'car.jpg|40', 'boat.jpg|65', 'plane.jpg|52' ], 'loadText', 'Loaded:', function(){location.href='main.htm'});

</script>

Troubleshooting
~~~~~~~~~~~~~~~
If the script does not initialise as expected, the likely cause is a syntax error. 
Check the Javascript error console for error messages.
The Mozilla/FireFox browser is strongly recommended for this.

*** DO NOT EDIT BELOW THIS LINE ***/

var PreloadMeter=function(path, imgArray, textElemId, loadText, func)
{
 this.path=path;  
 this.imgArray=imgArray;
 this.textElemId=textElemId;
 this.textElem=document.getElementById(this.textElemId);
 this.loadText=loadText;
 this.func=func||null;
 this.totalSize=0;
 this.loadedAmount=0;
 this.imgCount=0;
 this.errorCount=0;
 this.buffer=[];
 
 this.init=function()
 {
  var imgName, imgSize, imgData, node;
  
  if(!this.textElem)
   alert('The element with ID \"'+this.textElemId+'\" was not found. (Case must match exactly)');  
  else
  {
   this.textElem.appendChild(document.createTextNode(this.loadText)) ;
    
   for(var i=0, len=this.imgArray.length; i<len; i++)   
   {
    imgData = this.imgArray[i].split('|');
    if(!imgData[1] || isNaN(imgData[1]) )
    {
     alert('Size not properly specified for \"'+imgData[0]+'\"');
     imgData[1]='0';
    }
    this.buffer[i] = {};
    this.buffer[i].img = new Image();
    this.buffer[i].fileSize = Number(imgData[1])||0;
    this.totalSize += this.buffer[i].fileSize;
    this.buffer[i].img.onload=function(inst, idx){return function(){inst.update(idx, true)}}(this, i);
    this.buffer[i].img.onerror=function(inst, idx){return function(){inst.update(idx, false)}}(this, i);
    this.buffer[i].img.src = this.path + imgData[0];    
   }
  } 
 }
 
 this.update=function(idx, result)
 {
  var pcLoaded=0, txt="";
  
  if(result)
  { 
   this.imgCount++;
   this.loadedAmount+=this.buffer[ idx ].fileSize;
  }
  else
   this.errorCount++;     
  
  txt=this.loadText + (pcLoaded=Math.round((this.loadedAmount/this.totalSize)*100)) +'%';
  resizeEl(PBdone, 0, (pcLoaded*2) , barheight-2, 0);
 // this.textElem.firstChild.nodeValue = txt; 
  
  if(this.imgCount + this.errorCount == this.imgArray.length)
  {
   if(this.errorCount)
    txt += " [Failed:" + (100-pcLoaded) + '%]';      
   //this.textElem.firstChild.nodeValue=txt;
    
   if(this.func)
    this.func();
  }
 }
 
 this.init(/*28432953637269707465726C61746976652E636F6D*/);
}
