/**
 * Rotator
 *
 * (c) 2009 Alexander Petrushev
 * http://a-p.narod.ru
 *
 */


// http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
//
Array.prototype.shuffle = function()
{
  var i = this.length, j, t
  while (i > 1) {
    j = Math.floor((i--) * Math.random())
    if (i != j) {
      t = this[i]
      this[i] = this[j]
      this[j] = t
    }
  }
  return this
}

function Rotator(settings)
{
  this.name = settings.name || 'partners'
  this.empty = settings.empty || '/i/d.gif'
  this.images = settings.images.shuffle() || []
  this.next = this.index = 0
  this.timeout = settings.timeout || 2500
  this.width = settings.width || 200
  this.height = settings.height || 200
  this.tbl = settings.tbl || ''
  this.path = settings.path || ''
  this.displayUrl = settings.displayUrl || false
  this.click = settings.click || false
  this.debug = false
  this.messages = []
  this.mouse = settings.mouse || false
  this.stop = false

  this.current = 0
  this.opacity = 0
  this.started = 0

  this.getNext = function () {
    return (this.index + 1) % this.images.length
  }

  this.setOpacity = function(o, opacity) {
    if (o) {
      o.style.opacity = opacity / 100
      if (o.style.filter) o.style.filter = 'alpha(opacity = ' + opacity + ')'
    }
  }

  this.pic_OnLoad = function (n, partners) {
    partners.message('ON LOAD ' + n + ', current = ' + partners.current)
    if (n == partners.current) {
      
      var o = document.getElementById(partners.name + '_pic' + n)
      if (!o) {
        partners.message('NO ELEMENT')
        return
      }
      partners.message('LOADED ' + o.src)
      if (o.src.substr(Math.max(0, o.src.length - partners.empty.length)) == partners.empty) partners.message('EMPTY ACTIVE ELEMENT')

      var delay = (new Date()).getTime() - partners.started
      setTimeout(function () { partners.fade() }, 
        Math.max(0, partners.timeout - delay))
    } else {
      var o = document.getElementById(partners.name + '_pic' + n)
      if (!o) {
        partners.message('NO ELEMENT')
        return
      }
      partners.message('LOADED ' + o.src)
    }
  }

  this.message = function (text) {
    if (this.debug) {
      this.messages.push(text)
      if (this.messages.length > 50) this.messages.shift()
      var o = document.getElementById(this.name + '_debug')
      if (o) o.innerHTML = this.messages.join('<br>')
    }
  }

  this.getIndex = function () {
    return (this.opacity < 50 || this.opacity == 100 
        ? this.index 
        : this.next);
  }

  this.OnClick = function (partners) {
    if (partners.click) {
      var href = partners.images[partners.getIndex()].href
      if (href) partners.click(href)
    }
  }

  this.OnMouseOver = function (partners, event, t) {
    partners.stop = true
    var o = document.getElementById(partners.name + '_tip')
    if (o) {
      var i = partners.getIndex()
      var x = document.body.scrollLeft + event.clientX - t.offsetLeft
      var y = document.body.scrollTop + event.clientY - t.offsetTop
      var href = partners.images[i].href
      if (href) {
        if (href.substr(0, 7) == 'http://') href = href.substr(7)
        if (href.substr(href.length - 1, 1) == '/') href = href.substr(0, href.length - 1)
      }
      var s = ''
      s += href
        + (partners.images[i].title 
          ? (href ? '<br>' : '') 
          + '<b>' + partners.images[i].title + '</b>'
          : '')
      if (s) {
        o.innerHTML = s
        o.style.left = (x + 10) + 'px'
        o.style.top = (y + 20) + 'px'
        o.style.display = ''
      }
    }
  }

  this.OnMouseOut = function (partners, event, t) {
    partners.stop = false
    var o = document.getElementById(partners.name + '_tip')
    if (o) o.style.display = 'none'
  }

  this.OnMouseMove = function (partners, event, t) {
    var o = document.getElementById(partners.name + '_tip')
    if (!o) return
    if (o.style.display == '') {
      var x = document.body.scrollLeft + event.clientX - t.offsetLeft
      var y = document.body.scrollTop + event.clientY - t.offsetTop
      o.style.left = (x + 10) + 'px'
      o.style.top = (y + 20) + 'px'
    }
  }

  this.fade = function () {
    var partners = this
    if (partners.stop) {
      setTimeout(function () {
        partners.fade()
      }, 100)
      return
    }
    var o = document.getElementById(partners.name + '_pic' + partners.current)
    var t = document.getElementById(partners.name + '_pic' + (1 - partners.current))
    if (partners.opacity < 100) {
      partners.opacity += 5
      partners.setOpacity(o, partners.opacity)
      partners.setOpacity(t, 100 - partners.opacity)
      var x = document.getElementById(partners.name + '_href')
      if (x) x.innerHTML = partners.images[(partners.opacity < 50 ? partners.index : partners.next)].href
    }
    if (partners.opacity == 100) {
      var old = partners.index
      partners.index = partners.next
      partners.next = partners.getNext()
      partners.current = 1 - partners.current
      partners.opacity = 0
      partners.started = (new Date()).getTime()
      if (old == partners.next) {
        partners.message('start fade() for ' + old)
        setTimeout(function () { partners.fade() }, partners.timeout)
      } else {
        if (t) {
          partners.message('t.src = ' + partners.images[partners.next].img)
          t.src = partners.path + partners.images[partners.next].img
        } else {
          partners.message('cannot find t!')
        }
      }
    } else
      setTimeout(function () { partners.fade() }, 20)
  }

  this.startup = function () {
    (new Image()).src = this.empty   // preload
    document.write(''
      + (this.debug 
        ? this.images[this.index].img
        : '')
      + '<table ' + this.tbl + '>'
      + '<tr>'
      + '<td><div style="position: relative; width: ' + this.width + 'px; height: '
      + this.height + 'px'
      + (this.click 
        ? '; cursor: pointer" onclick="' + this.name + '.OnClick(' + this.name + ')'
        : '') + '"'
      + (this.mouse
        ? ' onmouseover="' + this.name + '.OnMouseOver(' + this.name + ', event, this)"'
        + ' onmouseout="' + this.name + '.OnMouseOut(' + this.name + ', event, this)"'
        + ' onmousemove="' + this.name + '.OnMouseMove(' + this.name + ', event, this)"'
        : '')
      + '>'
      + '<img id="' + this.name + '_pic0" style="opacity: 0; _filter: alpha(opacity = 0); position: absolute; top: 0; left: 0" src="'
      + this.path + this.images[this.index].img + '" '
      + 'onload="' + this.name + '.pic_OnLoad(0, ' + this.name + ')" alt="" width=' 
      + this.width + ' height=' + this.height + ' />'
      + '<img id="' + this.name + '_pic1" style="opacity: 0; _filter: alpha(opacity = 0); position: absolute; top: 0; left: 0" src="'
      + this.empty + '" '
      + 'onload="' + this.name + '.pic_OnLoad(1, ' + this.name + ')" alt="" width='
      + this.width + ' height=' + this.height + ' />'
      + '<div id="' + this.name + '_tip" style="display: none; background: #ffc; font-size: 85%; border: 1px solid #ccc; padding: 1px 2px; position: absolute; top: 0; left: 0"></div>'
      + '</div></td>'
      + '</tr>'
      + (this.displayUrl 
        ? '<tr><td align=center id="' + this.name + '_href"></td></tr>'
        : '')
      + (this.debug
        ? '<tr><td style="font-size: 80%" nowrap id="' + this.name + '_debug"></td></tr>'
        : '')
      + '</table>')
  }
}

Rotator.create = function (settings) {
  name = settings.name || 'partners'
  window[name] = new Rotator(settings)
  window[name].startup()
}
