/*
 * Fading Banner, queued emergence - reversed fade-out, version 1.1
 *
 * Copyright (C) 2007 Dmitriy Khudorozhkov
 *
 * This software is provided "as-is", without any express or implied warranty.
 * In no event will the author be held liable for any damages arising from the
 * use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and must not be
 *    misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source distribution.
 *
 *  - Dmitriy Khudorozhkov, kh_dmitry2001@mail.ru
 */

function FadingBannerQ2R(parentId, type, width, height, bg, timeout)
{
  this.batches  = [];
  this.current  = 0;
  this.images   = [];
  this.parent   = document.getElementById(parentId);
  this.root     = null;
  this.timeout  = timeout || 5000;
  this.type     = (type == "vertical") ? "vertical" : "horizontal";

  while(this.parent.firstChild)
    this.parent.removeChild(this.parent.firstChild);

  return this._construct(width, height, bg);
}

FadingBannerQ2R.prototype = {

  // public methods:

  add: function(batch, imageSrc, imageWidth, imageHeight, link)
  {
    var l = this.batches.length;
    for(var i = 0; i < l; i++)
      if(this.batches[i] == batch)
        break;

    if(i == l) this.batches[l] = batch;

    if(!this.images[batch]) this.images[batch] = [];

    var l2 = this.images[batch].length;

    var imag = this.images[batch][l2] = new Object;

    imag.src    = imageSrc;
    imag.link   = link;
    imag.width  = imageWidth;
    imag.height = imageHeight;

    var top = 0, left = 0, isH = (this.type == "horizontal");

    for(i = 0; i < l2; i++)
    {
      var _img = this.images[batch][i];

      if(isH)
      {
        left += _img.width;
      }
      else
      {
        top += _img.height;
      }
    }

    var a = imag.obj = document.createElement("A");
    a.href = imag.link;
    a.target = "_blank";
    a.style.display = "none";

    var img = document.createElement("IMG");
    img.src = imag.src;
    img.id  = "fb_img_" + this.parent.id + "_" + String(batch) + "_" + String(l2);

    a.appendChild(img);
    this.root.appendChild(a);

    var is = img.style;
    is.position = "absolute";
    is.top      = top + "px";
    is.left     = left + "px";
    is.width    = imag.width;
    is.height   = imag.height;
    is.border   = "0";
    is.opacity  = 0;
    is.filter   = "alpha(opacity=0)";

    this.batches.sort(function (a, b) { return a - b; });
    this.current = this.batches[0];

    return l2 + 1;
  },

  start: function()
  {
    this.root.style.display = "block";

    this._showbatch();
  },

  // support methods follow:

  _construct: function(width, height, bg)
  {
    var banner = document.createElement("DIV");
    var bs = banner.style;

    bs.position = "relative";
    bs.top      = "0px";
    bs.left     = "0px";
    bs.width    = width + "px";
    bs.height   = height + "px";

    bs.display  = "none";
    bs.backgroundColor = bg || "#FFF";

    this.root = this.parent.appendChild(banner);

    return this;
  },

  _callLater: function(obj, func, param)
  {
    param = param || null;
    return obj ? (function() { obj[func](param); }) : (function() { func(param); });
  },

  _next: function()
  {
    var _out = function(_obj)
    {
      var _go = function(__obj)
      {
        var cur = __obj.current, l = __obj.images[cur].length;

        for(var i = 0; i < l; i++)
          __obj.images[cur][i].obj.style.display = "none";

        l = __obj.batches.length;
        for(i = 0; i < l; i++)
          if(__obj.current == __obj.batches[i])
            break;

        __obj.current = (i == l - 1) ? __obj.batches[0] : __obj.batches[i + 1];

        __obj._showbatch();
      }

      // fade-out current batch:
      var cur = _obj.current, l = _obj.images[cur].length;

      var funcs = [];
      for(var i = l - 1; i >= 0; i--)
      {
        function genF(__obj, k)
        {
          return function()
          {
            var img = __obj.images[cur][k];
            img.obj.style.display = "block";

            __obj._fade(img.obj.firstChild.id, 0, 50, 10, (k == 0 ? function() { _go(_obj); } : funcs[k - 1]));
          }
        }

        funcs[i] = genF(_obj, i);
      }

      funcs[l - 1]();
    }

    setTimeout(this._callLater(null, _out, this), this.timeout);
  },

  _showbatch: function()
  {
    var cur = this.current, l = this.images[cur].length;

    var funcs = [];
    for(var i = 0; i < l; i++)
    {
      function genF(_obj, k)
      {
        return function()
        {
          var img = _obj.images[cur][k];
          img.obj.style.display = "block";

          _obj._fade(img.obj.firstChild.id, 100, 50, 10, (k == (l - 1) ? _obj._callLater(_obj, "_next") : funcs[k + 1]));
        }
      }

      funcs[i] = genF(this, i);
    }

    funcs[0]();
  },

  _fade: function(id, destOp, rate, delta, callback)
  {
    var obj = document.getElementById(id);

    if(obj.timer) clearTimeout(obj.timer);

    var curOp = obj.filters ? obj.filters.alpha.opacity : (obj.style.opacity * 100.0);
    var direction = (curOp <= destOp) ? 1 : -1;

    delta  = Math.min(direction * (destOp - curOp), delta);
    curOp += direction * delta;

    if(obj.filters)
      obj.filters.alpha.opacity = curOp;
    else
      obj.style.opacity = curOp / 100.0;

    if(curOp != destOp)
      obj.timer = setTimeout(function() { FadingBannerQ2R.prototype._fade(id, destOp, rate, delta, callback); }, rate);
    else
      if(callback) callback();
  }
};
