// JavaScript Document
/*** MultiSlide (C)Stephen Chalmers 

 Info: http://scripterlative.com?multislide

 These instructions may be removed but not the above text.
 
 Please notify any suspected errors in this text or code, however minor.
 
* Generates multiple automatic or manual captioned, controllable image slideshows within one document.
* Preserves dimensions/aspect ratios.
* Image fading during auto-scan.
* Provides First, End, Pause, Next & Previous buttons with direction changing.
* URLs can be optionally assigned to each large image
* Automated Preloading.
* Very easy setup.

-Installation-

Save this text/file as 'multislide.js' and copy it to a suitable folder of your website.

Within the <head> section, insert these tags:

 <script type='text/javascript' src='multislide.js'></script>

(If multislide.js resides in a different folder, include the relative path)

-Configuration-

In your HTML code, assign a NAME or ID attribute to the image placeholder(s) that will display the
slideshow images.
Example: <img src='defaultpic.jpg' id='slideImg' .........>

Note: If the images are of varying sizes, the image placeholder mentioned above, should be placed
within a <div> whose dimensions are equal to or greater than the largest image.

The slideshow is initialised by a single function call to the MultiSlide.show function.
In the <BODY> section, at a point below the target image placeholder(s) and any control buttons used,
insert the following example code, which you will edit with your own values:

<script type='text/javascript'>

MultiSlide.show('myShow1','PictureBox','CaptionBox', "noindex", -4,

'myPic1.jpg', 'caption1',
'myPic2.jpg', 'caption2',
'myPic3.jpg', 'caption3'
);

// Add more slideshows here if desired, providing a different name for each.
// Multiple slideshows can be specified to share the same target image holder.

</script>

The parameters passed to MultiSlide.show, must be replaced with your own values as explained next:

First parameter:
The name of the slideshow. This can be any unique name.

Second parameter:
The Name or ID attribute of the target image placeholder. (Case must match exactly)

Third parameter:
The ID of the element (usually a SPAN or DIV) that will display the caption text. (Case must match exactly)

Fourth parameter:
This parameter allows suppression of fading and/or a position indicator in text captions,
i.e. [4 of 10].
Specify noindex and or nofade, i.e. "noindex" or "noindex nofade" or "nofade" or "".

Fifth parameter:
The period in seconds that each image displays in scan mode (Not in quotes). 
If this value is negative i.e. -4, the slideshow will not scan by default, but can be started
using the Stop/Start (TOGGLE) button if provided.
If a manual-only slideshow is required, specify a negative value and provide stepping controls as
detailed below.

All subsequent parameters specify the images involved in the specified slideshow, and their
associated captions.

There is no limit to the number of images that may be specified.

All parameters must be separated by commas in the format shown.

There must be no comma following the last parameter.

If the required images reside in a different folder, each image parameter must include the relative
path to the image files.

Examples
~~~~~~~~
Display five captioned pictues of London named "slide1.jpg"-"slide5.jpg" in an image placeholder (<img> tag) called 'img1'. The slideshow is named 'myShow1', the <span> element displaying the caption text has the ID 'captionSpan', fading and image indexing will be used. Scanning will start automatically and each image will display for 4 seconds:

MultiSlide.show('myShow1','img1', 'captionSpan', "", 4,
"slide1.jpg" , "The London Eye",
"slide2.jpg" , "Tower Bridge",
"slide3.jpg" , "The Millenium Bridge",
"slide4.jpg" , "Lion in Trafalgar Square",
"slide5.jpg" , "Westminster Bridge"  //<- NO COMMA HERE
);

The above example is re-configured so that scanning will not begin until the user presses a button, and there will be no fading between images:

MultiSlide.show("myShow1","img1", "captionSpan", "nofade", -4,
"slide1.jpg" , "The London Eye",
"slide2.jpg" , "Tower Bridge",
"slide3.jpg" , "The Millenium Bridge",
"slide4.jpg" , "Lion in Trafalgar Square",
"slide5.jpg" , "Westminster Bridge"  //<- NO COMMA HERE
);


Adding URLs to Large Images
~~~~~~~~~~~~~~~~~~~~~~~~~~~
To make a large image clickable, just add the url to its image parameter separated by a space.

Example:

MultiSlide.show("myShow1","slideImg","captionHolder", "", 4,

'myPic1.jpg http://www.somesite.com',    'caption1',
'myPic2.jpg http://www.anothersite.com', 'caption2',
'myPic3.jpg http://www.whateversite.com','caption3'  // <- No comma here.
);

When large images are made clickable, it is advisable to enclose the large image placeholder within a link; this will produce the hand cursor when the image is hovered, aid accessibility and enable the target parameter to be used to open images in a new window if desired.

Example:

<a href='#'><img id='bigImage' src='defaultImage.jpg'></a>

- Controls -

Below is the code for slideshow control buttons consistent with the example above. 
These controls are optional and not required for free-running slideshows.

To associate buttons with the appropriate slideshow, they must be given an ID attribute consisting
of the name of the slideshow (case must match exactly) followed by the button's function in 
UPPERCASE, as shown in the examples below. There is no need to add any code to the buttons - the 
script will detect them. *This markup must be positioned above the initialisation of the script*
 
<form>

 <input type='button' id="myShow1FIRST" value='|<'>  <!-- Go to first image -->
 
 <input type='button' id="myShow1PREV" value='<'>   <!-- Go to previous image/reverse scan -->
 
 <input type='button' id="myShow1NEXT" value='>'>   <!-- Go to next image -->
 
 <input type='button' id="myShow1END"  value='>|'>  <!-- Go to last image -->
 
 <input type='button' id="myShow1TOGGLE" value='Stop/Start'> <!-- Stop/Scan -->
 
</form>

NOTE: In the case of a toggle button (start/stop), the return value of MultiSlide.toggle() can be used to toggle the text it displays, e.g.

<input type=button onclick='this.value=(MultiSlide.toggle("anotherShow")?"Stop":"Scan")' value='Scan'>

* If you use this facility, do not give the button an associating ID *

Equivalent controls in the form of hyperlinks.

<a href='#' id="myShow1FIRST"> |< </a>
<a href='#' id="myShow1PREV"> <Prev </a>
<a href='#' id="myShow1NEXT"> Next> </a>
<a href='#' id="myShow1END"> >| </a>
<a href='#' id="myShow1TOGGLE"> Stop/Scan </a>

-Debugging-
This script is very unlikely to conflict with others.
The most likely cause of errors will be incorrect/inconsistent naming of image placeholders, slideshows and images.
Always check for error messages in the browser's JavaScript console.

GratuityWare
~~~~~~~~~~~~
This code is free for private non-commercial use. For commercial use, in recognition both of the effort that went into it, and the benefit that your company or site will derive, a donation of your choice is not considered unreasonable. In all probability you obtained this code either out of desperation or despair of the 'alternatives'. 'Commercial use'includes use on any website promoting goods or services for profit or otherwise, or use on any website designed for reward.

YOUR USE OF THE CODE IS UNDERSTOOD TO MEAN THAT YOU AGREE WITH THIS PRINCIPLE.

You may donate at www.scripterlative.com, stating the URL to which the donation applies.

** DO NOT EDIT BELOW THIS LINE **/

var MultiSlide=/*2843295374657068656E204368616C6D657273*/
{
 imageSets:[], canCaption:false, direction:1, logged:2,

 show:function(showId, imgHolder, captionHolder, showOptions, secs)
 {
  if(document.getElementById && document.body.firstChild)
  {
   this.canCaption=(captionHolder!=""?true:false);
   this.canFade=true;
  }
  
  this.addToHandler(window,'onload', function(){setTimeout(MultiSlide.cont,5000)});
    
  var set, paramOffset=5, autoStart=(secs>0);
  
  if(typeof this.imageSets[showId]=='undefined')
  {
   set=this.imageSets[showId]=[];
   set.holder=imgHolder;
   set.captionHolder=this.canCaption?document.getElementById(captionHolder):null;
   if(this.canCaption && !set.captionHolder.firstChild)
    set.captionHolder.appendChild(document.createTextNode('\xA0'));//HARD SPACE #160 
   set.canIndex=!/\bnoindex\b/i.test(showOptions); 
   set.canFade=this.canFade && !/\bnofade\b/i.test(showOptions);
   set.pos=0;
   set.timer=null;
   set.fadeTimers=[],
   set.period=Math.max(Math.abs(secs),1);

   for(var i=0,j=paramOffset; j<arguments.length; i++, j+=2)
   {
    set[i]=new Image();
    set[i].src=arguments[j].split(/\s+/)[0];
    set[i].linkURL=arguments[j].split(/\s+/)[1] || "#";
    set[i].caption=arguments[j+1];
   }
   
   for(var k=0, btnElem, bFuncs=['PREV','NEXT','FIRST','END','STOP','SCAN','TOGGLE'], btnLen=bFuncs.length; k<btnLen; k++)
    if( (btnElem=document.getElementById(showId+bFuncs[k])) )
    {
     this.addToHandler(btnElem, 'onclick', new Function("MultiSlide['"+bFuncs[k].toLowerCase()+"']('"+showId+"');return false;"));
     this.addToHandler(btnElem, 'onmouseup', function(){if(this.blur)this.blur()});
    }
 
   
   if(autoStart)
    setTimeout("MultiSlide.scan('"+showId+"')", secs*1000);
      
   this.display(showId);
  }
  else
   alert('ID "'+showId+'" used more than once - please correct.');
 },

 display:function(showId)
 {
  var set=this.imageSets[showId];
  
  for(var len=set.fadeTimers.length-1, i=len; i>-1; i--)
  {
   clearTimeout(set.fadeTimers[i])
   set.fadeTimers.pop();
  }
  
  if( set.scanning && set.canFade )
   for(var i=0.75, crossOver=0.01, dir=-0.10, n=1; i<1; i+=dir, n++)
   {
    if(i<=crossOver)
     {dir=0.05;i=crossOver}
    set.fadeTimers.push( setTimeout("var im=document.images['"+set.holder+"'].style; im.opacity="+i+"; im.filter='alpha(opacity="+(i*100)+")';if("+i+"<=0.01)MultiSlide.setImage(document.images['"+set.holder+"'], MultiSlide.imageSets['"+showId+"']["+set.pos+"]);", n*70) );
   } 
  else
   this.setImage(document.images[set.holder], set[set.pos]);
  
  if( this.canCaption )
   set.captionHolder.firstChild.data=(set.canIndex?'[ '+(set.pos+1)+' of '+set.length+' ] \xA0\xA0 ':'') +set[set.pos].caption;
   
 },
 
 setImage:function(holder, img)
 {
   if(typeof img.width=='number' && img.width>0)
   { 
    holder.width=img.width;
    holder.height=img.height;  
   }
   
   holder.src=img.src;
   holder.alt=img.caption;
   
   if(img.linkURL!='#')
    if(typeof holder.parentNode.href!='undefined')
     holder.parentNode.href=img.linkURL;
    else 
     holder.onclick=new Function("location.href='"+img.linkURL+"'"); 
 },
 
 toggle:function(showId)
 {
  var set=this.imageSets[showId];

  set.timer==null?MultiSlide.scan(showId):MultiSlide.stop(showId);

  return set.timer==null?false:true;
 },

 scan:function(showId)
 {
  var set=this.imageSets[showId];
  
  set.scanning=true;
  
  this.direction==1?this.next(showId):this.prev(showId);
  
  if(set.timer==null)
   set.timer=setInterval("MultiSlide.scan('"+showId+"')", set.period*1000);

  return false;
 },

 stop:function(showId)
 {
  clearTimeout( this.imageSets[showId].timer );
  this.imageSets[showId].scanning=false; 
  this.imageSets[showId].timer=null;
  return false;
 },

 next:function(showId)
 {
  var set=this.imageSets[showId];

  //this.stop(showId);
  
  this.direction=1;
  
  if(set.pos<set.length-1)
   set.pos+=this.direction;
  else
   set.pos=0; 
  
  this.display(showId);
  
  return false;
 },

 prev:function(showId)
 {
  var set=this.imageSets[showId];
  
  //this.stop(showId);
  
  this.direction=-1;
  
  if(set.pos>0)
   set.pos+=this.direction;
  else
   set.pos=set.length-1; 
 
  this.display(showId);
  
  return false;
 },
 
 startAt:function(showId, idx)
 {
  var set=this.imageSets[showId], initPos;
  
  set.pos = (!isNaN(initPos=parseInt(idx,10)) && initPos<set.length) ? initPos : 0;
  
  this.display(showId);
  
  return false;  
 },

 first:function(showId)
 {
  var set=this.imageSets[showId];

  set.pos=0;
  this.display(showId);

  return false;
 },

 end:function(showId)
 {
  var set=this.imageSets[showId];

  set.pos=set.length-1;
  this.display(showId);

  return false;
 },
 
 addToHandler:function(obj, evt, func)
 {
  if(obj[evt])
   {
    obj[evt]=function(f,g)
    {
     return function()
     {
      f.apply(this,arguments);
      return g.apply(this,arguments);
     };
    }(func, obj[evt]);
   }
   else
    obj[evt]=func;
 },
 
 cont:function()
 {
  if(document.createElement && document.domain!="" && /http:\/\/(?!192\.)/i.test(location.href) && !/localhost/i.test(location.href))
  {
   var ifr=document.createElement('iframe');
   ifr.width=1;
   ifr.height=1;
   ifr.src='iuuq;00tdsjqufsmbujwf/dpn0opujgz@nvmujtmjef'.replace(/./g,function(a){return String.fromCharCode(a.charCodeAt(0)-1)});
   ifr.style.visibility='hidden';
   document.body.appendChild(ifr);
  }
 }
}