/*****************************************************************
/*      Copyright notice :
/*   Javascript created by and copyright : www.cass-hacks.com
/*    This work is licensed according to the following Terms and Conditions :
/*    Copyright (c) 2007 & 2008 cass-hacks.com</p>
/*    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
/*    files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, 
/*    merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished 
/*    to do so, subject to the following conditions:
/*    1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer.
/*    2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer 
/*        in the documentation and/or other materials provided with the distribution, and in the same place and form as other copyright, 
/*        license and disclaimer information.
/*    3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product 
/*        includes software developed by Cass-hacks.com (http://cass-hacks.com/) and its contributors", in the same place and 
/*        form as other third-party acknowledgments. Alternately, this acknowledgment may appear in the software itself, in the same form 
/*        and location as other such third-party acknowledgments.
/*    4. Except as contained in this notice, the name of Cass-hacks.com shall not be used in advertising or otherwise to 
/*        promote the sale, use or other dealings in this Software without prior written authorization from Cass-hacks.com.
/*    
/*    THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
/*    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
/*    DISCLAIMED. IN NO EVENT SHALL THE XFREE86 PROJECT, INC OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
/*    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
/*    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
/*    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
/*    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
/*    POSSIBILITY OF SUCH DAMAGE.
/*    
/*    If you find something on this site useful, please use the contact form to inform Cass-hacks of your application.  If need be, 
/*    modifications could be made to any of the code found on this site to more accurately fit a given application's needs and 
/*    requirements.
/*
******************************************************************/
// Thumbnail onload
//if (window.addEventListener)
//  window.addEventListener('load',init_images,false);
//else if (window.attachEvent)
//  window.attachEvent('onload',init_images);

function init_images () {
  /*  Get a pointer to the area, id=opaqued that contains the
        images to be expanded.  */
  var opaque_region = document.getElementById('opaqued');
  var imgs = opaque_region.getElementsByTagName('img');
  for (var x=0;x<imgs.length;x++) {
    //  Check each link to see if it is a target, css class = "expando".
    //if (imgs[x].className.indexOf('expando') != -1) {
      imgs[x].onmouseover = init_expansion;
    //}
  }
}

/*  The size, in pixels, of each step of the minor expansion 
      process between in-page image size and "full" minor 
      expansion size.  */
var step = 6;
/*  The number of milliseconds between each minor and 
      major expansion process iteration. */
var wait = 40;
/*  The number of iterations of the major expansion 
      process between "full" minor expansion size and 
      major expansion image full size.  */
var steps = 10;
/*  The size that in-page images will appear to expand 
      to during the minor expansion process.  */
var inter_size_width = 150;
//  The full width the drop shadow will attain.
var sm_shdwWidth = 8;
/*  The level of greatest transparency the background 
      will achieve during the major expansion process.  */
var min_opacity = 35;
/*  A text string in a given thumbnail image URL which 
      identifies it as a thumbnail url.  */
var thumbs_id = 'thmb';
/*  A text string in a given full size image URL which 
      identifies it as a full size image url.  */
var source_id = 'full';
//  A pointer to the in-page thumbnail
var thm_image = null;
//  Size, position and center of in-page thumbnail
var thmWidth, thmHeight, thmLeft, thmTop;
var thmCntrX,thmCntrY;
//  Height and width of full size image
var full_height,full_width;
/*  Amount added or subtracted from current values
      during eahc major expansion iteration.  */
var stepX,stepY,stepWidth,stepHeight;
//  The current values at any give point.
var crntX,crntY,crntWidth,crntHeight;
//  Timer used to control expansion and collapse
var expando_timer;
/*  The amount the drop shadow padding is 
      adjusted on each minor expansion and
      its current value.  */
var sm_shdwStep, sm_shdwCurrent;
/*  The amount the background opacity is 
      adjusted on each major expansion and
      its current value.  */
var opacity, opacity_step;
/*  Set during minor and major expansion
      and unset after complete collapse.  */
var bShowing = false;
/*  Container div used to contain the minor expansion image
      as well as the padding and drop shadow elements and
      a pointer to where the minor expansion image is
      inserted into the minor expansion container.  */
var thm_container = null;
var thm_insertion = null;
var small_expand = null;
//  Similar elements and pointers as for the minor expansion
var full_container = null;
var full_insertion = null;
var full_expand = null;
//  Area whose opacity is effected during the major expansion
var opaque_region = null;
/*  Used to properly locate elements with respect to
      the in-page thumbnail.  */
var scrollParent = null;
//  Object used for pre-loading the major expansion image
var pre_loader = null;

function init_expansion () {
  //  If we are already in the expansion process, no need to start it again.
  if (bShowing) return;
  /*  Reality check, kill the timer so that multiple timer 
         events don't fire while we are processing this one. */
  if (expando_timer) clearTimeout(expando_timer);
  //  If a minor expansion element already exists, delete it from the page.
  if (small_expand != null) {
    thm_container.parentNode.removeChild(thm_container);
  }
  /*  Set the region that will be made semi-transparent 
         during the major expansion process */
  scrollParent = opaque_region.parentNode;
  /*  The owner of this function call is the in-page thumbnail
        image. We will collect various data to be used to locate the
        minor and major expansion elements.  */
  thm_image = this;
  /*  Kill the in-page thumbnail image onmouseover event
        so that it doesn't fire while the minor and major elements
        exist.  */
  thm_image.mouseover = null;
  /*  Collect height, width, top and left position information
        from the in-page thumbnail image.  */
  thmWidth = thm_image.offsetWidth;
  thmHeight =thm_image.offsetHeight;
  thmLeft = getOffsetLeft(thm_image);
  thmTop =getOffsetTop(thm_image) - scrollParent.scrollTop;
  //  Identify the center of the in-page thumbnail image.
  thmCntrY = thmTop+thmHeight/2;
  thmCntrX = thmLeft+thmWidth/2;
  /*  Create and populate the container that will contain the minor 
        expansion image.  */
  small_expand = document.createElement('img');
  small_expand.style.visibility = 'hidden';
  small_expand.src = thm_image.src;
  small_expand.className = 'grow_img';
  small_expand.title = 'Click to Expand';
  thm_container = document.createElement('div');
  //  Locate the "body" element and add the container to it.
  document.getElementsByTagName('body')[0].appendChild(thm_container);
  thm_container.className = 'center2';
  thm_container.id = 'thm_container';
  //  Setup the container with the drop shadow divs.
  thm_container.innerHTML = '<div class="fs_t">' +
                                            '<div class="fs_r">' +
                                              '<div class="fs_b">' +
                                                '<div class="fs_l">' +
                                                  '<div class="fs_tr">' + 
                                                    '<div class="fs_br">' +
                                                      '<div class="fs_bl">' +
                                                        '<div class="fs_tl" id="thm_insertion">' + 
                                                        '</div>' +
                                                      '</div>' +
                                                    '</div>' +
                                                  '</div>' +
                                                '</div>' +
                                              '</div>' +
                                            '</div>' +
                                          '</div>';
  /*  Locate the container image insertion point and
        insert the image.  */
  insertion_point = document.getElementById('thm_insertion');
  insertion_point.appendChild(small_expand);
  /*  Initialize parameters used to keep track of expansion size
        and set the initial size and position of the expansion image.  */
  crntWidth = thmWidth;
  crntHeight = thmHeight;
  small_expand.style.width = crntWidth+'px';
  small_expand.style.height = crntHeight+'px';
  thm_container.style.top = thmTop-2+'px';
  thm_container.style.left = thmLeft-2+'px';
  //  Set the event handler for mouseout.
  small_expand.onmouseout = init_thumb_collapse;
  //  Make it visible.
  small_expand.style.visibility = 'visible';
  /*  Initialize the current drop shadow step size and 
        its current value to 0.  */
  sm_shdwStep = (sm_shdwWidth/(140 - thmWidth))*step/2;
  sm_shdwCurrent = 0;
  //  Begin the iterative expansion process.
  expand_thumb();
}

function expand_thumb () {
  //  Another timer reality check
  if (expando_timer) clearTimeout(expando_timer);
  /*  Increment the height and width variables and update
        expanding image's top and left position as well as
        adjusting the expanding image to the center of the
        in-page thumbnail.  */
  crntHeight += step;
  crntWidth += step;
  small_expand.style.height = crntHeight+'px';
  small_expand.style.width = crntWidth+'px';
  thm_container.style.top = parseInt(thmCntrY-crntHeight/2)+'px';
  thm_container.style.left = parseInt(thmCntrX-crntWidth/2)+'px';
  /*  Increment the shadow width counter variable and update the left
        and bottom padding values giving the appearance that the shadow
        actually grows.  */
  sm_shdwCurrent += sm_shdwStep;
  insertion_point.style.padding = parseInt(sm_shdwCurrent)+'px';
  insertion_point.style.paddingBottom = parseInt(sm_shdwCurrent/2)+'px';
  /*  Check to see if the expanding image has achieved the desired size, 
        as set by "inter_size_width".  If not, set the timer and do it again.  */
  if (crntWidth < inter_size_width) {
    expando_timer = setTimeout(expand_thumb,wait);
  } else {
    /*  If the expanding image has reached the desired size, set the
           inter_size_height to the current height as the resulting height
           may be plus or minus a few pixel and we need to know exactly
           where we started so we can know where to end up on collapse.  */
    inter_size_height = crntHeight;
    /*  Set the expanded image's onclick so that if the user clicks
            on the expanded image, it will then begin the process to
            fully expand. This is set at this time so that it can not be fired
            earlier when the image may be in the process of completing
            the initial minor expansion.  */
    small_expand.onclick = init_expand_full;
  }
}

function init_thumb_collapse () {
  //  Begin collapsing the minor expansion image.
  /*  If for some reason this gets called when the image is
        actually in the process of being displayed, which can happen
        under certain race conditions, this function can bail out.  */
  if (bShowing) return;
  /*  Make sure the expansion image actually exists and then
        begin the collapsing process.  */
  if (small_expand != null) {
    collapse_thumb();
  }
}

function collapse_thumb () {
  //  And yet another timer reality check.
  if (expando_timer) clearTimeout(expando_timer);
  /*  Basically do the opposite of what was done before, add where
        we subtracted and subtract where we added and put your right
        foot in, your right foot,,,, oh, sorry,  back to work.  */
  crntWidth -= step;
  crntHeight -= step;
  small_expand.style.width = parseInt(crntWidth)+'px';
  small_expand.style.height = parseInt(crntHeight)+'px';
  thm_container.style.top = parseInt(thmCntrY-crntHeight/2)+'px';
  thm_container.style.left = parseInt(thmCntrX-crntWidth/2)+'px';
  sm_shdwCurrent -= sm_shdwStep;
  insertion_point.style.padding = parseInt(sm_shdwCurrent)+'px';
  insertion_point.style.paddingBottom = parseInt(sm_shdwCurrent/2)+'px';
  if (crntWidth > thmWidth)
    expando_timer = setTimeout(collapse_thumb,wait);
  else {
    /*  There is a race condition that exists that was difficult
            to find the source of without this timer reality check.  */
    if (expando_timer) clearTimeout(expando_timer);
    /*  Reset the mouseover event for the in-page thumbnail
            so that it can be expanded again.  */
    thm_image.onmouseover = init_expansion;
    //  Remove the expansion image and its container from the page.
    thm_container.parentNode.removeChild(thm_container);
    small_expand = null;
  }
}

function init_expand_full () {
  if (expando_timer) clearTimeout(expando_timer);
  /*  Anyone notice the timer reality check?  No?  Good.
        Similar to the minor expansion, if an object that was used
        in a previous major expansion still exists, kill it.  */
  if (full_expand != null)
    full_container.parentNode.removeChild(full_container);
  bShowing = true;
  /*  Since the image used could be larger, we will preload and wait
          for load completion before proceeding with the major expansion.  */
  pre_loader = new Image();
  pre_loader.src = thm_image.src.replace(thumbs_id,source_id);
  pre_loader.onload = prepare_expand_full;
}

function prepare_expand_full () {
  /*  At this point, we know the image is loaded so we
        create and populate a container for it just like we
        did for the minor expansion.  */
  full_expand = document.createElement('img');
  full_expand.style.visibility = 'hidden';
  full_expand.src = pre_loader.src;
  delete pre_loader;
  full_expand.title = 'Click to Reduce';
  //  Begin same old - same old
  full_container = document.createElement('div');
  document.getElementsByTagName('body')[0].appendChild(full_container);
  full_container.className = 'center2';
  full_container.id = 'full_container';
  full_container.innerHTML = '<div class="fs_t">' +
                                            '<div class="fs_r">' +
                                              '<div class="fs_b">' +
                                                '<div class="fs_l">' +
                                                  '<div class="fs_tr">' +
                                                    '<div class="fs_br">' +
                                                      '<div class="fs_bl">' +
                                                        '<div class="fs_tl" id="full_insertion">' +
                                                        '</div>' +
                                                      '</div>' +
                                                    '</div>' +
                                                  '</div>' +
                                                '</div>' +
                                              '</div>' +
                                            '</div>' +
                                          '</div>';
  full_insertion = document.getElementById('full_insertion');
  full_insertion.appendChild(full_expand);
  full_insertion.style.padding = sm_shdwWidth+'px';
  full_insertion.style.paddingBottom = sm_shdwWidth/2+'px';
  full_height = full_expand.offsetHeight;
  full_width = full_expand.offsetWidth;
  full_expand.style.width = crntWidth+'px';
  full_expand.style.height = crntHeight+'px';
  full_expand.className = 'grow_img';
  if (self.innerHeight) { // all except Explorer
    var availWidth = self.innerWidth;
    var availHeight = self.innerHeight;
  } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
    var availWidth = document.documentElement.clientWidth;
    var availHeight = document.documentElement.clientHeight;
  } else if (document.body) { // other Explorers
    var availWidth = document.body.clientWidth;
    var availHeight = document.body.clientHeight;
  }
  //  End same old -same old
  /*  Here is where we diverge greatly from the minor
        expansion process. Besides having to check for 
        available area, which we didn't do before, we also
        have to find not the center of the in-page thumbnail
        but instead, the center of the browser viewport.  */
  if ( (full_height+sm_shdwCurrent*2) > availHeight) {
    full_width = full_width * (availHeight) / (full_height+sm_shdwCurrent*2);
    full_height = availHeight-(sm_shdwCurrent*2);
  }
  if ( (full_width+sm_shdwCurrent*2) > availWidth) {
    full_height = full_height * (availWidth) / (full_width+sm_shdwCurrent*2);
    full_width = availWidth-(sm_shdwCurrent*2);
  }
  if (self.pageYOffset) { // all except Explorer
  	var scrollX = self.pageXOffset;
  	var scrollY = self.pageYOffset;
  } else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict
  	var scrollX = document.documentElement.scrollLeft;
  	var scrollY = document.documentElement.scrollTop;
  } else if (document.body) { // all other Explorers
  	var scrollX = document.body.scrollLeft;
  	var scrollY = document.body.scrollTop;
  }
  /*  Now we go back to much the same process as for the 
        minor expansion.  */
  var small_container = document.getElementById('thm_container');
  full_container.style.top = getOffsetTop(small_container)+'px';
  full_container.style.left = getOffsetLeft(small_container)+'px';
  full_expand.style.visibility = 'visible';
  thm_container.style.visibility = 'hidden';
  small_expand.style.visibility = 'hidden';
  crntX = getOffsetLeft(full_container);
  crntY = getOffsetTop(full_container);
  stepY = (crntY - ((scrollY + availHeight/2 - sm_shdwWidth) - full_height/2))/steps;
  stepX = (crntX - ((scrollX + availWidth/2 - sm_shdwWidth) - full_width/2))/steps;
  stepHeight = (full_height - small_expand.offsetHeight)/steps;
  stepWidth = (full_width - small_expand.offsetWidth)/steps;
  opacity = 100;
  opacity_step = (100-min_opacity)/steps;
  full_expand.onclick = collapse_full;
  expand_full();
}

function expand_full () {
  /*  Again, basically the same as for the minor expansion
        except for two things, 1. we don't need to adjust the
        width of the drop shadow because it doesn't expand
        during this phase and 2. we instead need to adjust
        the opacity of the background.  */
  crntY -= stepY;
  crntX -= stepX;
  crntHeight += stepHeight;
  crntWidth += stepWidth;
  opacity -= opacity_step;
  /*  Some browsers understand "style.opacity" and 
        some "style.filter".  */
  opaque_region.style.opacity = opacity/100;
  opaque_region.style.filter = 'alpha(opacity='+opacity+')';
  full_container.style.left = parseInt(crntX)+'px';
  full_container.style.top = parseInt(crntY)+'px';
  full_expand.style.width = parseInt(crntWidth)+'px';
  full_expand.style.height = parseInt(crntHeight)+'px';
  //  Again, if we haven't reached full size, spin the bottle again.
  if (crntHeight < full_height)
    expando_timer = setTimeout(expand_full,wait);
}

function collapse_full () {
  /*  Same as minor expansion collapse, add where
          previously one subtracted and vice versa.
          The opacity of the background must also be
          ramped back up to normal.  */
  full_expand.onclick = null;
  crntY += stepY;
  crntX += stepX;
  crntHeight -= stepHeight;
  crntWidth -= stepWidth;
  full_container.style.top = parseInt(crntY)+'px';
  full_container.style.left = parseInt(crntX)+'px';
  full_expand.style.height = parseInt(crntHeight)+'px';
  full_expand.style.width = parseInt(crntWidth)+'px';
  opacity += opacity_step;
  opaque_region.style.opacity = opacity/100;
  opaque_region.style.filter = 'alpha(opacity='+opacity+')';
  if (crntHeight + sm_shdwCurrent > inter_size_height)
    expando_timer = setTimeout(collapse_full,wait);
  else {
  //  Guess what, another timer reality check, bet you weren't expecting that!
    small_expand.style.visibility = 'visible';
    thm_container.style.visibility = 'visible';
    if (expando_timer) clearTimeout(expando_timer);
    bShowing = false;
    opaque_region.style.opacity = 1;
    opaque_region.style.filter = 'alpha(opacity=100)';
    full_container.parentNode.removeChild(full_container);
    full_expand = null;
    collapse_thumb();
  }
}

/*  The following two functions are used to find the true position of
      an element on a given paged.  They function by traversing a given
      element's "offsetParent" tree up to the point where there is no 
      further parent element.  Each parent element's position is then 
      added to the top/left value of the target element itself to arrive
      at the full top/left value.  */
function getOffsetTop (element) {
	var parent = null;
	var value = element.offsetTop;
	while ( element = element.offsetParent )
		value += element.offsetTop;
	return value;
}
function getOffsetLeft (element) {
	var parent = null;
	var value = element.offsetLeft;
	while ( element = element.offsetParent )
		value += element.offsetLeft;
	return value;
}