// VIVO JavaScript Framework 1.1
// Copyright (c) 2005 Jeremy Raadt (jraadt@hotmail.com)
// Copyright (c) 2006 Andy Altepeter (aaltepet@altepeter.net)
//
// See vivo.js for full license.


//-------------------------------------
// DOM
//-------------------------------------
function getElementsByVivoAttributes(vivoAttrs, dom) {
  var result = [];
  if (dom == null || dom.nodeType != 1) {
    dom = document.documentElement;
  }
  start = new Date().getTime();

  // version 3 -- iterating the DOM directly  suprisingly, this is just as slow
  // as the tail-recursive version
  /*if (document.all || document.getElementsByTagName) {
    dom_q = [dom];
    while (node = dom_q.pop()) {
      if (node.nodeType != node.ELEMENT_NODE) // skip over non-element nodes
	continue;
      if (!(node.tagName == 'table' || node.tagName == 'TABLE')) {
	for (var j=0; j < vivoAttrs.length; j++) {
	  attr = node.getAttribute(vivoAttrs[j]); // IE5/Mac fix
	  if (attr != null) {
	    result[result.length] = node;
	  }
	}
      }
      for (i=0;i<node.childNodes.length;i++) {
	dom_q.push(node.childNodes[i]);
      }
    }
    alert('dom-traversal' + ((new Date().getTime()) - start));
    return result;
  }*/

    /* second try: loop through elements only once, checking each
       element to see if it has vivo attributes.
       This is still slow, as it first retrieves all attributes
       as a NodeList */
  /* suprisingly, this is faster in firefox than the dom traversal method*/
  /* only potential way to speed up in IE is to use XPath*/
  if (document.all || document.getElementsByTagName) {
    elements = document.all ? dom.all : dom.getElementsByTagName("*");
    for(var i = 0; i < elements.length; i++){
      /*it seems IE doesn't like tables, so don't check tables.
	further: it seems IE can't to getAttribute('vivo:name')*/
      if (elements[i].tagName == 'table' || elements[i].tagName == 'TABLE') {
	continue;
      }
      for (var j=0; j < vivoAttrs.length; j++) {
	attr = elements[i].getAttribute(vivoAttrs[j]); // IE5/Mac fix
	if (attr != null) {
	  result[result.length] = elements[i];
	  break;
	}
      }
    }
  }
  //alert('double-iterate' + ((new Date().getTime()) - start));
  return result;
}

function assignId(element) {
  var id = element.getAttribute("id");
  for (var k = 0; id == null || id==''; k++) {
    if (!document.getElementById(element.tagName + k)) {
      id = element.tagName + k;
      element.setAttribute("id", id);
    }
  }
  return id;
}

function getElementsByAttribute(name, value, tag, dom) {
  var elements;
  var attr;
  var result = [];

  if (dom == null || dom.nodeType != 1) {
    dom = document;
  }

  if (document.all || document.getElementsByTagName) {
    if (tag) {
      elements = document.all ? dom.all.tags(tag.toUpperCase()) : dom.getElementsByTagName(tag);
    }
    else {
      elements = document.all ? dom.all : dom.getElementsByTagName("*");
    }

    for(var i = 0; i < elements.length; i++){
      /*it seems IE doesn't like tables, so don't check tables.
	further: it seems IE can't to getAttribute('vivo:name')*/
      if (elements[i].tagName == 'table' || elements[i].tagName == 'TABLE') {
	continue;
      }
      attr = name == "class" ? elements[i].className : elements[i].getAttribute(name); // IE5/Mac fix
      if (attr != null) {
        if (value && attr != value) {
          continue;
        }
        result[result.length] = elements[i];
      }
    }
  }

  return result;
}



//-------------------------------------
// HASHTABLE
//-------------------------------------
function Hashtable() {
  this.hash = new Array();
  this.keys = new Array();
}

Hashtable.prototype.put = function(key, value) {
  if (this.hash[key] == null)
  {
    this.keys.push(key);
  }

  this.hash[key] = value;
}

Hashtable.prototype.get = function(key) {
  return this.hash[key];
}

Hashtable.prototype.remove = function(key) {
  delete this.hash[key];

  var index = this.keys.indexOf(key);
  if (index > -1) {
    delete this.keys[index];
  }
}

Hashtable.prototype.size = function() {
  return this.keys.length;
}

Hashtable.prototype.clear = function() {
  this.hash = new Array();
  this.keys = new Array();
}

Hashtable.prototype.containsKey = function(key) {
  if (this.get(key) != null) {
    return true;
  }
  return false;
}

Hashtable.prototype.containsValue = function(value) {
  if (this.hash.indexOf(value) > -1) {
    return true;
  }
  return false;
}

/*Hashtable.prototype.keys = function() {
  return this.keys;
  }*/



//-------------------------------------
// ARRAY
//-------------------------------------
if (!Array.indexOf) {
  Array.prototype.indexOf = function(value) {
    var result = -1;
    if (!this.length) {
      return -1;
    }

    for (var i = 0; i < this.length; i++) {
      if (this[i] == value) {
        return i;
      }
    }

    return -1;
  }
 }
