﻿// trans1.11 :: Image swap-fade 
// *****************************************************
// DOM scripting by brothercake -- http://www.brothercake.com/
//******************************************************
//global object
var trans = { 'clock': null, 'fade': true, 'count': 1 }
//trans.effects = ['swap', 'fade', 'wipe']; //Wipe has issues
trans.effects = ['swap'];

//To allow for easier recognition of the directions
trans.Directions =
{
   'leftToRight': 'lt',
   'rightToLeft': 'rt',
   'topToBottom': 'tb',
   'bottomToTop': 'bt',
   'topLToBottomR': 'tltr',
   'topRToBottomL': 'trbl',
   'bottomLToTopR': 'bltr',
   'bottomRToTopL': 'brtl',
   'centerToVerticalEdge': 'cve',
   'centerToHorizontalEdge': 'che',
   'centerToCorners': 'cc'
}

//To allow for shuffle function to work
var directionArray =
[
   trans.Directions.bottomLToTopR,
   trans.Directions.bottomRToTopL,
   trans.Directions.bottomToTop,
   trans.Directions.centerToCorners,
   trans.Directions.centerToHorizontalEdge,
   trans.Directions.centerToVerticalEdge,
   trans.Directions.leftToRight,
   trans.Directions.rightToLeft,
   trans.Directions.topLToBottomR,
   trans.Directions.topRToBottomL,
   trans.Directions.topToBottom
];

/*Define the list of images based on URL mapping.
This is a comma delimited list with NO spaces
CALL THIS FUNCTION FIRST --OB
images == comma string of image Names
links == comma string of link Locations for the image
Both need to be in appropriate order
*/
function defineImages(images, links) {
   trans.imgs = images.toString().split(',');
   trans.imgLinks = links.toString().split(',');

   //cache the images
   trans.cache = [];
   for (var i = 0; i < trans.imgs.length; i++) {
      var image = new Image();
      image.src = trans.imgs[i];
      image.link = trans.imgLinks[i];
      trans.cache[i] = image;
   }
}

//Allows automated and dynamic transitions based on the images within the cache
function transition(currentImage) {
   var newImage = shuffle(trans.cache);
   var effect = shuffle(trans.effects);
   switch (effect) {
      case "swap":
         swapfade(currentImage, newImage.src, 3);
         break;
      case "fade":
         crossfade(currentImage, newImage.src, 3);
         break;
      case "wipe":
         crosswipe(currentImage, newImage.src, 3, shuffle(directionArray));
         break;
   }
   document.getElementById("couponCycleLink").setAttribute("Href", newImage.link);
}

//Randomly Picks an item from an Array
var current = 0;
function shuffle(o) { //v1.0
   if (current >= o.length) current = 0;   
   return o[current++];
}

//swapfade setup function
function swapfade(imgObject, newImageSrcLocation, interval) {
   //if the timer is not already going
   if (trans.clock == null) {
      //copy the image object
      trans.image = imgObject;

      //copy the image src argument
      trans.src = newImageSrcLocation;
      trans.type = setTransType();

      //if any kind of opacity is supported
      if (trans.type != 'none') {
         //copy and convert fade duration argument 
         //the duration specifies the whole transition
         //but the swapfade is two distinct transitions
         trans.length = parseInt(interval, 10) * 500;

         //create fade resolution argument as 20 steps per transition
         //again, split for the two distrinct transitions
         trans.resolution = parseInt(interval, 10) * 10;

         //start the timer
         trans.clock = setInterval('trans.swapfade()', trans.length / trans.resolution);
      }

      //otherwise if opacity is not supported
      else {
         //just do the image swap
         trans.image.src = trans.src;
      }

   }
};


//swapfade timer function
trans.swapfade = function() {
   //increase or reduce the counter on an exponential scale
   trans.count = (trans.fade) ? trans.count * 0.9 : (trans.count * (1 / 0.9));

   //if the counter has reached the bottom
   if (trans.count < (1 / trans.resolution)) {
      //clear the timer
      clearInterval(trans.clock);
      trans.clock = null;

      //do the image swap
      trans.image.src = trans.src;

      //reverse the fade direction flag
      trans.fade = false;

      //restart the timer
      trans.clock = setInterval('trans.swapfade()', trans.length / trans.resolution);

   }

   //if the counter has reached the top
   if (trans.count > (1 - (1 / trans.resolution))) {
      //clear the timer
      clearInterval(trans.clock);
      trans.clock = null;

      //reset the fade direction flag
      trans.fade = true;

      //reset the counter
      trans.count = 1;
   }

   //set new opacity value on element
   //using whatever method is supported
   switch (trans.type) {
      case 'ie':
         trans.image.filters.alpha.opacity = trans.count * 100;
         break;

      case 'khtml':
         trans.image.style.KhtmlOpacity = trans.count;
         break;

      case 'moz':
         //restrict max opacity to prevent a visual popping effect in firefox
         trans.image.style.MozOpacity = (trans.count == 1 ? 0.9999999 : trans.count);
         break;

      default:
         //restrict max opacity to prevent a visual popping effect in firefox
         trans.image.style.opacity = (trans.count == 1 ? 0.9999999 : trans.count);
   }
};

/*crosswipe setup function
Arguments [0] = the Image
[1] = interval of the fade as Integer
[2] = Direction of the Transition. : use trans.Direction Properties
*/

function crosswipe(imgObject, newImageSrcLocation, interval, direction) {
   //if the timer is not already going
   if (trans.clock == null) {
      //copy the image object 
      trans.image = imgObject;

      //get its dimensions
      trans.size = { 'w': trans.image.width, 'h': trans.image.height };

      //copy the image src argument 
      trans.src = newImageSrcLocation;


      //if dynamic element creation is supported
      if (typeof document.createElementNS != 'undefined' || typeof document.createElement != 'undefined') {
         //create a new image object and append it to body
         //detecting support for namespaced element creation, in case we're in the XML DOM
         trans.newimg = document.getElementsByTagName('body')[0].appendChild((typeof document.createElementNS != 'undefined') ? document.createElementNS('http://www.w3.org/1999/xhtml', 'img') : document.createElement('img'));

         //set positioning classname
         trans.newimg.className = 'idupe'; //so the CSS can set its visibility and position

         //set src to new image src
         trans.newimg.src = trans.src

         //move it to superimpose original image
         trans.newimg.style.left = trans.getRealPosition(trans.image, 'x') + 'px';
         trans.newimg.style.top = trans.getRealPosition(trans.image, 'y') + 'px';

         //set it to be completely hidden with clip
         trans.newimg.style.clip = 'rect(0, 0, 0, 0)';

         //show the image 
         trans.newimg.style.visibility = 'visible';

         //copy and convert fade duration argument 
         trans.length = parseInt(interval, 10) * 1000;

         //create fade resolution argument as 20 steps per transition
         trans.resolution = parseInt(interval, 10) * 20;

         //copy slide direction argument
         trans.dir = direction;

         //start the timer
         trans.clock = setInterval('trans.crosswipe()', trans.length / trans.resolution);
      }

      //otherwise if dynamic element creation is not supported
      else {
         //just do the image swap
         trans.image.src = trans.src;
      }

   }
};


//crosswipe timer function
trans.crosswipe = function() {
   //decrease the counter on a linear scale
   trans.count -= (1 / trans.resolution);

   //if the counter has reached the bottom
   if (trans.count < (1 / trans.resolution)) {
      //clear the timer
      clearInterval(trans.clock);
      trans.clock = null;

      //reset the counter
      trans.count = 1;

      //set the original image to the src of the new image
      trans.image.src = trans.src;
   }

   //animate the clip of the new image
   //using the width and height properties we saved earlier
   trans.newimg.style.clip = 'rect('
		+ ((/bt|bltr|brtl/.test(trans.dir)) ? (trans.size.h * trans.count) : (/che|cc/.test(trans.dir)) ? ((trans.size.h * trans.count) / 2) : (0))
		+ 'px, '
		+ ((/lr|tlbr|bltr/.test(trans.dir)) ? (trans.size.w - (trans.size.w * trans.count)) : (/cve|cc/.test(trans.dir)) ? (trans.size.w - ((trans.size.w * trans.count) / 2)) : (trans.size.w))
		+ 'px, '
		+ ((/tb|tlbr|trbl/.test(trans.dir)) ? (trans.size.h - (trans.size.h * trans.count)) : (/che|cc/.test(trans.dir)) ? (trans.size.h - ((trans.size.h * trans.count) / 2)) : (trans.size.h))
		+ 'px, '
		+ ((/lr|tlbr|bltr/.test(trans.dir)) ? (0) : (/tb|bt|che/.test(trans.dir)) ? (0) : (/cve|cc/.test(trans.dir)) ? ((trans.size.w * trans.count) / 2) : (trans.size.w * trans.count))
		+ 'px)';

   //keep new image in position with original image
   //in case text size changes mid transition or something
   trans.newimg.style.left = trans.getRealPosition(trans.image, 'x') + 'px';
   trans.newimg.style.top = trans.getRealPosition(trans.image, 'y') + 'px';

   //if the counter is at the top, which is just after the timer has finished
   if (trans.count == 1) {
      //remove the duplicate image
      trans.newimg.parentNode.removeChild(trans.newimg);
   }
};

//Sets up the transition type based on the browser
function setTransType() {

   var type = new String();
   //store the supported form of opacity
   if (typeof trans.image.style.opacity != 'undefined') {
      type = 'w3c';
   }
   else if (typeof trans.image.style.MozOpacity != 'undefined') {
      type = 'moz';
   }
   else if (typeof trans.image.style.KhtmlOpacity != 'undefined') {
      type = 'khtml';
   }
   else if (typeof trans.image.filters == 'object') {
      //weed out win/ie5.0 by testing the length of the filters collection (where filters is an object with no data)
      //then weed out mac/ie5 by testing first the existence of the alpha object (to prevent errors in win/ie5.0)
      //then the returned value type, which should be a number, but in mac/ie5 is an empty string
      type = (trans.image.filters.length > 0 && typeof trans.image.filters.alpha == 'object' && typeof trans.image.filters.alpha.opacity == 'number') ? 'ie' : 'none';
   }
   else {
      type = 'none';
   }

   return type;
}

/*crossfade setup function
Arguments [0] = the Image
[1] = interval of the fade as Integer
*/
function crossfade(imgObject, newImageSrcLocation, interval) {
   //if the timer is not already going
   if (trans.clock == null) {
      //copy the image object 
      trans.image = imgObject;

      //copy the image src argument 
      trans.src = newImageSrcLocation;
      trans.type = setTransType();

      //if any kind of opacity is supported
      if (trans.type != 'none') {
         //create a new image object and append it to body
         //detecting support for namespaced element creation, in case we're in the XML DOM
         trans.newimg = document.getElementsByTagName('body')[0].appendChild((typeof document.createElementNS != 'undefined') ? document.createElementNS('http://www.w3.org/1999/xhtml', 'img') : document.createElement('img'));

         //set positioning classname
         trans.newimg.className = 'idupe';

         //set src to new image src
         trans.newimg.src = trans.src

         //move it to superimpose original image
         trans.newimg.style.left = trans.getRealPosition(trans.image, 'x') + 'px';
         trans.newimg.style.top = trans.getRealPosition(trans.image, 'y') + 'px';

         //copy and convert fade duration argument
         trans.length = parseInt(interval, 10) * 1000;

         //create fade resolution argument as 20 steps per transition
         trans.resolution = parseInt(interval, 10) * 20;

         //start the timer
         trans.clock = setInterval('trans.crossfade()', trans.length / trans.resolution);
      }

      //otherwise if opacity is not supported
      else {
         //just do the image swap
         trans.image.src = trans.src;
      }

   }
};


//crossfade timer function
trans.crossfade = function() {
   //decrease the counter on a linear scale
   trans.count -= (1 / trans.resolution);

   //if the counter has reached the bottom
   if (trans.count < (1 / trans.resolution)) {
      //clear the timer
      clearInterval(trans.clock);
      trans.clock = null;

      //reset the counter
      trans.count = 1;

      //set the original image to the src of the new image
      trans.image.src = trans.src;
   }

   //set new opacity value on both elements
   //using whatever method is supported
   switch (trans.type) {
      case 'ie':
         trans.image.filters.alpha.opacity = trans.count * 100;
         trans.newimg.filters.alpha.opacity = (1 - trans.count) * 100;
         break;

      case 'khtml':
         trans.image.style.KhtmlOpacity = trans.count;
         trans.newimg.style.KhtmlOpacity = (1 - trans.count);
         break;

      case 'moz':
         //restrict max opacity to prevent a visual popping effect in firefox
         trans.image.style.MozOpacity = (trans.count == 1 ? 0.9999999 : trans.count);
         trans.newimg.style.MozOpacity = (1 - trans.count);
         break;

      default:
         //restrict max opacity to prevent a visual popping effect in firefox
         trans.image.style.opacity = (trans.count == 1 ? 0.9999999 : trans.count);
         trans.newimg.style.opacity = (1 - trans.count);
   }

   //now that we've gone through one fade iteration 
   //we can show the image that's fading in
   trans.newimg.style.visibility = 'visible';

   //keep new image in position with original image
   //in case text size changes mid transition or something
   trans.newimg.style.left = trans.getRealPosition(trans.image, 'x') + 'px';
   trans.newimg.style.top = trans.getRealPosition(trans.image, 'y') + 'px';

   //if the counter is at the top, which is just after the timer has finished
   if (trans.count == 1) {
      //remove the duplicate image
      trans.newimg.parentNode.removeChild(trans.newimg);
   }
};

//get real position method
trans.getRealPosition = function() {
   this.pos = (arguments[1] == 'x') ? arguments[0].offsetLeft : arguments[0].offsetTop;
   this.tmp = arguments[0].offsetParent;
   while (this.tmp != null) {
      this.pos += (arguments[1] == 'x') ? this.tmp.offsetLeft : this.tmp.offsetTop;
      this.tmp = this.tmp.offsetParent;
   }

   return this.pos;
};