/************************** Image Carousel 2 **********************************
*******************************************************************************
Author: Kendall Conrad of Angelwatt.com
Home Page: http://www.angelwatt.com/coding/
Created: 2008
Updated: 2009-09-06
Description: Takes a group of images and allows them to be scrolled left/right
continuously without a beginning or end.
License:
* This work is licensed under a Creative Commons Attribution-Share Alike
  3.0 United States License
  http://creativecommons.org/licenses/by-sa/3.0/us/
******************************************************************************/
function ImageCarousel2(args) {
  // Make sure required argument exist
  if (args['cid'] === undefined || args['images'] === undefined) {
    return false;
  }
  // Setup main variable
  this.v = {
    id:   args['cid'],                  // tag where carousel should be placed
    step: parseInt(args['speed']) || 5, // speed, integer
    dir:  args['direction'] || 'left',  // direction of carousel
    imgs: [],      // holds image sources
    timer:   null, // animation timer
    count:   0,    // for totaler function
    wAll:    0,    // width of carousel
    offsets: null,  // holds current offset position of each image
    padding:15
  };
  // Make sure step is valid int
  if (isNaN(this.v['step'])) { this.v['step'] = 5; }
  var self;

  // Check if images are in array or in the DOM
  if (typeof(args['images']) == 'string') { // id
    this.v['arr'] = false;
    // Check that ID exist on page
    if (!document.getElementById(args['images'])) { return false; }
    var im =document.getElementById(args['images']).getElementsByTagName('img');
    // Check that there exist at least 2 image
    if (im.length <= 1) { return false; }
    var a=0, b=im.length;
    do { this.v['imgs'][a] = im[a].src; } while (++a < b);
  }
  // Check if array of images was sent
  else if (args['images'].constructor.toString().match(/array/i)) {
    this.v['arr'] = true;
    this.v['imgs'] = args['images'];
  }
  // Neither an ID or an array of images, bail
  else { return false; }
  // Initiate offset array to number of images found
  this.v['offsets'] = new Array(this.v['imgs'].length);

  this.Init = function() {
    self = this; var v = self.v;
    // Place images onto page
    var cid = document.getElementById(v['id']);
    var txt = '';
    for (var x=0, y=v['imgs'].length; x<y; x++) {
      txt += "<img src='"+  v['imgs'][x]
        +"' style='position:absolute; top:0;' alt='' />";
    }
    cid.innerHTML = txt;
    v['imgs'] = document.getElementById(v['id']).getElementsByTagName('img');

    // preload images and gather widths
    for (var x=0; x < v['imgs'].length; x++) {
      v['offsets'][x] = 0;
      // If images were gathered from page, no need to preload
      if (v['imgs'][x].width > 0) { self.Totaler(v['imgs'][x]); continue; }
      var img = new Image();
      img.onload = function(){ self.Totaler(this); };
      img.src = v['imgs'][x].src;
    }

    v['wAll'] += ( v['padding'] * 2 )
  };
  this.Totaler = function(i) {
    var v = self.v;
    v['wAll'] += ( i.width + v['padding'] );
    // Check if all images in carousel are loaded
    if (++v['count'] >= v['imgs'].length) {
      var max = 0;
      for (var x=0, y=v['imgs'].length; x<y; x++) {
        // Find max height among images
        max = (v['imgs'][x].height > max) ? v['imgs'][x].height : max;
      }
      document.getElementById(v['id']).style.height = max +'px';
      self.Start();
    }
  };
  this.Start = function() {
    var v = self.v;
    // set initial positions
    var t = 0;
    for (var x=0, y=v['imgs'].length; x<y; x++) {
      v['offsets'][x] = t;
      v['imgs'][x].style.left = (t +'px');
      t += v['imgs'][x].width + v['padding'];
    }
    if (v['dir'].match(/left/i)) { self.Left(); }
    else { self.Right(); }
  };
  this.Stop = function() {
    clearTimeout(self.v['timer']);
  };
  this.Left = function() {
    var v = self.v;
    self.Stop();
    var step = v['step'];
    for (var x=0, y=v['imgs'].length; x<y; x++) {
      // Reset to far right once completely off left side
      if ((v['offsets'][x]-step) < (0-(v['imgs'][x].width + v['padding'] ))) {
        // set offset to far right
        v['offsets'][x] += v['wAll'] - step;
      }
      else { v['offsets'][x] -= step; }
    }
    self.Redraw();
    v['timer'] = setTimeout(function(){self.Left()}, 70);
  };
  this.Right = function() {
    var v = self.v;
    self.Stop();
    var step = v['step'];
    for (var x=0, y=v['imgs'].length; x<y; x++) {
      if ((v['offsets'][x] + step) > (v['wAll'] - ( v['imgs'][x].width + v['padding']))) {
        v['offsets'][x] += step - v['wAll'];
      }
      else { v['offsets'][x] += step; }
    }
    self.Redraw();
    v['timer'] = setTimeout(function(){self.Right()}, 70);
  };
  this.Redraw = function() {
    var v = self.v;
    for (var x=0, y=v['imgs'].length; x<y; x++) {
      v['imgs'][x].style.left = v['offsets'][x] + (x + v['padding']) +'px';
    }
  };
  this.SetSpeed = function(sp) {
    if (isNaN(parseInt(sp))) { return false; }
    self.v['step'] = parseInt(sp);
  };
  this.Init();
  return {
    Left:this.Left, Right:this.Right, Stop:this.Stop, SetSpeed:this.SetSpeed
  };
}
function appendOnLoad(fx) {
  try { // For browsers that know DOMContentLoaded (FF, Safari, Opera)
    document.addEventListener("DOMContentLoaded", fx, false);
  } catch(e) {
    var old = window.onload;
    if (typeof old != 'function') { window.onload = fx; }
    else { window.onload = function() { old(); fx(); } }
  }
}
