/**************************************
* Copyright (c) 2002 Blackfire Internet Solutions, Inc. All rights reserved.
*
* Dependencies
* ------------
* browser.js
**************************************/

var _bisAnimation = // used by bisAnimation
{
  stop      : false,
  curFrame  : null,
  frames    : null
}

function bisButton(name, type, label, value, style)
{
  // Default Parameters
  if (!type)
    type = "button";
  if (!label && type == "submit")
    label = "Submit Query";
  if (!value && type == "submit")
    value = type;
  if (!style)
    style = new bisStyle;

  // Properties
  this.name;
  this.type;
  this.label;
  this.value;
  this.size;
  this.style; // bisStyle object

  // Methods
  this.isEmpty  = bisButtonIsEmpty;
  this.toString = bisButtonString;

  // Default Values
  this.name   = name;
  this.type   = type;
  this.label  = label;
  this.value  = value;
  this.style  = style;
}

function bisButtonIsEmpty()
{
  return typeof(this.label) == "undefined" || this.label == "";
}

function bisButtonString()
{
  var tokens = new Array;

  if (!this.isEmpty())
  {
    tokens[++tokens.length - 1] = "<button";
    if (this.name)
      tokens[++tokens.length - 1] = " name=" + this.name;
    if (!this.style.isEmpty())
      tokens[++tokens.length - 1] = " " + this.style;
    if (this.type)
      tokens[++tokens.length - 1] = " type=" + this.type;
    if (this.value)
      tokens[++tokens.length - 1] = " value='" + this.value + "'";
    tokens[++tokens.length - 1] = ">";

    tokens[++tokens.length - 1] = this.label;

    tokens[++tokens.length - 1] = "</button>";
  }

  return tokens.join("");
}

function bisRadio(name, value, isChecked, style)
{
  // Default Parameters
  if (!style)
    style = new bisStyle;

  // Properties
  this.name;
  this.value;
  this.isChecked; // boolean
  this.style;     // bisStyle object
  this.event;     // bisEvent object

  // Methods
  this.isEmpty  = bisRadioIsEmpty;
  this.toString = bisRadioString;

  // Default Values
  this.name       = name;
  this.value      = value;
  this.isChecked  = isChecked;
  this.style      = style;
  this.event      = new bisEvent;
}

function bisRadioIsEmpty()
{
  return false;
}

function bisRadioString()
{
  var tokens = new Array;

  if (!this.isEmpty())
  {
    tokens[++tokens.length - 1] = "<input type=radio";
    if (!this.style.isEmpty())
      tokens[++tokens.length - 1] = " " + this.style;
    if (this.name)
      tokens[++tokens.length - 1] = " name=" + this.name;
    if (this.value)
      tokens[++tokens.length - 1] = " value='" + this.value + "'";
    if (this.isChecked)
      tokens[++tokens.length - 1] = " checked";
    if (!this.event.isEmpty())
      tokens[++tokens.length - 1] = " " + this.event;
    tokens[++tokens.length - 1] = ">";
  }

  return tokens.join("");
}

function bisCheckBox(name, value, isChecked, style)
{
  // Default Parameters
  if (!style)
    style = new bisStyle;

  // Properties
  this.name;
  this.value;
  this.isChecked; // boolean
  this.style;     // bisStyle object
  this.event;     // bisEvent object

  // Methods
  this.isEmpty  = bisCheckBoxIsEmpty;
  this.toString = bisCheckBoxString;

  // Default Values
  this.name       = name;
  this.value      = value;
  this.isChecked  = isChecked;
  this.style      = style;
  this.event      = new bisEvent;
}

function bisCheckBoxIsEmpty()
{
  return false;
}

function bisCheckBoxString()
{
  var tokens = new Array;

  if (!this.isEmpty())
  {
    tokens[++tokens.length - 1] = "<input type=checkbox";
    if (!this.style.isEmpty())
      tokens[++tokens.length - 1] = " " + this.style;
    if (this.name)
      tokens[++tokens.length - 1] = " name=" + this.name;
    if (this.value)
      tokens[++tokens.length - 1] = " value='" + this.value + "'";
    if (this.isChecked)
      tokens[++tokens.length - 1] = " checked";
    if (!this.event.isEmpty())
      tokens[++tokens.length - 1] = " " + this.event;
    tokens[++tokens.length - 1] = ">";
  }

  return tokens.join("");
}

function bisTextBox(name, text, numRows, numCols, style)
{
  // Default Parameters
  if (!numRows)
    numRows = 5;
  if (!numCols)
    numCols = 80;
  if (!style)
    style = new bisStyle;

  // Properties
  this.name;
  this.text;
  this.numRows;
  this.numCols;
  this.style;

  // Methods
  this.isEmpty  = bisTextBoxIsEmpty;
  this.toString = bisTextBoxString;

  // Default Values
  this.name     = name;
  this.text     = text;
  this.numRows  = numRows;
  this.numCols  = numCols;
  this.style    = style;
}

function bisTextBoxIsEmpty()
{
  return !this.numRows || !this.numCols;
}

function bisTextBoxString()
{
  var tokens = new Array;

  if (!this.isEmpty())
  {
    tokens[++tokens.length - 1] = "<textarea";
    if (!this.style.isEmpty())
      tokens[++tokens.length - 1] = " " + this.style;
    if (this.name)
      tokens[++tokens.length - 1] = " name=" + this.name;
    if (this.numRows)
      tokens[++tokens.length - 1] = " rows=" + this.numRows;
    if (this.numCols)
      tokens[++tokens.length - 1] = " cols=" + this.numCols;
    tokens[++tokens.length - 1] = ">";
    if (this.text)
      tokens[++tokens.length - 1] = this.text;
    tokens[++tokens.length - 1] = "</textarea>";
  }

  return tokens.join("");
}

function bisOption(displayText, value, isSelected)
{
  // Default Parameters
  if (!value)
    value = displayText;

  // Properties
  this.displayText;
  this.value;
  this.isSelected;

  // Methods
  this.isEmpty  = bisOptionIsEmpty;
  this.toString = bisOptionString;

  // Default Values
  this.displayText  = displayText;
  this.value        = value;
  this.isSelected   = isSelected;
}

function bisOptionIsEmpty()
{
  return typeof(this.displayText) == "undefined";
}

function bisOptionString()
{
  var tokens = new Array;

  if (!this.isEmpty())
  {
    tokens[++tokens.length - 1] = "<option";
    if (this.value)
      tokens[++tokens.length - 1] = " value='" + this.value + "'";
    if (this.isSelected)
      tokens[++tokens.length - 1] = " selected";
    tokens[++tokens.length - 1] = ">";
    tokens[++tokens.length - 1] = this.displayText;
  }

  return tokens.join("");
}

function bisSelect(name, options, style)
{
  // Default Parameters
  if (!options)
    options = new Array;
  else
    if (!options[0])
      options = new Array(options);

  if (!style)
    style = new bisStyle;

  // Properties
  this.name;        // string
  this.options;     // bisOption object collection
  this.isMultiple;  // boolean
  this.style;       // bisStyle object
  this.event;       // bisEvent object

  // Methods
  this.isEmpty      = bisSelectIsEmpty;
  this.toString     = bisSelectString;
  this.createOption = bisSelectCreateOption;
  this.insertOption = bisSelectInsertOption;

  // Default Values
  this.name     = name;
  this.options  = options;
  this.style    = style;
  this.event    = new bisEvent;
}

function bisSelectIsEmpty()
{
  return this.options.length == 0;
}

function bisSelectString()
{
  var tokens = new Array;

  if (!this.isEmpty())
  {
    tokens[++tokens.length - 1] = "<select";
    if (!this.style.isEmpty())
      tokens[++tokens.length - 1] = " " + this.style;
    if (this.name)
      tokens[++tokens.length - 1] = " name=" + this.name;
    if (this.isMultiple)
      tokens[++tokens.length - 1] = " multiple";
    if (!this.event.isEmpty())
      tokens[++tokens.length - 1] = " " + this.event;
    tokens[++tokens.length - 1] = ">";

    for (var i = 0; i < this.options.length; ++i)
      tokens[++tokens.length - 1] = this.options[i];

    tokens[++tokens.length - 1] = "</select>";
  }

  return tokens.join("");
}

function bisSelectCreateOption(displayText, value, isSelected)
{
  var option = new bisOption(displayText, value, isSelected);

  this.insertOption(option);

  return option;
}

function bisSelectInsertOption(option)
{
  this.options[++this.options.length - 1] = option;
}

function bisInputText(name, value, size, style)
{
  // Default parameters
  if (!style)
    style = new bisStyle;

  // Properties
  this.name;
  this.value;
  this.size;
  this.style;

  // Methods
  this.isEmpty  = bisInputTextIsEmpty;
  this.toString = bisInputTextString;

  // Default values
  this.name   = name;
  this.value  = value;
  this.size  = size;
  this.style  = style;
}

function bisInputTextIsEmpty()
{
  return (typeof(this.name)   == "undefined" || !this.name) &&
         (typeof(this.value)  == "undefined");
}

function bisInputTextString()
{
  var tokens = new Array;

  if (!this.isEmpty())
  {
    tokens[++tokens.length - 1] = "<input type=text";
    if (!this.style.isEmpty())
      tokens[++tokens.length - 1] = " " + this.style;
    if (typeof(this.value) != "undefined")
      tokens[++tokens.length - 1] = " value='" + this.value + "'";
    if (this.name)
      tokens[++tokens.length - 1] = " name='" + this.name + "'";
    if (this.size)
      tokens[++tokens.length - 1] = " size=" + this.size;
    tokens[++tokens.length - 1] = ">";
  }

  return tokens.join("");
}

function bisListItem(object, style)
{
  // Default parameters
  if (!style)
    style = new bisStyle;

  // Properties
  this.object;
  this.style;

  // Methods
  this.toString = bisListItemString;
  this.isEmpty  = bisListItemIsEmpty;

  // Default values
  this.object = object;
  this.style  = style;
}

function bisListItemString()
{
  var tokens = new Array;
  
  if (!this.isEmpty())
  {
    tokens[++tokens.length - 1] = "<li";
    if (!this.style.isEmpty())
      tokens[++tokens.length - 1] = " " + this.style;
    tokens[++tokens.length - 1] = ">";
    tokens[++tokens.length - 1] = this.object;
    tokens[++tokens.length - 1] = "</li>";
  }
  
  return tokens.join("");
}

function bisListItemIsEmpty()
{
  return typeof(this.object) == "undefined" || !this.object;
}

function bisUnorderedList(bullet, style)
{
  // Default parameters
  if (!bullet)
    bullet = "square";
  if (!style)
    style = new bisStyle;

  // Properties
  this.bullet;  // 'disc', 'circle', 'square'
  this.style;
  this.items;   // array of bisListItem objects

  // Methods
  this.toString = bisUnorderedListString;
  this.isEmpty  = bisUnorderedListIsEmpty;
  this.addItem  = bisUnorderedListAddItem;

  // Default values
  this.bullet = bullet;
  this.style  = style;
  this.items  = new Array;
}

function bisUnorderedListString()
{
  var tokens = new Array;

  if (!this.isEmpty())
  {
    tokens[++tokens.length - 1] = "<ul";
    if (this.bullet)
      tokens[++tokens.length - 1] = " type=" + this.bullet;
    if (!this.style.isEmpty())
      tokens[++tokens.length - 1] = " " + this.style;
    tokens[++tokens.length - 1] = ">";
    for (var i = 0; i < this.items.length; ++i)
      tokens[++tokens.length - 1] = this.items[i].toString();
    tokens[++tokens.length - 1] = "</ul>";
  }

  return tokens.join("");
}

function bisUnorderedListIsEmpty()
{
  return this.items.length == 0;
}

function bisUnorderedListAddItem(object, style)
{
  this.items[++this.items.length - 1] = new bisListItem(object, style);
}

function bisParagraph(object, style)
{
  // Default values
  if (!style)
    style = new bisStyle;

  // Define properties for this object.
  this.object = object; // any object that can be translated into HTML code
  this.style = style;   // bisStyle

  // Define methods for this object.
  this.toString = bisParagraphString;
  this.isEmpty  = bisParagraphIsEmpty;
}

function bisParagraphString()
{
  var tokens = new Array;

  if (!this.isEmpty())
  {
    tokens[++tokens.length - 1] = "<p";
    if (!this.style.isEmpty())
      tokens[++tokens.length - 1] = " " + this.style;
    tokens[++tokens.length - 1] = ">";
    if (typeof(this.object) != "undefined")
      tokens[++tokens.length - 1] = this.object;
    tokens[++tokens.length - 1] = "</p>";
  }

  return tokens.join("");
}

function bisParagraphIsEmpty()
{
  return typeof(this.object) == "undefined";
}

function bisDiv(object, style)
{
  // Default parameters
  if (!style)
    style = new bisStyle;

  // Define properties for this object.
  this.object = object;       // any object that can be translated into HTML code
  this.style = style;         // bisStyle
  this.event = new bisEvent;
  this.id;

  // Define methods for this object.
  this.toString   = bisDivString;
  this.isEmpty    = bisDivIsEmpty;
  this.begin      = bisDivBegin;
  this.end        = bisDivEnd;
  this.fetchById  = bisDivFetchById;

  // Default property values.
}

function bisDivString()
{
  var tokens = new Array;

  if (!this.isEmpty())
  {
    tokens[++tokens.length - 1] = this.begin();
    tokens[++tokens.length - 1] = this.object;
    tokens[++tokens.length - 1] = this.end();
  }

  return tokens.join("");
}

function bisDivIsEmpty()
{
  return typeof(this.object) == "undefined";
}

function bisDivBegin()
{
  var tokens = new Array;

  tokens[++tokens.length - 1] = "<div";
  if (!this.style.isEmpty())
    tokens[++tokens.length - 1] = " " + this.style;
  if (this.id)
  {
    tokens[++tokens.length - 1] = " name='" + this.id + "'";
    tokens[++tokens.length - 1] = " id='" + this.id + "'";
  }
  if (!this.event.isEmpty())
    tokens[++tokens.length - 1] = " " + this.event;
  tokens[++tokens.length - 1] = ">";
  if (isBrowserNS4() && !this.style.isEmpty())
    tokens[++tokens.length - 1] = this.style.begin();

  return tokens.join("");
}

function bisDivEnd()
{
  var tokens = new Array;

  if (isBrowserNS4() && !this.style.isEmpty())
    tokens[++tokens.length - 1] = this.style.end();
  tokens[++tokens.length - 1] = "</div>";

  return tokens.join("");
}

function bisDivFetchById()
{
  return isBrowserNS4() ? "document.ids." + this.id : "document.getElementById('" + this.id + "')";
}

function bisSpan(object, style)
{
  // Default parameters
  if (!style)
    style = new bisStyle;

  // Properties
  this.object;
  this.style;

  // Methods
  this.toString = bisSpanString;
  this.isEmpty  = bisSpanIsEmpty;

  // Default Values
  this.object = object;
  this.style  = style;
}

function bisSpanString()
{
  var tokens = new Array;

  if (!this.isEmpty())
  {
    tokens[++tokens.length - 1] = "<span";
    if (!this.style.isEmpty() && !isBrowserNS4())
      tokens[++tokens.length - 1] = " " + this.style;
    tokens[++tokens.length - 1] = ">";

    if (isBrowserNS4() && !this.style.isEmpty())
      tokens[++tokens.length - 1] = this.style.begin();
    tokens[++tokens.length - 1] = this.object;
    if (isBrowserNS4() && !this.style.isEmpty())
      tokens[++tokens.length - 1] = this.style.end();
    tokens[++tokens.length - 1] = "</span>";
  }

  return tokens.join("");
}

function bisSpanIsEmpty()
{
  return typeof(this.object) == "undefined" || !this.object;
}

function bisHeader(level, object, style)
{
  // Default Parameters
  if (!style)
    style = new bisStyle;

  // Define properties for this object.
  this.level;         // 0-6
  this.object;        // object that can be tansposed into HTML text
  this.style;

  // Define methods for this object.
  this.toString = bisHeaderString;
  this.isEmpty  = bisHeaderIsEmpty;

  // Default values
  this.level  = level;
  this.object = object;
  this.style  = style;
}

function bisHeaderString()
{
  var tokens = new Array();

  if (!this.isEmpty())
  {
    tokens[++tokens.length - 1] = "<h" + this.level;

    if (!this.style.isEmpty())
      tokens[++tokens.length - 1] = " " + this.style;

    tokens[++tokens.length - 1] = ">";
    tokens[++tokens.length - 1] = this.object;
    tokens[++tokens.length - 1] = "</h" + this.level + ">";
  }

  return tokens.join("");
}

function bisHeaderIsEmpty()
{
  return this.level == null;
}

function bisString(string)
{
  // Default values

  // Define properties for this object.
  this.font = new bisFont;
  this.text = string;

  // Define methods for this object.
  this.toString = bisStringString;  // converts this object into an inline type style string
  this.isEmpty  = bisStringIsEmpty; // determines if this object is empty
}

function bisStringString()
{
  var tokens = new Array();

  if (!this.isEmpty())
  {
    if (this.font && !this.font.isEmpty())
      tokens[++tokens.length - 1] = this.font.begin();
    tokens[++tokens.length - 1] = this.text;
    if (this.font && !this.font.isEmpty())
      tokens[++tokens.length - 1] = this.font.end();
  }

  return tokens.join("");
}

function bisStringIsEmpty()
{
  return !this.text || this.text == "";
}

function bisFont(family, color, size, weight, style)
{
  // Default values

  // Define properties for this object.
  this.family = family; // font name or family
  this.size   = size;   // absolute(point size); relative('smaller','larger')
  this.color  = color;  // color name or #rgb-hexvalue
  this.weight = weight; // absolute(100-700) [400 is normal]; relative('bolder','lighter')
  this.style  = style;  // 'italic','oblique'

  // Define methods for this object.
  this.toString = bisFontString;  // converts this object into an inline type style string
  this.isEmpty  = bisFontIsEmpty; // determines if this object is empty
  this.js       = bisFontJS;      // outputs javascript code as a string that applies this object to the specified object name.
  this.begin    = bisFontBegin;   // returns opening HTML tags
  this.end      = bisFontEnd;   // returns closing HTML tags
}

function bisFontString()
{
  var tokens = new Array();

  if (!this.isEmpty())
  {
    if (this.family)
      tokens[++tokens.length - 1] = "font-family:" + this.family;
    if (this.size)
      tokens[++tokens.length - 1] = "font-size:" + this.size;
    if (this.color)
      tokens[++tokens.length - 1] = "color:" + this.color;
    if (this.weight)
      tokens[++tokens.length - 1] = "font-weight:" + this.weight;
    if (this.style)
      tokens[++tokens.length - 1] = "font-style:" + this.style;
  }

  return tokens.join(";");
}

function bisFontIsEmpty()
{
  return  (!this.family  || this.family == "")  &&
          (!this.size    || this.size == ""  )  &&
          (!this.color   || this.color == "" )  &&
          (!this.weight  || this.weight == "")  &&
          (!this.style   || this.style == "");
}

function bisFontJS(object_name)
{
  var statements = new Array();

  if (!this.isEmpty())
  {
    if (this.family)
      statements[++statements.length - 1] = object_name + ".style.fontFamily='" + this.family + "'";
    if (this.size)
      statements[++statements.length - 1] = object_name + ".style.fontSize='" + this.size + "'";
    if (this.color)
      statements[++statements.length - 1] = object_name + ".style.color='" + this.color + "'";
    if (this.weight)
      statements[++statements.length - 1] = object_name + ".style.fontWeight='" + this.weight + "'";
    if (this.style)
      statements[++statements.length - 1] = object_name + ".style.fontStyle='" + this.style + "'";
  }

  return statements.join(";");
}

function bisFontBegin()
{
  var html = new Array;

  if (!this.isEmpty())
  {
    if (this.family || this.size || this.color)
      html[++html.length - 1] = "<font";
    if (this.family && this.family != "")
      html[++html.length - 1] = " face='" + this.family + "'";
    if (this.size && this.size != "")
      if (!isBrowserNS4())
        html[++html.length - 1] = " size='" + this.size + "'";
      else
        if (isNaN(this.size))
          html[++html.length - 1] = " size='" + (this.size == "smaller" ? "-1" : "+1") + "'";
        else
          html[++html.length - 1] = " point-size='" + (this.size - 3) + "'";
    if (this.color && this.color != "")
      html[++html.length - 1] = " color='" + this.color + "'";
    if (this.family || this.size || this.color)
      html[++html.length - 1] = ">";
    if (this.weight && this.weight == "bolder")
      html[++html.length - 1] = "<b>";
    if (this.style && this.style == "italic")
      html[++html.length - 1] = "<i>";
  }

  return html.join("");
}

function bisFontEnd()
{
  var html = new Array;

  if (!this.isEmpty())
  {
    if (this.weight && this.weight == "bolder")
      html[++html.length - 1] = "</b>";
    if (this.style && this.style == "italic")
      html[++html.length - 1] = "</i>";
    if (this.family || this.size || this.color)
      html[++html.length - 1] = "</font>";
  }

  return html.join("");
}

function bisBorder(style, color, width, side)
{
  // Default Parameters
  if (!width)
    width = "medium";

  // Properties
  this.style;   // 'none', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset'
  this.color;   // color name or #rgb-hexvalue
  this.width;   // string: number with units or 'thin', 'medium', or 'thick'
  this.side;    // null - all sides; 'right', 'left', 'top', or 'bottom'
  this.padding;

  // Methods
  this.toString   = bisBorderString;  // converts this object into an inline type style string
  this.isEmpty    = bisBorderIsEmpty; // determines if this object is empty
  this.js         = bisBorderJS;      // outputs javascript code that applies this object to the specified object name
  this.duplicate  = bisBorderDuplicate;

  // Default Values
  this.style    = style;
  this.color    = color;
  this.width    = width;
  this.side     = side;
  this.padding  = { top:0, bottom:0, left:0, right:0 };
}

function bisBorderDuplicate()
{
  var border = new bisBorder;

  border.style          = this.style;
  border.color          = this.color;
  border.width          = this.width;
  border.padding.top    = this.padding.top;
  border.padding.bottom = this.padding.bottom;
  border.padding.left   = this.padding.left;
  border.padding.right  = this.padding.right;

  return border;
}

function bisBorderString()
{
  var direction = !this.side ? "-" : "-" + this.side + "-";
  var tokens = new Array();

  if (!this.isEmpty())
  {
    if (typeof(this.style) != "undefined")
      tokens[++tokens.length - 1] = "border" + direction + "style:" + this.style;
    if (typeof(this.color) != "undefined")
      tokens[++tokens.length - 1] = "border" + direction + "color:" + this.color;
    if (typeof(this.width) != "undefined")
      tokens[++tokens.length - 1] = "border" + direction + "width:" + this.width;
    if (this.padding)
    {
      if (this.padding.top)
        tokens[++tokens.length - 1] = "padding-top:" + this.padding.top;
      if (this.padding.bottom)
        tokens[++tokens.length - 1] = "padding-bottom:" + this.padding.bottom;
      if (this.padding.left)
        tokens[++tokens.length - 1] = "padding-left:" + this.padding.left;
      if (this.padding.right)
        tokens[++tokens.length - 1] = "padding-right:" + this.padding.right;
    }
  }

  return tokens.join(";");
}

function bisBorderIsEmpty()
{
  return typeof(this.width) == "undefined";
}

function bisBorderJS(object_name)
{
  var statements = new Array();

  if (!this.isEmpty())
  {
    var direction = !this.side ? "" : this.side;

    if (direction != "")
    {
      var chars = direction.split("");

      chars[0] = chars[0].toUpperCase();
      direction = chars.join("");
    }

    if (typeof(this.style) != "undefined")
      statements[++statements.length - 1] = object_name + ".style.border" + direction + "Style='" + this.style + "'";
    if (typeof(this.color) != "undefined")
      statements[++statements.length - 1] = object_name + ".style.border" + direction + "Color='" + this.color + "'";
    if (typeof(this.width) != "undefined")
      statements[++statements.length - 1] = object_name + ".style.border" + direction + "Width='" + this.width + "'";
  }

  return statements.join(";");
}

function bisBackground()
{
  // Default values

  // Define object properties and set their values.
  this.color;  // color name or #rgb-hexvalue

  // Define methods for this object.
  this.toString = bisBackgroundString;  // converts this object into an inline type style string
  this.isEmpty  = bisBackgroundIsEmpty; // determines if this object is empty
  this.js       = bisBackgroundJS;      // outputs javascript code as a string that applies this object to the specified object name.
}

function bisBackgroundString()
{
  var tokens = new Array();

  if (typeof(this.color) != "undefined")
    tokens[++tokens.length - 1] = "background-color:" + this.color;

  return tokens.join(";");
}

function bisBackgroundIsEmpty()
{
  return typeof(this.color) == "undefined";
}

function bisBackgroundJS(object_name)
{
  var statements = new Array();

  if (!this.isEmpty())
    if (typeof(this.color) != "undefined")
      if (!isBrowserNS4())
        statements[++statements.length - 1] = object_name + ".style.backgroundColor='" + this.color + "'";
      else
        statements[++statements.length - 1] = object_name + ".bgColor='" + this.color + "'";

  return statements.join(";");
}

function bisStyle()
{
  // Default parameters

  // Properties
  this.font;        // bisFont object
  this.border;      // bisBorder object
  this.bg;          // bisBackground object
  this.width;       // string
  this.height;      // string
  this.align;       // string: 'left', 'center', 'right'
  this.cursor;      // string: 'hand'
  this.position;    // string: 'absolute','relative'
  this.top;         // number: top position in pixels
  this.left;        // number: left position in pixels
  this.visibility;  // string: 'visible','hidden' [IE]; 'show','hidden' [NS]
  this.decoration;  // string: 'none','underline','overline','line-through','blink'
  this.render;      // true - object is rendered; false - object is not rendered

  // Methods
  this.toString   = bisStyleString;   // converts this object into an inline type style string
  this.isEmpty    = bisStyleIsEmpty;  // determines if this object is empty
  this.js         = bisStyleJS;       // outputs javascript code as a string that applies this object to the specified object name.
  this.begin      = bisStyleBegin;
  this.end        = bisStyleEnd;
  this.duplicate  = bisStyleDuplicate;

  // Default values
  this.font       = new bisFont;
  this.border     = new bisBorder;
  this.bg         = new bisBackground;
  this.position   = "relative";
  this.top        =
  this.left       = 0;
}

function bisStyleDuplicate()
{
  var style = new bisStyle;

  style.font        = this.font;
  style.border      = this.border.duplicate();
  style.bg          = this.bg;
  style.width       = this.width;
  style.height      = this.height;
  style.align       = this.align;
  style.cursor      = this.cursor;
  style.position    = this.position;
  style.top         = this.top;
  style.left        = this.left;
  style.visibility  = this.visibility;
  style.decoration  = this.decoration;
  style.render      = this.render;

  return style;
}

function bisStyleBegin()
{
  var tokens = new Array;

  if (!this.isEmpty())
  {
    if (!this.font.isEmpty())
      tokens[++tokens.length - 1] = this.font.begin();
    if (this.align == "center")
      tokens[++tokens.length - 1] = "<center>";
  }

  return tokens.join("");
}

function bisStyleEnd()
{
  var tokens = new Array;

  if (!this.isEmpty())
  {
    if (this.align == "center")
      tokens[++tokens.length - 1] = "</center>";
    if (!this.font.isEmpty())
      tokens[++tokens.length - 1] = this.font.end();
  }

  return tokens.join("");
}

function bisStyleString()
{
  var tokens = new Array();

  if (!this.isEmpty())
  {
    if (!isBrowserNS4())
    {
      if (this.font && !this.font.isEmpty())
        tokens[++tokens.length - 1] = this.font;
      if (typeof(this.align) != "undefined")
        tokens[++tokens.length - 1] = "text-align:" + this.align;
    }

    if (typeof(this.decoration) != "undefined")
      tokens[++tokens.length - 1] = "text-decoration:" + this.decoration;
    if (this.border && !this.border.isEmpty())
      tokens[++tokens.length - 1] = this.border;
    if (this.bg && !this.bg.isEmpty())
      tokens[++tokens.length - 1] = this.bg;
    if (typeof(this.width) != "undefined")
      tokens[++tokens.length - 1] = "width:" + this.width;
    if (typeof(this.height) != "undefined")
      tokens[++tokens.length - 1] = "height:" + this.height;
    if (typeof(this.cursor) != "undefined")
      tokens[++tokens.length - 1] = "cursor:" + this.cursor;
    if (typeof(this.visibility) != "undefined")
      tokens[++tokens.length - 1] = "visibility:" + this.visibility;
    if (typeof(this.render) != "undefined")
      tokens[++tokens.length - 1] = "display:" + (this.render ? "block" : "none");
    if (this.top || this.left)
    {
      if (this.top)
        tokens[++tokens.length - 1] = "top:" + this.top;
      if (this.left)
        tokens[++tokens.length - 1] = "left:" + this.left;
      if (typeof(this.position) != "undefined")
        tokens[++tokens.length - 1] = "position:" + this.position;
    }
  }

  return tokens.length == 0 ? "" : "style='" + tokens.join(";") + "'";
}

function bisStyleIsEmpty()
{
  return  typeof(this.width)      == "undefined"  &&
          typeof(this.height)     == "undefined"  &&
          typeof(this.align)      == "undefined"  &&
          typeof(this.cursor)     == "undefined"  &&
          typeof(this.visibility) == "undefined"  &&
          typeof(this.decoration) == "undefined"  &&
          typeof(this.render)     == "undefined"  &&
          this.font.isEmpty()                     &&
          this.border.isEmpty()                   &&
          this.bg.isEmpty()                       &&
          !this.top                               &&
          !this.left;
}

function bisStyleJS(object_name)
{
  var statements = new Array();

  if (!this.isEmpty())
    if (isBrowserNS4())
    {
      if (typeof(this.bg) != "undefined" && !this.bg.isEmpty())
        statements[++statements.length - 1] = this.bg.js(object_name);
      if (typeof(this.visibility) != "undefined")
        statements[++statements.length - 1] = object_name + ".visibility='" + this.visibility + "'";
    }
    else
    {
      if (typeof(this.font) != "undefined" && !this.font.isEmpty())
        statements[++statements.length - 1] = this.font.js(object_name);
      if (typeof(this.border) != "undefined" && !this.border.isEmpty())
        statements[++statements.length - 1] = this.border.js(object_name);
      if (typeof(this.bg) != "undefined" && !this.bg.isEmpty())
        statements[++statements.length - 1] = this.bg.js(object_name);
      if (typeof(this.width) != "undefined")
        statements[++statements.length - 1] = object_name + ".style.width='" + this.width + "'";
      if (typeof(this.height) != "undefined")
        statements[++statements.length - 1] = object_name + ".style.height='" + this.height + "'";
      if (typeof(this.align) != "undefined")
        statements[++statements.length - 1] = object_name + ".style.textAlign='" + this.align + "'";
      if (typeof(this.cursor) != "undefined")
        statements[++statements.length - 1] = object_name + ".style.cursor='" + this.cursor + "'";
      if (typeof(this.decoration) != "undefined")
        statements[++statements.length - 1] = object_name + ".style.textDecoration='" + this.decoration + "'";
      if (typeof(this.render) != "undefined")
        statements[++statements.length - 1] = object_name + ".style.display='" + (this.render ? "block" : "none") + "'";
      if (this.top || this.left)
      {
        if (this.top)
          statements[++statements.length - 1] = object_name + ".style.top=" + this.top;
        if (this.left)
          statements[++statements.length - 1] = object_name + ".style.left=" + this.left;
        if (typeof(this.position) != "undefined")
          statements[++statements.length - 1] = object_name + ".style.position='" + this.position + "'";
      }
    }

  return statements.join(";");
}

function bisEvent()
{
  // Default values

  // Define object properties and set their values.
  this.onblur;      // string
  this.onclick;     // string
  this.onload;      // string
  this.onmouseout;  // string
  this.onmouseover; // string
  this.onsubmit;    // string
  this.onchange;    // string

  // Define methods for this object.
  this.toString               = bisEventString;
  this.isEmpty                = bisEventIsEmpty;
  this.addJavaScriptStatement = bisEventAddJavaScriptStatement;
}

function bisEventString()
{
  var tokens = new Array();

  if (!this.isEmpty())
  {
    if (this.onclick)
      tokens[++tokens.length - 1] = "onclick=" + this.onclick;
    if (this.onmouseover)
      tokens[++tokens.length - 1] = "onmouseover=" + this.onmouseover;
    if (this.onmouseout)
      tokens[++tokens.length - 1] = "onmouseout=" + this.onmouseout;
    if (this.onload)
      tokens[++tokens.length - 1] = "onload=" + this.onload;
    if (this.onblur)
      tokens[++tokens.length - 1] = "onblur=" + this.onblur;
    if (this.onsubmit)
      tokens[++tokens.length - 1] = "onsubmit='return " + this.onsubmit + "'";
    if (this.onchange)
      tokens[++tokens.length - 1] = "onchange=" + this.onchange;
  }

  return tokens.join(" ");
}

function bisEventIsEmpty()
{
  return (!this.onclick     || this.onclick == "")      &&
         (!this.onmouseover || this.onmouseover == "")  && 
         (!this.onload      || this.onload == "")       && 
         (!this.onblur      || this.onblur == "")       && 
         (!this.onsubmit    || this.onsubmit == "")     && 
         (!this.onchange    || this.onchange == "")     && 
         (!this.onmouseout  || this.onmouseout == "");
} 

function bisEventAddJavaScriptStatement(eventType, jsStatement)
{
  var eventHandler = eval("this." + eventType);

  if (eventHandler && eventHandler != "")
  {
    var jsStatements = eventHandler.split('"');
    var prevStatement = jsStatements[jsStatements.length == 1 ? 0 : 1];

    jsStatement = prevStatement + ";" + jsStatement;
  }

  eventHandler = '"' + jsStatement + '"';
  eval("this." + eventType + "= eventHandler");
}

function bisCell(object, style)
{
  // Default parameters
  if (!style)
    style = new bisStyle;

  // Properties
  this.object;
  this.id;
  this.colspan; // number
  this.style;   // bisStyle object
  this.event;   // bisEvent object

  // Methods
  this.toString = bisCellString;
  this.isEmpty  = bisCellIsEmpty;

  // Default values
  this.object   = object;
  this.colspan  = 1;
  this.style    = style;
  this.event    = new bisEvent;
}

function bisCellString()
{
  var tokens = new Array();

  tokens[++tokens.length - 1] = "<td";
  if (this.id)
  {
    tokens[++tokens.length - 1] = " id=" + this.id;
    tokens[++tokens.length - 1] = " name=" + this.id;
  }
  if (this.style && !this.style.isEmpty())
    if (!isBrowserNS4())
      tokens[++tokens.length - 1] = " " + this.style;
    else
    {
      if (!this.style.border.isEmpty())
        tokens[++tokens.length - 1] = " style=" + this.style.border;
      if (this.style.width)
        tokens[++tokens.length - 1] = " width=" + (parseInt(this.style.width) + Math.ceil(this.style.width * 0.1));
      if (this.style.align)
        tokens[++tokens.length - 1] = " align=" + this.style.align;
      if (!this.style.bg.isEmpty())
        tokens[++tokens.length - 1] = " bgcolor=" + this.style.bg.color;
    }
  if (this.colspan)
    tokens[++tokens.length - 1] = " colspan=" + this.colspan;
  if (!isBrowserNS4() && this.event && !this.event.isEmpty())
    tokens[++tokens.length - 1] = " " + this.event;
  tokens[++tokens.length - 1] = ">";

  if (isBrowserNS4() && !this.style.isEmpty())
    tokens[++tokens.length - 1] = this.style.begin();

  if (this.object)
    tokens[++tokens.length - 1] = this.object;

  if (isBrowserNS4() && !this.style.isEmpty())
    tokens[++tokens.length - 1] = this.style.end();

  tokens[++tokens.length - 1] = "</td>";

  return tokens.join("");
}

function bisCellIsEmpty()
{
  return typeof(this.object) == "undefined";
}

function bisRow(cells, style)
{
  // Default parameters
  if (!cells)
    cells = new Array;
  else
    if (!cells[0])
      cells = new Array(cells);
  if (!style)
    style = new bisStyle;

  // Properties
  this.cells; // collection of bisCell objects
  this.style; // bisStyle object

  // Methods
  this.toString = bisRowString;       // converts this object into HTML code
  this.isEmpty  = bisRowIsEmpty;      // determines if this object is empty
  this.insertCell = bisRowInsertCell; // inserts a cell to the cells collection

  // Default values
  this.cells  = cells;
  this.style  = style;
}

function bisRowString()
{
  var tokens = new Array();

  tokens[++tokens.length - 1] = "<tr";
  if (!this.style.isEmpty())
    tokens[++tokens.length - 1] = " " + this.style;
  tokens[++tokens.length - 1] = ">";
  if (this.cells)
    for (var i = 0; i < this.cells.length; ++i)
      tokens[++tokens.length - 1] = this.cells[i];
  tokens[++tokens.length - 1] = "</tr>";

  return tokens.join("");
}

function bisRowIsEmpty()
{
  return this.cells.length == 0;
}

function bisRowInsertCell(cell)
{
  // Make sure there is a valid collection.
  if (!this.cells || this.cells.length == null)
    if (!this.cells)  // collection doesn't exist, create one
      this.cells = [];
    else  // single item, not a collection; create collection and preserve item
      this.cells = [ this.cells ];

  if (!cell)
    cell = new bisCell;

  this.cells[++this.cells.length - 1] = cell;

  return cell;
}

function bisTable(rows, style)
{
  // Default parameters
  if (!rows)
    rows = new Array;
  else
    if (!rows[0])
      rows = new Array(rows);
  if (!style)
    style = new bisStyle;

  // Properties
  this.align; // 'left', 'center', 'right'
  this.style; // bisStyle object
  this.event; // bisEvent object
  this.rows;  // bisRow collection

  // Methods
  this.toString   = bisTableString;     // convert this object into HTML code
  this.isEmpty    = bisTableIsEmpty;    // determines if this object is empty
  this.insertRow  = bisTableInsertRow;  // inserts a row to the rows collection; returns newly added row

  // Default values
  this.align  = "left";
  this.style  = style;
  this.event  = new bisEvent;
  this.rows   = rows;
}

function bisTableString()
{
  var tokens = new Array();

  tokens[++tokens.length - 1] = "<table";
  if (this.style && !this.style.isEmpty())
    if (!isBrowserNS4())
      tokens[++tokens.length - 1] = " " + this.style;
    else
    {
      if (!this.style.border.isEmpty() && typeof(this.style.border.width) != "undefined")
        tokens[++tokens.length - 1] = " border='" + this.style.border.width + "'";
      if (this.style.bg && this.style.bg.color)
        tokens[++tokens.length - 1] = " bgcolor='" + this.style.bg.color + "'";
    }
  if (this.align && this.align != "")
    tokens[++tokens.length - 1] = " align=" + this.align;
  if (!this.event.isEmpty())
    tokens[++tokens.length - 1] = " " + this.event;
  tokens[++tokens.length - 1] = ">";
  tokens[++tokens.length - 1] = "<tbody>";
  if (this.rows)
    for (var i = 0; i < this.rows.length; ++i)
      tokens[++tokens.length - 1] = this.rows[i];
  tokens[++tokens.length - 1] = "</tbody>";
  tokens[++tokens.length - 1] = "</table>";

  return tokens.join("");
}

function bisTableIsEmpty()
{
  return !this.rows;
}

function bisTableInsertRow(row)
{
  // Make sure we have a valid collection
  if (!this.rows || this.rows.length == null)
    if (!this.rows)
      this.rows = [];
    else
      this.rows = [this.rows];

  if (!row)
    row = new bisRow;

  this.rows[++this.rows.length - 1] = row;

  return row;
}

function bisLayer(object)
{
  // Default values

  // Define object properties and set their values.
  this.object = object;        // any object that can be translated into HTML code
  this.event  = new bisEvent;
  this.style  = new bisStyle;
  this.id;

  // Define methods for this object.
  this.toString = bisLayerString;     // convert this object into HTML code
  this.isEmpty  = bisLayerIsEmpty;    // determines if this object is empty
  this.begin    = bisLayerBegin;
  this.end      = bisLayerEnd;
}

function bisLayerString()
{
  var tokens = new Array();

  tokens[++tokens.length - 1] = this.begin();
  tokens[++tokens.length - 1] = this.object;
  tokens[++tokens.length - 1] = this.end();

  return tokens.join("");
}

function bisLayerIsEmpty()
{
  return !this.object || this.object == "";
}

function bisLayerBegin()
{
  var tokens = new Array();
  
  tokens[++tokens.length - 1] = this.style.position == "relative" ? "<ilayer" : "<layer";
  if (this.id)
    tokens[++tokens.length - 1] = " id='" + this.id + "'";
  if (this.style && !this.style.isEmpty())
  {
    this.style.visibility = this.style.render ? "show" : "hide";
    if (this.style.visibility && this.style.visibility != "")
      tokens[++tokens.length - 1] = " visibility=" + this.style.visibility;
    if (this.style.width && this.style.width != "")
      if (typeof(this.style.width) == "string" && this.style.width.indexOf("%") != -1)
        tokens[++tokens.length - 1] = " width=" + this.style.width;
      else
        tokens[++tokens.length - 1] = " width=" + (parseInt(this.style.width) + Math.ceil(this.style.width * 0.1));
    if (this.style.bg && !this.style.bg.isEmpty())
      tokens[++tokens.length - 1] = " bgcolor='" + this.style.bg.color + "'";
    if (this.style.top != null)
      tokens[++tokens.length - 1] = " top=" + this.style.top;
    if (this.style.left != null)
      tokens[++tokens.length - 1] = " left=" + this.style.left;
  }
  if (this.event && !this.event.isEmpty())
    tokens[++tokens.length - 1] = " " + this.event;
  tokens[++tokens.length - 1] = ">";
  tokens[++tokens.length - 1] = "<html><body>";
  if (this.style && !this.style.isEmpty())
  {
    if (this.style.align == "center")
      tokens[++tokens.length - 1] = "<center>";
    if (this.style.font && !this.style.font.isEmpty())
      tokens[++tokens.length - 1] = this.style.font.begin();
  }

  return tokens.join("");
}

function bisLayerEnd()
{
  var tokens = new Array();
  
  if (this.style && !this.style.isEmpty())
  {
    if (this.style.font && !this.style.font.isEmpty())
      tokens[++tokens.length - 1] = this.style.font.end();
    if (this.style.align == "center")
      tokens[++tokens.length - 1] = "</center>";
  }
  tokens[++tokens.length - 1] = "</body></html>";
  tokens[++tokens.length - 1] = this.style.position == "relative" ? "</ilayer>" : "</layer>";

  return tokens.join("");
}

function bisAnchor(object, link)
{
  // Default values

  // Define object properties and set their values.
  this.name;                  // string
  this.target;                // string
  this.object = object;       // any object that can be translated into HTML code
  this.link   = link;         // url or javascript code
  this.event  = new bisEvent;
  this.style  = new bisStyle;

  // Define methods for this object.
  this.toString   = bisAnchorString;     // convert this object into HTML code
  this.isEmpty    = bisAnchorIsEmpty;    // determines if this object is empty
}

function bisAnchorString()
{
  var tokens = new Array();

  tokens[++tokens.length - 1] = "<a";
  if (this.name && this.name != "")
    tokens[++tokens.length - 1] = " name='" + this.name + "'";
  if (this.link && this.link != "")
    tokens[++tokens.length - 1] = " href='" + this.link + "'";
  if (this.target && this.target != "")
    tokens[++tokens.length - 1] = " target='" + this.target + "'";
  if (this.style && !this.style.isEmpty() && !isBrowserNS4())
    tokens[++tokens.length - 1] = " " + this.style;
  if (this.event && !this.event.isEmpty())
    tokens[++tokens.length - 1] = " " + this.event;
  tokens[++tokens.length - 1] = ">";
  if (isBrowserNS4() && this.style && !this.style.isEmpty())
    tokens[++tokens.length - 1] = this.style.begin();
  tokens[++tokens.length - 1] = this.object;
  if (isBrowserNS4() && this.style && !this.style.isEmpty())
    tokens[++tokens.length - 1] = this.style.end();
  tokens[++tokens.length - 1] = "</a>";

  return tokens.join("");
}

function bisAnchorIsEmpty()
{
  return  !this.object || this.object == "";
}

function bisImage(src, name)
{
  // Default parameters

  // Define object properties and set their values.
  this.alt;                   // string
  this.name   = name;         // string
  this.src    = src;          // string
  this.frames = new Array;    // Image array
  this.event  = new bisEvent;
  this.style  = new bisStyle;

  // Define methods for this object.
  this.toString     = bisImageString;     // convert this object into HTML code
  this.isEmpty      = bisImageIsEmpty;    // determines if this object is empty
  this.toggle       = bisImageToggle;
  this.insertFrame  = bisImageInsertFrame;

  // Default values
  this.style.border.width = "0";
  if (this.src)
    this.insertFrame(this);
}

function bisImageString()
{
  var tokens = new Array();

  tokens[++tokens.length - 1] = "<img";
  if (this.name && this.name != "")
    tokens[++tokens.length - 1] = " name='" + this.name + "'";
  if (this.style && !this.style.isEmpty() && this.style.border && !this.style.border.isEmpty())
    tokens[++tokens.length - 1] = " border=" + this.style.border.width;
  if (this.src && this.src != "")
    tokens[++tokens.length - 1] = " src='" + this.src + "'";
  if (this.alt && this.alt != "")
    tokens[++tokens.length - 1] = " alt='" + this.alt + "'";
  if (this.event && !this.event.isEmpty())
    tokens[++tokens.length - 1] = " " + this.event;
  tokens[++tokens.length - 1] = ">";

  return tokens.join("");
}

function bisImageIsEmpty()
{
  return  !this.src || this.src == "";
}

function bisImageToggle()
{
  var curImage = eval("document." + this.name);

  if (curImage && this.frames.length >= 2)
    curImage.src = curImage.src == this.frames[0].src ? this.frames[1].src : this.frames[0].src;
}

function bisImageInsertFrame(frame)
{
  var image;

  if (!frame)
    frame = this.src;

  if (typeof(frame.src) != "undefined" && typeof(frame.frames) == "undefined")  // Image object?
    image = frame;
  else  // bisImage object or string
  {
    image = new Image;

    if (typeof(frame) == "string")
      image.src = frame;
    else
    {
      image.name  = frame.name;
      image.src   = frame.src;
    }
  }

  if (typeof(this.frames.length) == "undefined")
    this.frames = [image];
  else
    this.frames[++this.frames.length - 1] = image;
}

function bisContainer()
{
  // Default parameters

  // Define object properties and set their values.
  this.object = isBrowserNS4() ? new bisLayer : new bisDiv;

  // Define methods for this object.
  this.toString     = bisContainerString;     // convert this object into HTML code
  this.isEmpty      = bisContainerIsEmpty;    // determines if this object is empty
  this.begin        = bisContainerBegin;
  this.end          = bisContainerEnd;
  this.fetchById    = bisContainerFetchById;
  this.fetchByName  = bisContainerFetchByName;
}

function bisContainerString()
{
  return this.object.toString();
}

function bisContainerIsEmpty()
{
  return typeof(this.object) == "undefined";
}

function bisContainerBegin()
{
  return this.object.begin();
}

function bisContainerEnd()
{
  return this.object.end();
}

function bisContainerFetchById()
{
  var fetchString;

  if (this.object.id)
    fetchString = "document." + (isBrowserNS4() ? this.object.id : "getElementById('" + this.object.id + "')");

  return fetchString;
}

function bisContainerFetchByName()
{
  var fetchString;

  if (this.object.id)
    fetchString = "document." + (isBrowserNS4() ? this.object.id : "getElementsByName('" + this.object.id + "')");

  return fetchString;
}

function bisAnimation()
{
  // Default parameter values

  // Properties
  this.frames;
  this.loop;
  this.abort;

  // Methods
  this.addFrame = bisAnimationAddFrame;
  this.start    = bisAnimationStart;
  this.stop     = bisAnimationStop;

  // Default property values
  this.frames = new Array;
  this.loop   = 1;
  this.abort  = false;
}

function bisAnimationAddFrame(htmlElement, timeLength_in_milliseconds, specialEffects)
{
  var frame =
  {
    element       : htmlElement,
    displayTime   : 0,
    timeLength    : timeLength_in_milliseconds,
    specialFX     : specialEffects,
    action        : null
  };

  if (this.frames.length > 0)
    frame.displayTime = this.frames[this.frames.length - 1].displayTime + this.frames[this.frames.length - 1].timeLength;

  if (frame.specialFX == "fade")
    frame.timeLength += 4000;

  this.frames[++this.frames.length - 1] = frame;
}

function bisAnimationStart()
{
  _bisAnimation.stop = false;
  _bisAnimation.frames = this.frames;

  var statements = new Array;

  for (var i = 0; i < this.frames.length; ++i)
  {
    statements.length = 0;
    statements[++statements.length - 1] = "if (_bisAnimation.stop) return";
    statements[++statements.length - 1] = "_bisAnimation.curFrame = _bisAnimation.frames[" + i + "]";
    statements[++statements.length - 1] = "var frame = _bisAnimation.curFrame";
    statements[++statements.length - 1] = "displayRender(frame.element)";

    if (this.frames[i].specialFX == "fade")
      statements[++statements.length - 1] = "fade(frame.element, false)";

    if (this.frames[i].timeLength)
    {
      if (this.frames[i].specialFX == "fade")
        statements[++statements.length - 1] = "setTimeout('fade(_bisAnimation.curFrame.element, true)', frame.timeLength - 2000)";

      statements[++statements.length - 1] = "setTimeout('displayNoRender(_bisAnimation.curFrame.element)', frame.timeLength)";
    }

    if (i < this.frames.length - 1)
      statements[++statements.length - 1] = "if (!_bisAnimation.stop) setTimeout('_bisAnimation.frames[" + (i + 1) + "].action()', _bisAnimation.curFrame.timeLength)";

    ++statements.length;  // for the trailing semicolon
    this.frames[i].action = new Function(statements.join(";\n"));
  }

  _bisAnimation.frames[0].action(); // start the animation
}

function bisAnimationStop()
{
  _bisAnimation.stop = true;

  return _bisAnimation.curFrame.element;
}
