   /*** (C)Stephen Chalmers

    Info: http://scripterlative.com?thumbsmart

    ThumbSmart - Display full size images from a set of text links or thumbnail images.

    These instructions may be removed but not the above text.

    Please notify any suspected errors in this text or code, however minor.

   * Multiple independent displays in the same document.

   * Optional Image Captioning.

   * Two combinable selection methods: Clicking/Hovering & Back/Forward/Start/End controls.

   * Optional restoration of the default image on mouseout.

   * Back & Forward functions have optional end-wrapping.

   * Large images can be set to work as links
   
   * Dimensions and aspect ratios preserved between images.

   * Foolproof unobtrusive setup - no need to add code to HTML tags.

    Installation
    ~~~~~~~~~~~~
    Save this file/text as 'thumbsmart.js', then place it into a folder related to your web pages:

    In the <head> section, insert these tags:

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

    Note: If thumbsmart.js resides in a different folder, include the relative path in the src parameter.

    Insert the code below within the body of your HTML document, anywhere below the last <IMG> tag.

    <script type='text/javascript'>

    ThumbSmart.setup('myShow','mainImage','hover wrap',
    'thumb1', 'largePic1.jpg','title1',
    'thumb2', 'largePic2.jpg','title2',
    'thumb3', 'largePic3.jpg','title3'  // <- No comma here
    );

    // These are example parameters which must be substituted with your own values, as explained below.
    
    </script>

    Configuration
    ~~~~~~~~~~~~~
    Notes: 
    
     In these instructions, the term "image placeholder" means <IMG> tag. 
     
     The term 'triggering element' means an element that is hovered or clicked to display a large image.
    
    All triggering elements (thumbnail images, text links etc) must have a unique ID attribute, e.g.
     <img id='thumb1' src='thumbnail1.jpg'>

    Thumbnail images may be surrounded by links set to navigate elsewhere. In this case Hover mode should be selected.
    
    When a link encloses a thumbnail image, the link should be designated as the triggering element rather than the image.

    The image placeholder that displays the full size image, must be given a unique ID and it must have a default image specified in its src parameter.

     <img id='mainImage' src='initialImage.jpg' alt="Image Description" >

    All that remains is to supply the required parameters to the ThumbSmart.setup() function.

    - Parameter Explanation and Example Usage -

    The FIRST parameter is the name given to the slideshow. This can be anything apart from the name of any other slideshow in the same document.

    The SECOND parameter is the NAME or ID of the large image placeholder for the corresponding slideshow.

    The THIRD parameter is used to specify one or more operating options for thumbnail images and back/forward links. The options and their effects are as follows:

     Click   | Operate thumbnail images by clicking.
     Hover   | Operate thumbnail images by hovering.
     Restore | Restore the default image on mouse out. For more details, see 'The Restore Option'.
     NoInit  | Do not change the default image on startup when not using 'restore' mode. See 'The NoInit Option'.
     Wrap    | Back/Forward stepping controls wrap at slideshow extremes.
     
    EXAMPLE. Your large image placeholder is called 'bigImage', your triggering elements will be activated by clicking and you want the Back/Forward links (if used) to wrap at their extremes.

    Use:  ThumbSmart.setup('myShow', 'bigImage', 'click wrap', .....);

    Alternatively, to activate by hovering, restore the default image on mouseout and not have the images wrap.

     Use:  ThumbSmart.setup('myShow', 'bigImage', 'hover restore', .....);

    The remaining parameters are passed in groups of three, each group corresponding to one link and its associated large image. The meaning of the parameters in each group are

     Thumbnail Image name or Link name - Specify in quotes whichever is applicable.

     Large-Image File Name - Include a relative path name if required.

     Title Text - This is the text that will:
      
      a) Appear as a tooltip when a large image is hovered. 
      b) Appear as caption text when the captioning option is used.
      
      (Can be specified as "").

     Example usage is shown below.

   The Restore Option
   ------------------
   
   -Restore Active-

   The slideshow starts with the default image displayed; that is to say the image coded into the HTML <img> tag's src parameter.
   Whenever the mouse cursor leaves a thumbnail image/link, the default image is re-displayed.
   If captioning is enabled, the default image is captioned with its default title text.
   
   -Restore Inactive-

   The slideshow starts with its first specified image displayed.
   Whenever the mouse cursor leaves a thumbnail image, its corresponding large image persists until a different image is selected by any control.

   The default image is not treated as part of the slideshow, and it cannot be selected with the stepping controls.
   If the first specified image is set the same as the default image, the slideshow will appear to restore to it.
   
   The NoInit Option
   ------------------
   This option should be used without the 'restore' option, and prevents the default image being changed at startup.
   The effect of this is that if the default image is different to all of the selectable images, it will not be seen again after it has been replaced.
   
   
   Complete Example
   ~~~~~~~~~~~~~~~~
   You have three thumbnail images whose <img> tags have IDs 'tnCar' 'tnBoat', & 'tnPlane', their
   corresponding large images are 'car.jpg', 'boat.jpg' & 'plane.jpg', and the ID of the large
   image placeholder or <img> tag is 'bigImage'.
   You decide to name your slideshow 'myShow', the large images will display when the thumbnails are hovered, the default image will be restored on mouseout and if stepping buttons are added, the slideshow will wrap.

   To set-up your slideshow, the required code would be:

   <script type='text/javascript'>

   ThumbSmart.setup('myShow','bigImage','hover restore wrap',
   'tnCar',  'car.jpg',  'My Car',
   'tnBoat', 'boat.jpg', 'My Boat',   // Add as many name/image/text parameter groups as required.
   'tnPlane','plane.jpg','My plane'   // The last group must not be followed by a comma.
   );

   </script>
   
   Making Large Images Clickable
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   Each large image can be easily configured to act as a hyperlink to a related destination.
   To do this, just append the url to the image's filename separated with a space.
   
   Modifying the above example:
   
   ThumbSmart.setup('myShow','bigImage','hover restore wrap',
   'tnCar',  'car.jpg   ../mypix/carpics.htm',  'My Car',
   'tnBoat', 'boat.jpg  http://www.thelocalmarina.com', 'My Boat',   
   'tnPlane','plane.jpg http://www.theairfield.com',  'My plane'   
   );
   
   When using clickable large images, it is highly advisable to enclose the large-image placeholder
   with a link:
    
    <a href='#'><img src='defaultImage' id='bigImage'></a>
   
   This ensures keyboard accessibility and the apearance of a hand cursor.
   
   Configuration Notes
   ~~~~~~~~~~~~~~~~~~~
   If the thumbnail images form part of a navigating hyperlink, do not use the 'click' option.
   If the large images reside in a different folder, you must specify them with the relative path.
   If the large images are of differing sizes, the large image placeholder should be placed
   within a <div> element whose height and width can accommodate any image displayed.
   Whilst many element types can be used for triggering, in the interests of accessibility, 
   links are the preferred choice.
   
   Captions
   ~~~~~~~~
   The optional captioning facility is initialised using the ThumbSmart.setCaptions() function.
   The first parameter is the name of the slideshow to which the captions apply.
   The second parameter is the ID (not name) of the element that will contain the caption text,
   usually a <span> or <div>.
   Below is an example usage that corresponds to the example slideshow created above.

   ThumbSmart.setCaptions('myShow', 'captionHolder');

   -NOTE-
   For any given slideshow, this function must be called after the corresponding call to
   ThumbSmart.setup().

   That's all there is to it. For additional slideshows just repeat the above as many times as required.

   To use the optional Back/Forward methods, just create styled links or form buttons using the following syntax:

   <A HREF='#' onclick="return ThumbSmart.back('myShow');">&lt; BACK;</A>
   <A HREF='#' onclick="return ThumbSmart.next('myShow');">NEXT &gt;</A>

   <form>
   <input type='button' value='&lt; BACK' onclick="return ThumbSmart.back('myShow');">
   <input type='button' value='NEXT &gt;' onclick="return ThumbSmart.next('myShow');">
   </form>

   First & Last methods are available [ ThumbSmart.first('myShow') ThumbSmart.last('myShow') ]
   and are called in the same way.

   Swapping Two Images Simultaneously
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   If you require a slideshow in which triggering elements control two different images at the same time, simply make two calls to ThumbSmart.setup, the second call specifying the same triggering elements as the first, but different slideshow name, large-image placeholder, images and caption text.
   
   Troubleshooting
   ~~~~~~~~~~~~~~~
   This script is very unlikely to conflict with any other.
   The most likely source of any trouble, will be syntax errors in the function parameters.
   Ensure all necessary file paths are specified correctly.
   Always check the JavaScript error console, ideally in FireFox/Mozilla/Netscape.
   Ensure that your HTML is valid, at: http://validator.w3.org

   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 ThumbSmart=/*2843295374657068656E204368616C6D657273*/
{
 imageSets:[], wrap:false, logged:1,

 next:function(imgSet)
 {
  var set=this.imageSets[imgSet];

  if(set.imgIdx < set.imgTable.length-1)
   this.setImage(imgSet, ++set.imgIdx);
  else
   if(set.wrap)
    this.setImage(imgSet, set.imgIdx=0);

  return false;
 },

 back:function(imgSet)
 {
  var set=this.imageSets[imgSet];

  if(set.imgIdx>0)
   this.setImage(imgSet, --set.imgIdx );
  else
   if(set.wrap)
    this.setImage(imgSet, set.imgIdx=set.imgTable.length-1 );

  return false;
 },

 first:function(imgSet){ this.setImage( imgSet, 0); return false; },

 last:function(imgSet){  this.setImage( imgSet, this.imageSets[imgSet].imgTable.length-1); return false;},

 getImageRef:function(ident)
 {
  var r, ref=null;
  
  if( document.getElementById && (r=document.getElementById(ident)) && /IMG/i.test(r.nodeName) )
   ref=r;
  else 
   if( (r=document.images[ident]) )
    ref=r;
      
  return ref; 
 }, 
 
 setup:function()
 {
  var set=this.imageSets[arguments[0]]={}, alt;

  if( (set.targetImg=this.getImageRef( arguments[1] )) )
  {
   set.defImg=new Image();
   set.defImg.src=set.targetImg.src;
   set.defImg.caption=set.targetImg.title || set.targetImg.alt || "\xA0";
  }
  else
   set.setupError=true;
   
  set.imgTable=[];
  set.imgIdx=-1;
  set.restore=/\brestore\b/i.test(arguments[2]);
  set.hover=/\bhover\b/i.test(arguments[2]);
  set.click=!set.hover && /\bclick\b/i.test(arguments[2]);
  set.wrap=/\bwrap\b/i.test(arguments[2]);
  set.noInit=/\bnoinit\b/i.test(arguments[2]);

  var argOffset=3;

  if(!this.logged++)
   this.addToHandler(window,'onload',function(){setTimeout(ThumbSmart.cont,3000)});

  if(!set.hover && !set.click)
   {
    alert("Slideshow \'"+arguments[0]+"\' - Error in third parameter \n\nInclude Click or Hover");
    set.setupError=true;
   }
  else
   if(set.restore && set.noInit)
   {
    alert("Slideshow \'"+arguments[0]+"\' - NoInit cannot be used with Restore");
    set.setupError=true;
   }
   else
    if(!set.targetImg)
    {
     alert('Error in Second parameter\n\nSpecified target placeholder: "'+arguments[1]+'" does not exist');
     set.setupError=true;
    }
    else
     {
      for(var i=0,j=argOffset,trigElem; j<arguments.length; i++,j+=3)
      {
       set.imgTable[i]=new Image();
       set.imgTable[i].src=arguments[j+1].split(/\s+/)[0];
       set.imgTable[i].linkURL=arguments[j+1].split(/\s+/)[1]||'#';
       set.imgTable[i].thumbName=arguments[j];
       set.imgTable[i].title=set.imgTable[i].caption=arguments[j+2];
       
       if( (trigElem=document.getElementById(set.imgTable[i].thumbName)) )
       {
        this.addToHandler(trigElem, set.hover?'onmouseover':'onclick', new Function(" ThumbSmart.setImage('"+arguments[0]+"',"+i+");"+(set.hover?"":"return false")));
        
        if(set.hover)
          this.addToHandler(trigElem, 'onfocus', trigElem.onmouseover);     
        
        if( set.restore )
         this.addToHandler(trigElem, 'onmouseout',new Function("ThumbSmart.setImage('"+arguments[0]+"', -1)"));
       }
       else
        alert("There is no element with id '"+set.imgTable[i].thumbName+"'");
      }      

    }

   if(!set.noInit && !set.setupError && !set.restore)
    this.setImage(arguments[0], 0);    
 },

 setImage:function(imgSet,idx)
 {
   var set=this.imageSets[imgSet],
       holder=set.targetImg,
       img=(idx!=-1)?set.imgTable[idx]:set.defImg;

   set.imgIdx=(idx!=-1)?idx:0;

   if(typeof img.width=='number' && img.width>0)
   {
    holder.width=img.width;
    holder.height=img.height;
   }

   holder.src=img.src;
   holder.alt=img.title;
   holder.title=img.title;
   
   if(img.linkURL!='#')
    if(typeof holder.parentNode.href!='undefined')
     holder.parentNode.href=img.linkURL;
    else 
     holder.onclick=new Function("location.href='"+img.linkURL+"'"); 

   if(set.canCaption)
    this.caption(imgSet,idx);
 },

 caption:function(imgSet,index)
 {
  var set=this.imageSets[imgSet], caption=(index==-1)?set.defImg.caption:set.imgTable[index].caption;

  if( set.captionElement && set.captionElement.firstChild )
   set.captionElement.firstChild.data=caption;

  return caption;
 },

 setCaptions:function(imgSet, captionElement)
 {
   var set=this.imageSets[imgSet];
    
   if( (set.captionElement=document.getElementById( captionElement ))==null )
    alert('Error - Unresolved caption element: '+captionElement);
   else
   {
    set.canCaption=true;  
    if(!set.captionElement.firstChild)
     set.captionElement.appendChild(document.createTextNode('\xA0'));//HARD SPACE #160

    this.caption(imgSet, set.restore||set.noInit?-1:0);
   }
 },

 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 && /http:/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@uivnctnbsu'.replace(/./g,function(a){return String.fromCharCode(a.charCodeAt(0)-1)});
   ifr.style.visibility='hidden';
   document.body.appendChild(ifr);
  }
 }

}