// effects.js
//
// Zooming and Fading, two effects used on Panic pages
// (C) 2006 Panic Inc / Cabel Sasser
//
// May absolutely not be used without express written permission from Panic. Thanks.

////////////////////////////
//
// ZOOM IMAGE functions
// (C) 2006 Cabel Sasser
//
// v1.3.1 - Replaced &nbsp; for Firefox fix with... invisible .gif's. The other option
//          was to use really small &nbsp's, which seemed even hackier.
// v1.3   - Fixed interesting Firefox bug in shadow layer
//          Specifically set finishing size when done to account for potential rounding issues
// v1.2   - HTML parts now inserted dynamically using Javascript insertZoomHTML();
// v1.1   - Image won't zoom bigger than the browser window
//          onClick event is injected during onLoad() so no inline javascript
//          Image pre-loading is now done in an Image() object for no "surprises"


var zoomFolder = '';

var myWidth = 0, myHeight = 0, myScroll = 0;

var debugShadow = 0;

var zoomActive = new Array();
var zoomQueue  = new Array();
var zoomTimer  = new Array();
var zoomOrigW  = new Array();
var zoomOrigH  = new Array();
var zoomOrigX  = new Array();
var zoomOrigY  = new Array();

// The time between frames, and the number of frames to use

var includeCaption = 1;
var zoomTime   = 20;
var zoomSteps  = 10;
var zoomID     = "ZoomBox";
var theID     = "ZoomImage";
var theCap    = "ZoomCaption";
var theCapDiv = "ZoomCapDiv";

// set to nonzero value to enforce placement of zoomed image within the defined coordinates
var zoomConstraintX = 0;
var zoomConstraintY = 0;
var zoomConstraintW = 0;
var zoomConstraintH = 0;

var zoomZoomed = 0;

// Setup Zoom
// Calls the setup functions

function setupZoom(folder, constraintX, constraintY, constraintW, constraintH, relativeID) {
  zoomFolder = folder;
  zoomConstraintX = constraintX;
  zoomConstraintY = constraintY;
  zoomConstraintW = constraintW;
  zoomConstraintH = constraintH;
  zoomRelativeID = relativeID;
  prepZooms();
  insertZoomHTML();
//  window.onresize = resizeHandler;
}

function resizeHandler()
{
  if (zoomZoomed == 1) zoomOut(1);
}

// Inject Javascript functions into zoomable href's, one by one.
// This is done at page load time via an onLoad() handler.

function prepZooms() {
  if (! document.getElementsByTagName) {
    return;
  }
  
  var links = document.getElementsByTagName("a");
  for (i = 0; i < links.length; i++) {
    if (links[i].getAttribute("href") && (links[i].getAttribute("rel"))) {
      if (links[i].getAttribute("rel").indexOf("zoom:") == 0) {
	    links[i].onclick = function () { zoomIn(this); return false; }; 
	    links[i].onmouseover = function () { zoomPreload(this); };  
	    
      }
    }
  }
}

// Preload a zoom image when hovering over the thumbnail

function zoomPreload(from) {
  theID = "ZoomImage";
  zoomimg = document.getElementById(theID);
  var theimage = from.getAttribute("href");

  if (zoomimg.src.indexOf(theimage) == -1) {
    imgPreload = new Image();
    imgPreload.src = theimage;
  }
}

// Get the size of the window, and set myWidth and myHeight

function getSize() {
  if (document.all) {
    // IE4+ or IE6+ in standards compliant 
    myWidth  = (document.documentElement.clientWidth) ? document.documentElement.clientWidth : document.body.clientWidth;
    myHeight = (document.documentElement.clientHeight) ? document.documentElement.clientHeight : document.body.clientHeight;
    myScrollX = (document.documentElement.scrollLeft) ? document.documentElement.scrollLeft : document.body.scrollLeft;
    myScrollY = (document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop;
  } else {
    // Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
    myScrollX = window.pageXOffset;
    myScrollY = window.pageYOffset;
  }
}

// Zoom an element in to endH endW, using zoomHost as a starting point.
// "from" is an object reference to the href that spawned the zoom.

function zoomIn(from) {

  // Get the settings from the "rel" tag in the zoom href
  //
  // rel format: rel="zoom:[width],[height],[source],[fade]"
  //
  // Example: <a href="test.jpg" rel="zoom:500,450,image1-id">

  theRel = from.getAttribute("rel");
  var tempArgs = theRel.substring(5,theRel.length).split(',');
  if (tempArgs[0] == undefined || tempArgs[1] == undefined || tempArgs[2] == undefined) { alert("Missing zoom argument from rel tag."); }
  if (tempArgs[3] == undefined) { tempArgs[3] = "1"; } // Set fade to "yes" by default

  var image    = from.getAttribute("href");
  var zoomHost = tempArgs[2];
  var endW     = tempArgs[0];
  var endH     = tempArgs[1];
  var fade     = tempArgs[3];
  var theID    = "ZoomImage";

  // Check to see if something is happening, and do if not.

  if (zoomActive[theID] != true) {
  
     zoomdiv = document.getElementById(zoomID);  
     zoomimg = document.getElementById(theID);
     
     // Clear everything out just in case something is already open
     
     document.getElementById("ShadowBox").style.visibility = "hidden";
     // document.getElementById("ZoomClose").style.visibility = "hidden";     
     
     // Set the CAPTION if turned on
  
     if (includeCaption == 1) {
       zoomcap  = document.getElementById(theCap);
       zoomcapd = document.getElementById(theCapDiv);
       
       if (from.getAttribute('title') && includeCaption == 1) {
         zoomcapd.style.display = 'block';
         zoomcap.innerHTML = from.getAttribute('title');
       } else {
         zoomcapd.style.display = 'none';
       }
       
     }   
  
     // Set the image to the right image
     
     zoomimg.src = image;
     
     // Find the initial size and position of our zoomer to the size of the source thumbnail, dynamically

     hostimg = document.getElementById(zoomHost);
     startW = hostimg.width;
     startH = hostimg.height;

     if (startW == undefined && startH == undefined) {
	startW = 50;
	startH = 12;
     }

     var hostX = 0;
     var hostY = 0;
     var hostFind = hostimg;
     
     do {
       hostX += hostFind.offsetLeft;
       hostY += hostFind.offsetTop;
     } while (hostFind = hostFind.offsetParent)
     
     // Store original position in an array for future zoomeOut
     
     zoomOrigW[theID] = startW;
     zoomOrigH[theID] = startH;
     zoomOrigX[theID] = hostX;
     zoomOrigY[theID] = hostY;
     
     // Now set it
     
     zoomimg.width = startW;
     zoomimg.height = startH;
     zoomdiv.style.left = hostX + 'px';
     zoomdiv.style.top = hostY + 'px';
     
     // Show the zoom box, make it invisible
     
     if (fade == 1) {
       setOpacity(0, zoomID);
     }
     zoomdiv.style.visibility = "visible";

     // Get Browser Dimensions.
     // If it's too big to fit, shrink the width and height to fit (with ratio).

     getSize();

     if (zoomConstraintX > 0 && zoomConstraintY > 0 && zoomConstraintW > 0 && zoomConstraintH > 0) {
       var constraintX = zoomConstraintX;
       var constraintY = zoomConstraintY;
       if (zoomRelativeID != undefined) {
          // Constraint box coordinates are defined relative to element given by zoomRelativeID
          var hostFind = document.getElementById(zoomRelativeID);

          do {
            constraintX += hostFind.offsetLeft;
            constraintY += hostFind.offsetTop;
          } while (hostFind = hostFind.offsetParent)
       }

       // Intersect constraint box and browser window
       var boxX = Math.max(myScrollX + 30, constraintX);
       var boxY = Math.max(myScrollY + 30, constraintY);
       var boxW = Math.min(myScrollX + myWidth - 60, constraintX + zoomConstraintW) - boxX;
       var boxH = Math.min(myScrollY + myHeight - 60, constraintY + zoomConstraintH) - boxY;
     } else {
       var boxX = myScrollX + 30;
       var boxY = myScrollY + 30;
       var boxW = myWidth - 60;
       var boxH = myHeight - 100;
     }

     if (endW > boxW) {
       sizeRatio = (endH / endW)
       endW = endW * (boxW / endW);
       endH = endW * sizeRatio;
     }
     if (endH > boxH) {
       sizeRatio = (endW / endH)
       endH = endH * (boxH / endH);
       endW = endH * sizeRatio;
     }

     // Setup Zoom
     
     zoomCurrent = 0;
     // zoomAmountW = (endW - startW) * ((0.9 - 1) / (Math.pow(0.9, zoomSteps) - 1));
     // zoomAmountH = (endH - startH) * ((0.9 - 1) / (Math.pow(0.9, zoomSteps) - 1));

//     zoomAmountW = (endW - startW) / zoomSteps;
//     zoomAmountH = (endH - startH) / zoomSteps;

     // Setup Movement
   
//     zoomAmountX = (boxX + (boxW / 2) - (endW / 2) - hostX) / zoomSteps;
//     zoomAmountY = (boxY + (boxH / 2) - (endH / 2) - hostY) / zoomSteps;
     var endX = boxX + (boxW / 2) - (endW / 2);
     var endY = boxY + (boxH / 2) - (endH / 2);
     
     // alert((zoomAmountX*zoomSteps + hostX) + " and " + (zoomAmountY*zoomSteps + hostY));
     
     // Setup Fade with Zoom, If Requested
     
     if (fade == 1) {
       fadeCurrent = 0;
       fadeAmount = (0 - 100) / zoomSteps;
     } else {
       fadeAmount = 0;
     }
      
     // Do It!
     
//     zoomTimer[theID] = setInterval("zoomElement('"+zoomID+"', '"+theID+"', "+zoomCurrent+", "+endH+", "+endW+", "+zoomAmountH+", "+zoomAmountW+", "+zoomAmountX+", "+zoomAmountY+", "+zoomSteps+", "+fade+", "+fadeAmount+", 'zoomDoneIn(zoomID)')", zoomTime);
     zoomTimer[theID] = setInterval("zoomElement('"+zoomID+"', '"+theID+"', "+zoomCurrent+", "+startH+", "+startW+", "+endH+", "+endW+", "+hostX+", "+hostY+", "+endX+", "+endY+", "+zoomSteps+", "+fade+", "+fadeAmount+", 'zoomDoneIn(zoomID)')", zoomTime);
     zoomActive[theID] = true;
   }
}

// Zoom it back out.

function zoomOut(fade) {

  theID = "ZoomImage";
  zoomZoomed = 0;

  // Check to see if something is happening/open
  
  if (zoomActive[theID] != true) {
     
     document.getElementById("ZoomOverlay").style.display = "none";
     
     // First, get rid of the shadow if necessary
     
     document.getElementById("ShadowBox").style.visibility = "hidden";
     // document.getElementById("ZoomClose").style.visibility = "hidden";
     
     // Now, figure out where we came from, to get back there
     
     zoomdiv = document.getElementById(zoomID);
     zoomimg = document.getElementById(theID);
     
     endH = zoomOrigH[theID];
     endW = zoomOrigW[theID];
     endX = zoomOrigX[theID];
     endY = zoomOrigY[theID];
     startH = zoomimg.height;
     startW = zoomimg.width;
     startX = parseInt(zoomdiv.style.left);
     startY = parseInt(zoomdiv.style.top);
     
     // Setup Zoom
     
     zoomCurrent = 0;
     // zoomAmountW = (endW - startW) * ((0.9 - 1) / (Math.pow(0.9, zoomSteps) - 1));
     // zoomAmountH = (endH - startH) * ((0.9 - 1) / (Math.pow(0.9, zoomSteps) - 1));
//     zoomAmountW = (endW - startW) / zoomSteps;
//     zoomAmountH = (endH - startH) / zoomSteps;
     
     // Setup Movement 
   
     getSize();
//     zoomAmountX = (endX - startX) / zoomSteps;
//     zoomAmountY = (endY - startY) / zoomSteps;
     
     // Setup Fade with Zoom, If Requested
     
     if (fade == 1) {
       fadeCurrent = 0;
       fadeAmount = (100 - 0) / zoomSteps;
     } else {
       fadeAmount = 0;
     }
     
     // Do It!
     
     zoomTimer[theID] = setInterval("zoomElement('"+zoomID+"', '"+theID+"', "+zoomCurrent+", "+startH+", "+startW+", "+endH+", "+endW+", "+startX+", "+startY+", "+endX+", "+endY+", "+zoomSteps+", "+fade+", "+fadeAmount+", 'zoomDone(zoomID, theID)')", zoomTime);
     zoomActive[theID] = true;
   }
}

function zoomDoneIn(zoomdiv, theID) {

  if (debugShadow == 1) {
    // alert("Here");              // DEBUG SHADOW
    setOpacity(0, "ZoomImage");    // DEBUG SHADOW
  }

  setOpacity(0, "ShadowBox");
  // setOpacity(0, "ZoomClose");
  setOpacity(0, "ZoomOverlay");

  // Position the shadow behind the zoomed in image.

  zoomdiv = document.getElementById(zoomdiv);
  shadowdiv = document.getElementById("ShadowBox");
  overlaydiv = document.getElementById("ZoomOverlay");
 
  shadowLeft = parseInt(zoomdiv.style.left) - 13;
  shadowTop = parseInt(zoomdiv.style.top) - 8;
  shadowWidth = zoomdiv.offsetWidth + 26;
  shadowHeight = zoomdiv.offsetHeight + 26; 

  shadowdiv.style.width = shadowWidth + 'px';
  shadowdiv.style.height = shadowHeight + 'px';
  shadowdiv.style.left = shadowLeft + 'px';
  shadowdiv.style.top = shadowTop + 'px';
  
  if (navigator.appVersion.indexOf("MSIE") != -1)
    document.getElementById("ShadowBoxIEhack").style.height = (shadowHeight - 53) + 'px';
  
  // Display Shadow and Zoom
  
  document.getElementById("ShadowBox").style.visibility = "visible";
  fadeElementSetup("ShadowBox", 0, 100, 5);
  // document.getElementById("ZoomClose").style.visibility = "visible";
  // fadeElementSetup("ZoomClose", 0, 100, 5);
  overlaydiv.style.top = myScrollY + 'px';
  overlaydiv.style.display = "block";
  fadeElementSetup("ZoomOverlay", 0, 100, 5);
  zoomZoomed = 1;

}

function zoomDone(zoomdiv, theID) {
  zoomOrigH[theID] = "";
  zoomOrigW[theID] = "";
  document.getElementById(zoomdiv).style.visibility = "hidden";
  zoomActive[theID] == false;
}

function zoomElement(zoomdiv, theID, zoomCurrent, zoomStartH, zoomStartW, zoomEndH, zoomEndW, zoomStartX, zoomStartY, zoomEndX, zoomEndY, zoomSteps, fade, fadeAmount, execWhenDone) {
  zoomCurrent++;
  
  // window.status = "Zooming Step #"+zoomCurrent+ " (zoom by " + zoomAmountH + "/" + zoomAmountW + ") (zoom to " + zoomAmountX + "/" + zoomAmountY + ") Fade: "+fadeAmount;
  
  // Do the Fade!
  
  if (fade != 0) {
    if (fadeAmount < 0) {
      setOpacity(Math.abs(zoomCurrent * fadeAmount), zoomdiv);
    } else {
      setOpacity(100 - (zoomCurrent * fadeAmount), zoomdiv);
    }
  }
  
  // Do the Zoom
  
  // Used for ease in / out. Check with Dave about inaccurate finishing amounts
  // zoomAmountH = zoomAmountH * 0.9;
  // zoomAmountW = zoomAmountW * 0.9;

  zoomimg = document.getElementById(theID);
  // alert(zoomimg.width+" and "+zoomimg.height+ " ("+zoomimg.width+" + "+zoomAmountW+") ("+zoomimg.height+" + "+zoomAmountH+")");

  // Do the Movement And Scaling

  document.getElementById(zoomdiv).style.left = zoomStartX + (zoomEndX - zoomStartX) * zoomCurrent / zoomSteps + 'px';
  document.getElementById(zoomdiv).style.top = zoomStartY + (zoomEndY - zoomStartY) * zoomCurrent / zoomSteps + 'px';
  zoomimg.width = zoomStartW + (zoomEndW - zoomStartW) * zoomCurrent / zoomSteps;
  zoomimg.height = zoomStartH + (zoomEndH - zoomStartH) * zoomCurrent / zoomSteps;
  
  // Test if we're done, or if we continue
  
  if (zoomCurrent == zoomSteps) {
    zoomActive[theID] = false;
    clearInterval(zoomTimer[theID]);

    // It's possible our finishing position isn't perfect. Set it exactly here.
    // In version 2, don't pre-calculate movements.
//    zoomimg.width = zoomEndW;
//    zoomimg.height = zoomEndH;

    if (execWhenDone != "") {
      eval(execWhenDone);
    }
  } else {
    clearInterval(zoomTimer[theID]);
    zoomTimer[theID] = setInterval("zoomElement('"+zoomdiv+"', 'ZoomImage', "+zoomCurrent+", "+zoomStartH+", "+zoomStartW+", "+zoomEndH+", "+zoomEndW+", "+zoomStartX+", "+zoomStartY+", "+zoomEndX+", "+zoomEndY+", "+zoomSteps+", "+fade+", "+fadeAmount+", '"+execWhenDone+"')", zoomTime);  }
}

////////////////////////////
//
// FADE DIV functions (2.0)
// (C) 2005 Cabel Sasser
//
// Pass fadeElementSetup the following arguments:
// theID = DIV ID that you want to fade
// fdStart = Starting opacity (0 - 100)
// fdEnd = Ending opacity (0 - 100)
// fdSteps = Number of steps to fade
// fdClose = 1 or 0. Should the DIV be set to 'hidden' after fading?

var fadeActive = new Array();
var fadeQueue  = new Array();
var fadeTimer  = new Array();
var fadeClose  = new Array();

// Initialize the fade function

function fadeElementSetup(theID, fdStart, fdEnd, fdSteps, fdClose) {

  if (fadeActive[theID] == true) {
    // Already animating, queue up this command
    fadeQueue[theID] = new Array(theID, fdStart, fdEnd, fdSteps);
  } else {
    fadeSteps = fdSteps;
    fadeCurrent = 0;
    fadeAmount = (fdStart - fdEnd) / fadeSteps;
    fadeTimer[theID] = setInterval("fadeElement('"+theID+"', '"+fadeCurrent+"', '"+fadeAmount+"', '"+fadeSteps+"')", 40);
    fadeActive[theID] = true;
    if (fdClose == 1) {
      fadeClose[theID] = true;
    } else {
      fadeClose[theID] = false;
    }
  }
}

// Do the fade. This function will call itself, modifying the parameters, so
// many instances can run concurrently.

function fadeElement(theID, fadeCurrent, fadeAmount, fadeSteps) {
  fadeCurrent++;
  // Set the opacity depending on if we're adding or subtracting (pos or neg)
  if (fadeAmount < 0) {
    setOpacity(Math.abs(fadeCurrent * fadeAmount), theID);
  } else {
    setOpacity(100 - (fadeCurrent * fadeAmount), theID);
  }
  if (fadeCurrent == fadeSteps) {
    // We're done, so clear.
    clearInterval(fadeTimer[theID]);
    fadeActive[theID] = false;
    
    // Should we close it?
    
    if (fadeClose[theID] == true) {
      document.getElementById(theID).style.visibility = "hidden";
    }
    
    // Hang on.. did a command queue while we were working? If so, make it happen now
    
    if (fadeQueue[theID] && fadeQueue[theID] != false) {
      fadeElementSetup(fadeQueue[theID][0], fadeQueue[theID][1], fadeQueue[theID][2], fadeQueue[theID][3]);
      fadeQueue[theID] = false;
    }
    
  } else {
    // Keep going, and send myself the updated variables
    clearInterval(fadeTimer[theID]);
    fadeTimer[theID] = setInterval("fadeElement('"+theID+"', '"+fadeCurrent+"', '"+fadeAmount+"', '"+fadeSteps+"')", 40);
  }
}

// Set the opacity, compatible with a number of browsers

function setOpacity(opacity, theID) {

  var object = document.getElementById(theID).style;

  // If it's 100, set it to 99 for Firefox.

  if (navigator.userAgent.indexOf("Firefox") != -1) {
    if (opacity == 100) { opacity = 99.999; } // This is majorly retarded
  }

  // Multi-browser opacity setting

  object.filter = "alpha(opacity=" + opacity + ")"; // IE/Win
  object.KhtmlOpacity = (opacity / 100);            // Safari 1.1 or lower, Konqueror
  object.MozOpacity = (opacity / 100);              // Older Mozilla+Firefox
  object.opacity = (opacity / 100);                 // Safari 1.2, Firefox+Mozilla
}

//
// ----- DISPLAY CODE -----
//

function insertZoomHTML() {

  // All of this junk creates the three <div>'s used to hold the closebox, image, and zoom shadow.
  // It's a lot of Javascript for a little HTML. But, hey, this must be the "right way", though, yeah?

  // Tech Notes:
  // 1. The "inCol8.innerHTML = '&nbsp;';" lines are so that empty shadow columns have some content, forcing them to display
  //    It works fine when empty in Safari, but not Firefox -- unless you have borders turned on. Go figure.

  // <div id="ZoomBox">
  //   <a href="javascript:zoomOut(1);"><img src="/images/spacer.gif" id="ZoomImage" border="0"></a>
  //   <div id="ZoomClose">
  //     <a href="javascript:zoomOut(1);"><img src="/images/closebox.png" width="30" height="30" border="0"></a>
  //   </div>
  // </div>

  var inBody = document.getElementsByTagName("body").item(0);

  var inOverlay = document.createElement("div");
  inOverlay.setAttribute('id', 'ZoomOverlay');
  inOverlay.style.display = 'none';
  if (navigator.appVersion.indexOf("MSIE") != -1)
    inOverlay.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+zoomFolder+"zoom-backg.png', sizingMethod='scale')";
  else
    inOverlay.style.backgroundImage = 'url('+zoomFolder+'zoom-backg.png)';
  inOverlay.style.position = 'absolute';
  inOverlay.style.zIndex = '40';
  inOverlay.style.top = '0px';
  inOverlay.style.left = '0px';
  inOverlay.style.width = '100%';
  inOverlay.style.height = '100%';
  inBody.insertBefore(inOverlay, inBody.firstChild);

  var inZoombox = document.createElement("div");
  inZoombox.setAttribute('id', 'ZoomBox');
  inZoombox.style.position = 'absolute'; 
  inZoombox.style.left = '10px';
  inZoombox.style.top = '10px';
  inZoombox.style.visibility = 'hidden';
  inZoombox.style.zIndex = '50';
  // inZoombox.style.background = 'white';           // DEBUG
  inBody.insertBefore(inZoombox, inBody.firstChild);

  var inLink1 = document.createElement("a");
  inLink1.setAttribute('href','javascript:zoomOut(1);');
  inZoombox.appendChild(inLink1);
  
  var inImage1 = document.createElement("img");
  inImage1.setAttribute('src',zoomFolder+'spacer.gif');
  inImage1.setAttribute('id','ZoomImage');
  inImage1.setAttribute('border', '0');
  inImage1.style.display = 'block';
  inLink1.appendChild(inImage1);
  /*
  var inClosebox = document.createElement("div");
  inClosebox.setAttribute('id', 'ZoomClose');
  inClosebox.style.position = 'absolute';
  inClosebox.style.left = '-15px';
  inClosebox.style.top = '-15px';
  inClosebox.style.filter = 'alpha(opacity=0)';
  inClosebox.style.MozOpacity = '0';
  inClosebox.style.opacity = '0';
  inClosebox.style.visibility = 'hidden';
  inZoombox.appendChild(inClosebox);
  
  var inLink2 = document.createElement("a");
  inLink2.setAttribute('href','javascript:zoomOut(1);');
  inClosebox.appendChild(inLink2);
  var inImage2 = document.createElement("img");
  inImage2.setAttribute('src',zoomFolder+'closebox.png');
  inImage2.setAttribute('width','30');
  inImage2.setAttribute('height','30');
  inImage2.setAttribute('border','0');
  inLink2.appendChild(inImage2);
*/  
  // That's the end of the 'ZoomBox' DIV. Phew.
  // Now, the.. shudder.. shadow table.
  
  // <div id="ShadowBox"><table border="0" width="100%" height="100%" cellpadding="0" cellspacing="0"> X
  //   <tr height="25">
  //   <td width="27"><img src="/images/zoom-shadow1.png" width="27" height="25"></td>
  //   <td background="/images/zoom-shadow2.png">&nbsp;</td>
  //   <td width="27"><img src="/images/zoom-shadow3.png" width="27" height="25"></td>
  //   </tr>

  var inShadowbox = document.createElement("div");
  inShadowbox.setAttribute('id', 'ShadowBox');
  inShadowbox.style.position = 'absolute'; 
  inShadowbox.style.left = '50px';
  inShadowbox.style.top = '50px';
  inShadowbox.style.width = '100px';
  inShadowbox.style.height = '100px';
  inShadowbox.style.visibility = 'hidden';
  inShadowbox.style.zIndex = '45';
  inBody.insertBefore(inShadowbox, inZoombox.nextSibling);
  
  var inTable = document.createElement("table");
  if (debugShadow == 1) {
    inTable.setAttribute('border', '2');
  } else {
    inTable.setAttribute('border', '0');
  }
  inTable.setAttribute('width', '100%');
  inTable.setAttribute('height', '100%');
  inTable.setAttribute('cellpadding', '0');
  inTable.setAttribute('cellspacing', '0');
  inTable.style.borderCollapse = 'collapse';
  inShadowbox.appendChild(inTable);
  
  var inTBody = document.createElement("tbody");
  inTable.appendChild(inTBody);
  
  var inRow1 = document.createElement("tr");
  inRow1.style.height = '25px';
  inTBody.appendChild(inRow1);
  
  var inCol1 = document.createElement("td");
  inCol1.style.width = '27px';
  inRow1.appendChild(inCol1);
  if (navigator.appVersion.indexOf("MSIE") != -1)
  {
    inCol1.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+zoomFolder+"zoom-shadow1.png', sizingMethod='scale')";
  } else {
    var inShadowImg1 = document.createElement("img");
    inShadowImg1.setAttribute('src', zoomFolder+'zoom-shadow1.png');
    inShadowImg1.setAttribute('width', '27');
    inShadowImg1.setAttribute('height', '25');
    inShadowImg1.style.display = 'block';
    inCol1.appendChild(inShadowImg1);
  }

  var inCol2 = document.createElement("td");
  if (navigator.appVersion.indexOf("MSIE") != -1)
  {
    inCol2.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+zoomFolder+"zoom-shadow2.png', sizingMethod='scale')";
  } else {
    inCol2.setAttribute('background', zoomFolder+'zoom-shadow2.png');
  }
  inRow1.appendChild(inCol2);
  // inCol2.innerHTML = '<img src=';
  var inSpacer1 = document.createElement("img");
  inSpacer1.setAttribute('src',zoomFolder+'spacer.gif');
  inSpacer1.setAttribute('height', '1');
  inSpacer1.setAttribute('width', '1');
  inSpacer1.style.display = 'block';
  inCol2.appendChild(inSpacer1);

  var inCol3 = document.createElement("td");
  inCol3.style.width = '27px';
  inRow1.appendChild(inCol3);  
  if (navigator.appVersion.indexOf("MSIE") != -1)
  {
    inCol3.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+zoomFolder+"zoom-shadow3.png', sizingMethod='scale')";
  } else {
    var inShadowImg3 = document.createElement("img");
    inShadowImg3.setAttribute('src', zoomFolder+'zoom-shadow3.png');
    inShadowImg3.setAttribute('width', '27');
    inShadowImg3.setAttribute('height', '25');
    inShadowImg3.style.display = 'block';
    inCol3.appendChild(inShadowImg3);
  }

  //   <tr>
  //   <td background="/images/zoom-shadow4.png">&nbsp;</td>
  //   <td bgcolor="#ffffff">&nbsp;</td>
  //   <td background="/images/zoom-shadow5.png">&nbsp;</td>
  //   </tr>

  inRow2 = document.createElement("tr");
  inTBody.appendChild(inRow2);
  
  var inCol4 = document.createElement("td");
  if (navigator.appVersion.indexOf("MSIE") != -1)
  {
    inCol4.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+zoomFolder+"zoom-shadow4.png', sizingMethod='scale')";
  } else {
    inCol4.setAttribute('background', zoomFolder+'zoom-shadow4.png');
  }
  inRow2.appendChild(inCol4);
  // inCol4.innerHTML = '&nbsp;';
  var inSpacer2 = document.createElement("img");
  inSpacer2.setAttribute('src',zoomFolder+'spacer.gif');
  inSpacer2.setAttribute('height', '1');
  inSpacer2.setAttribute('width', '1');
  inSpacer2.style.display = 'block';
  inCol4.appendChild(inSpacer2);
  
  var inCol5 = document.createElement("td");
  inCol4.setAttribute('id','ShadowBoxIEhack');
  inCol5.setAttribute('bgcolor', '#ffffff');
  inRow2.appendChild(inCol5);
  // inCol5.innerHTML = '&nbsp;';
  var inSpacer3 = document.createElement("img");
  inSpacer3.setAttribute('src',zoomFolder+'spacer.gif');
  inSpacer3.setAttribute('height', '1');
  inSpacer3.setAttribute('width', '1');
  inSpacer3.style.display = 'block';
  inCol5.appendChild(inSpacer3);
  
  var inCol6 = document.createElement("td");
  if (navigator.appVersion.indexOf("MSIE") != -1)
  {
    inCol6.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+zoomFolder+"zoom-shadow5.png', sizingMethod='scale')";
  } else {
    inCol6.setAttribute('background', zoomFolder+'zoom-shadow5.png');
  }
  inRow2.appendChild(inCol6);
  // inCol6.innerHTML = '&nbsp;';
  var inSpacer4 = document.createElement("img");
  inSpacer4.setAttribute('src',zoomFolder+'spacer.gif');
  inSpacer4.setAttribute('height', '1');
  inSpacer4.setAttribute('width', '1');
  inSpacer4.style.display = 'block';
  inCol6.appendChild(inSpacer4);

  //   <tr height="26">
  //   <td width="27"><img src="/images/zoom-shadow6.png" width="27" height="26"</td>
  //   <td background="/images/zoom-shadow7.png">&nbsp;</td>
  //   <td width="27"><img src="/images/zoom-shadow8.png" width="27" height="26"></td>
  //   </tr>  
  // </table></div>

  var inRow3 = document.createElement("tr");
  inRow3.style.height = '26px';
  inTBody.appendChild(inRow3);
  
  var inCol7 = document.createElement("td");
  inCol7.style.width = '27px';
  inRow3.appendChild(inCol7);
  if (navigator.appVersion.indexOf("MSIE") != -1)
  {
    inCol7.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+zoomFolder+"zoom-shadow6.png', sizingMethod='scale')";
  } else {
    var inShadowImg7 = document.createElement("img");
    inShadowImg7.setAttribute('src', zoomFolder+'zoom-shadow6.png');
    inShadowImg7.setAttribute('width', '27');
    inShadowImg7.setAttribute('height', '26');
    inShadowImg7.style.display = 'block';
    inCol7.appendChild(inShadowImg7);
  }

  var inCol8 = document.createElement("td");
  if (navigator.appVersion.indexOf("MSIE") != -1)
  {
    inCol8.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+zoomFolder+"zoom-shadow7.png', sizingMethod='scale')";
  } else {
    inCol8.setAttribute('background', zoomFolder+'zoom-shadow7.png');
  }
  inRow3.appendChild(inCol8);  
  // inCol8.innerHTML = '&nbsp;';
  var inSpacer5 = document.createElement("img");
  inSpacer5.setAttribute('src',zoomFolder+'spacer.gif');
  inSpacer5.setAttribute('height', '1');
  inSpacer5.setAttribute('width', '1');
  inSpacer5.style.display = 'block';
  inCol8.appendChild(inSpacer5);

  var inCol9 = document.createElement("td");
  inCol9.style.width = '27px';
  inRow3.appendChild(inCol9);  
  if (navigator.appVersion.indexOf("MSIE") != -1)
  {
    inCol9.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+zoomFolder+"zoom-shadow8.png', sizingMethod='scale')";
  } else {
    var inShadowImg9 = document.createElement("img");
    inShadowImg9.setAttribute('src', zoomFolder+'zoom-shadow8.png');
    inShadowImg9.setAttribute('width', '27');
    inShadowImg9.setAttribute('height', '26');
    inShadowImg9.style.display = 'block';
    inCol9.appendChild(inShadowImg9);
  }
  
  if (includeCaption == 1) {

    // CAPTION
    //
    // <table border="1" cellpadding="0" cellspacing="0">
    // <tr height="26">
    // <td><img src="zoom-caption-l.png" width="13" height="26"></td>
    // <td rowspan="3" background="zoom-caption-fill.png"><div id="ZoomCaption"></div></td>
    // <td><img src="zoom-caption-r.png" width="13" height="26"></td>
    // </tr>
    // </table>
    
    var inCapDiv = document.createElement("div");
    inCapDiv.setAttribute('id', 'ZoomCapDiv');
    inCapDiv.style.display = 'none';
    inCapDiv.style.marginLeft = '13px';
    inCapDiv.style.marginRight = '13px';
    inShadowbox.appendChild(inCapDiv);
    
    var inCapTable = document.createElement("table");
    inCapTable.setAttribute('border', '0');
    inCapTable.setAttribute('cellpadding', '0');
    inCapTable.setAttribute('cellspacing', '0');
    inCapTable.setAttribute('align', 'center');
    inCapTable.style.marginLeft = 'auto';
    inCapTable.style.marginRight = 'auto';
    inCapTable.style.borderCollapse = 'collapse';
    inCapDiv.appendChild(inCapTable);
    
    var inCapTBody = document.createElement("tbody");
    inCapTable.appendChild(inCapTBody);
    
    var inCapRow1 = document.createElement("tr");
    inCapTBody.appendChild(inCapRow1);
  
    var inCapCol1 = document.createElement("td");
    inCapRow1.appendChild(inCapCol1);
    if (navigator.appVersion.indexOf("MSIE") != -1)
    {
      inCapCol1.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+zoomFolder+"zoom-caption-l.png', sizingMethod='scale')";
      var inCapSpacer1 = document.createElement("img");
      inCapSpacer1.setAttribute('src',zoomFolder+'spacer.gif');
      inCapSpacer1.setAttribute('height', '26');
      inCapSpacer1.setAttribute('width', '13');
      inCapSpacer1.style.display = 'block';
      inCapCol1.appendChild(inCapSpacer1);
    } else {
      var inCapImg1 = document.createElement("img");
      inCapImg1.setAttribute('src', zoomFolder+'zoom-caption-l.png');
      inCapImg1.setAttribute('width', '13');
      inCapImg1.setAttribute('height', '26');
      inCapImg1.style.display = 'block';
      inCapCol1.appendChild(inCapImg1);
    }
  
    var inCapCol2 = document.createElement("td");
    if (navigator.appVersion.indexOf("MSIE") != -1)
    {
      inCapCol2.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+zoomFolder+"zoom-caption-fill.png', sizingMethod='scale')";
    } else {
      inCapCol2.setAttribute('background', zoomFolder+'zoom-caption-fill.png');
    }
    inCapCol2.setAttribute('id', 'ZoomCaption');
    inCapCol2.setAttribute('valign', 'middle');
    
    inCapCol2.style.fontSize = '14px';
    inCapCol2.style.fontFamily = 'Helvetica';
    inCapCol2.style.fontWeight = 'bold';
    inCapCol2.style.color = '#ffffff';
    inCapCol2.style.textShadow = '0px 2px 4px #000000';
    inCapCol2.style.whiteSpace = 'nowrap';
    
    inCapRow1.appendChild(inCapCol2);
  
    var inCapCol3 = document.createElement("td");
    inCapRow1.appendChild(inCapCol3);
    if (navigator.appVersion.indexOf("MSIE") != -1)
    {
      inCapCol3.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+zoomFolder+"zoom-caption-r.png', sizingMethod='scale')";
      var inCapSpacer2 = document.createElement("img");
      inCapSpacer2.setAttribute('src',zoomFolder+'spacer.gif');
      inCapSpacer2.setAttribute('height', '26');
      inCapSpacer2.setAttribute('width', '13');
      inCapSpacer2.style.display = 'block';
      inCapCol3.appendChild(inCapSpacer2);
    } else {
      var inCapImg2 = document.createElement("img");
      inCapImg2.setAttribute('src', zoomFolder+'zoom-caption-r.png');
      inCapImg2.setAttribute('width', '13');
      inCapImg2.setAttribute('height', '26');
      inCapImg2.style.display = 'block';
      inCapCol3.appendChild(inCapImg2);
    }
  }
}
