// needs JavaScript1.2 and proper DOM support

if (document.getElementById && document.createTextNode) {
  addEvent(window, 'load', set_slide_show);
}

function set_slide_show() {
  var s = new slide_show('picture', 3000,
    ['images/slide1.jpg', 'images/slide2.jpg', 'images/slide3.jpg', 'images/slide4.jpg']);
  if (s.ready()) {
    s.rotate();
  }
}

//{{{  slide_show object
function slide_show(div_id, pause, slides, opacity_start, opacity_step, opacity_interval, dnload_check) {
  this._div_id = div_id;  // container id
  this._slides = slides;  // array of images
  this._pause = pause;  // pause between slides (ms)
  this._opacity_start = opacity_start || 10;  // starting point to fade in
  this._opacity_step = opacity_step || 10;  // step to increase opacity
  this._opacity_interval = opacity_interval || 100; // interval between increasing opacity (ms)
  this._dnload_check = dnload_check || 100;  // interval between check of download finish (ms)

  // "private" members
  this._opacity = this._opacity_start;  // current opacity level
  this._slide_ptr = 0;  // current slide pointer
  this._canvas_ptr = 0;  // pointer to current canvas
  this._curr_canvas;  // current canvas object
  this._fade_interval;  // interval id
  this._download;
  this._slide_ready = false;  // download completed ?

  // 2-elements arrays (current object & object to prepare)
  // cache (to speed up process)
  this._canvas;
  this._img;

  var o = document.getElementById(this._div_id);
  if (o) {
    var canvas0 = document.getElementById(this._div_id + 0);
    var img0 = canvas0.getElementsByTagName('img')[0];
    if (img0) {
      var img1 = document.createElement('img');
      var canvas1 = document.createElement('div');
      canvas1.setAttribute('id', this._div_id + '1');
      canvas1.className = 'slide';
      canvas1.style.visibility = 'hidden';
      canvas1.appendChild(img1);
      o.appendChild(canvas1);
      this._canvas = new Array(canvas0, canvas1);
      this._img = new Array(img0, img1);
      this._slides[0] = this._cache(this._slides[0]);  // already cached by browser
      // See if we're using W3C opacity, MSIE filter, or just toggling visiblity
      if (typeof canvas0.style.opacity != 'undefined') {
        this._updateOpacity = this._updateOpacityW3c;
      } else if (typeof canvas0.style.filter != 'undefined') {
        this._updateOpacity = this._updateVisibility;
        if (this._check_IE_filter(canvas0, 0) && this._check_IE_filter(canvas1, 0)) {
          this._updateOpacity = this._updateOpacityMSIE;
        } else if (this._check_IE_filter(canvas0, 1) && this._check_IE_filter(canvas1, 1)) {
          this._updateOpacity = this._updateOpacityOlderMSIE;
        }
      } else if (typeof canvas0.style.MozOpacity != 'undefined') {
        this._updateOpacity = this._updateOpacityMozFF;
      } else if (typeof canvas0.style.KHTMLOpacity != 'undefined') {
        this._updateOpacity = this._updateOpacitySK;
      } else { // Opera
        this._updateOpacity = function () {};
      }
      this._slide_ready = true;
    }
  }
}

slide_show.prototype.ready = function () {
  return this._slide_ready;
}

slide_show.prototype.fade = function () {
if (this._opacity < 100) {
  this._opacity += this._opacity_step;
  this._updateOpacity(this._curr_canvas);
} else { // fade_in end
  clearInterval(this._fade_interval);
  this._fade_interval = null;
  // prepare next slide
  this._canvas_ptr = (this._canvas_ptr == 0) ? 1 : 0;
  this._slide_ptr = (this._slide_ptr < this._slides.length-1) ? this._slide_ptr+1 : 0;
  this._img[this._canvas_ptr].src = this._slides[this._slide_ptr].src;
  var objref = this;
  setTimeout(function() { objref.rotate(); }, this._pause);
}
}

// start new image fade_in
slide_show.prototype.rotate = function () {
if (this._slide_ready) {
  if (this._slide_ptr < this._slides.length-1) {
    this._cache_next_img(this._slide_ptr+1);
  }
  // prepare current canvas and start fade_in process
  this._curr_canvas = this._canvas[this._canvas_ptr];
  this._opacity = this._opacity_start;
  this._updateOpacity(this._curr_canvas);
  this._curr_canvas.style.zIndex++;
  var objref = this;
  this._fade_interval = window.setInterval(function() { objref.fade(); }, this._opacity_interval);
}
}

slide_show.prototype._process_download = function () {
  if (this._download.complete) {
    this._slide_ready = true;
    this._download = null;
  } else {
    var objref = this;
    window.setTimeout(function() { objref._process_download(); }, this._dnload_check);
  }
}

slide_show.prototype._cache_next_img = function (ptr) {
  if (ptr < this._slides.length) {
    if (typeof this._slides[ptr] == 'string') { // cache only once
      this._slide_ready = false;
      this._slides[ptr] = this._cache(this._slides[ptr]);
      this._download = this._slides[ptr];
      var objref = this;
      window.setTimeout(function() { objref._process_download(); }, this._dnload_check);
    }
  }
}

// helper functions
// turns the string into an image object
slide_show.prototype._check_IE_filter = function (obj, older) {
  // If there's not an alpha filter on the element already, add one
  if (obj.style.filter.indexOf('alpha') == -1) {
    // Attempt to preserve existing filters
    var existingFilters = '';
    if (obj.style.filter) {
      existingFilters = obj.style.filter + ' ';
    }
    obj.style.filter = existingFilters + 'alpha(opacity=' + this._opacity + ')';
  }
  if (older) {
    return (obj.style.filter.indexOf('alpha') > -1) ? 1 : 0;
  } else {
    return (obj.style.filter.alpha) ? 1 : 0;
  }
}

slide_show.prototype._cache = function (src) {
  var img = new Image();
  img.src = src;
  return img;
}

slide_show.prototype._updateVisibility = function (obj) {
  obj.style.visibility = (this._opacity > 0) ? 'visible' : 'hidden';
}

// Safari 1.2, newer Firefox and Mozilla, CSS3
slide_show.prototype._updateOpacityW3c = function (obj) {
  obj.style.opacity = this._opacity/101;
  this._updateVisibility(obj);
}

// IE/Win
slide_show.prototype._updateOpacityMSIE = function (obj) {
  obj.filters.alpha.opacity = this._opacity;
  this._updateVisibility(obj);
}

// Older IE/Win
slide_show.prototype._updateOpacityOlderMSIE = function (obj) {
  obj.style.filter = 'alpha(opacity=' + this._opacity + ')';
  this._updateVisibility(obj);
}

// Older Mozilla and Firefox
slide_show.prototype._updateOpacityMozFF = function (obj) {
  obj.style.MozOpacity = this._opacity/101;
  this._updateVisibility(obj);
}

// Safari<1.2, Konqueror
slide_show.prototype._updateOpacitySK = function (obj) {
  obj.style.KHTMLOpacity = this._opacity/101;
  this._updateVisibility(obj);
}
//}}} slide_show object end

function addEvent(obj, evType, fn){
if (obj.addEventListener){//DOM
  obj.addEventListener(evType, fn, true);
  return true;
} else if (obj.attachEvent){//IE
  var r = obj.attachEvent('on'+evType, fn);
  return r;
} else {//IE5/Mac
  obj['on' + evType] = fn;
  //return false;
}
}

