// Module: DOM
// for working with the W3C DOM
// by Jon Frechette


function DOM() {} // empty constructor


DOM.isNode = function( pObject )
  {
  return pObject != null && typeof pObject.nodeName != 'undefined';
  }


DOM.isElement = function( pObject )
  {
  return DOM.isNode( pObject ) && pObject.nodeType == Node.ELEMENT_NODE;
  }


DOM.hasClassname = function( pObj, pClassname )
  {
  if ( ! pObj.className )
    return false;
  var strs = pObj.className.split( ' ' );
  for ( var i = 0; i < strs.length; i++ )
    if ( strs[ i ] == pClassname )
      return true;
  return false;
  }


DOM.addClassname = function( pObj, pClassname )
  {
  if ( pObj.className )
    pObj.className += ' ' + pClassname;
  else
    pObj.className = pClassname;
  }


DOM.removeClassname = function( pObj, pClassname )
  {
  if ( ! DOM.hasClassname( pObj, pClassname ) )
    return;
  var names = pObj.className.split( ' ' );
  var newNames = '';
  for ( var i = 0; i < names.length; i++ )
    {
    var name = names[ i ];
    if ( name != pClassname )
      {
      if ( i > 0 )
        newNames += ' ';
      newNames += name;
      }
    }
  pObj.className = newNames;
  return;
  }


DOM.getParentElement = function( pObject )
  {
  if ( ! DOM.isNode( pObject ) )
    return null;
  var p = pObject.parentNode;
  while ( ! DOM.isElement( p ) )
    {
    if ( ! p.parentNode )
      return null;
    p = p.parentNode;
    }
  return p;
  }


DOM.getChildElements = function( pObject )
  {
  return DOM._getChildElements( pObject, null, null )
  }


DOM.getChildElementsByTagName = function( pObject, pTagName )
  {
  return DOM._getChildElements( pObject, pTagName, null )
  }


DOM.getChildElementsByClassName = function( pObject, pClassName )
  {
  return DOM._getChildElements( pObject, null, pClassName )
  }


DOM.getChildElementsByTagNameAndClassName = function( pObject, pTagName, pClassName )
  {
  return DOM._getChildElements( pObject, pTagName, pClassName )
  }


DOM.getParentElement = function( pObject )
  {
  return DOM._getParentElement( pObject, null, null )
  }


DOM.getParentElementByTagName = function( pObject, pTagName )
  {
  return DOM._getParentElement( pObject, pTagName, null )
  }


DOM.getParentElementByClassName = function( pObject, pClassName )
  {
  return DOM._getParentElement( pObject, null, pClassName )
  }


DOM.getParentElementByTagNameAndClassName = function( pObject, pTagName, pClassName )
  {
  return DOM._getParentElement( pObject, pTagName, pClassName )
  }


DOM.dgShowElements = function( pElement, pShowAll )
  {
  var element = pElement;
  var s = DOM._elementsAsStr( element, 0, pShowAll );
  Diag.showCode( s );
  return;
  }

/* -------------------------------------------------------------------------- */

DOM._getParentElement = function( pObject, pTagName, pClassName )
  {
  if ( ! DOM.isNode( pObject ) )
    return null;

  if ( pTagName )
    pTagName = pTagName.toUpperCase();
  var node = pObject;
  do {
    if ( ! node.parentNode )
      return null;
    node = node.parentNode;
  } while ( ! DOM.isElement( node ) ||
            (pTagName && node.tagName != pTagName) ||
            (pClassName && ! DOM.hasClassName( node, pClassName )) );
  return node;
  }


DOM._getChildElements = function( pObject, pTagName, pClassName )
  {
  if ( ! DOM.isNode( pObject ) )
    return null;

  if ( pTagName )
    pTagName = pTagName.toUpperCase();
  var elements = new Array();
  if ( DOM.isNode( pObject ) )
    {
    var nodes = pObject.childNodes;
    for ( var i = 0; i < nodes.length; i++ )
      {
      var node = nodes.item( i );
      if ( DOM.isElement( node ) &&
           (! pTagName || node.tagName == pTagName) &&
           (! pClassName || DOM.hasClassName( node, pClassName )) )
        {
        elements[ elements.length ] = node;
        }
      }
    }
  return elements;
  }


DOM._elementsAsStr = function( pElement, pIndents, pShowAll )
{
  if ( pElement.localName === null || pElement.localName == 'script' )
    return '';
  if ( pElement.nodeName == '#text' || pElement.nodeName == '#comment' )
    if ( ! pShowAll )
      return '';

  var s = ''.padRight( pIndents * 2, ' ' );
  s += '<';
  if ( pElement.nodeName == '#comment' )
    s += '!--' + pElement.nodeValue + '--';
  else
    {
  s += pElement.nodeName.toLowerCase();
  if ( pElement.id )
    s += " id='" + pElement.id + "'";
  if ( pElement.className )
    s += " class='" + pElement.className + "'";
    }
  s += '>\n';

  if ( pElement.hasChildNodes() )
    {
    var kids = pElement.childNodes;
    for ( var i = 0; i < kids.length; i++ )
      {
      s += DOM._elementsAsStr( kids.item( i ), pIndents + 1, pShowAll );
      }
    }
  return s;
} // _elementsAsStr



  // If there is no Node object, define one with the following properties and values.
  // Note that these are HTML node types only.
  // For XML-specific nodes, you need to add other constants here.
  // IE6 does not support the node-type constants defined by the Node interface.
if ( typeof window.Node == 'undefined' )
  {
  window.Node = {          
    ELEMENT_NODE           : 1,
    ATTRIBUTE_NODE         : 2,
    TEXT_NODE              : 3,
    COMMENT_NODE           : 8,
    DOCUMENT_NODE          : 9,
    DOCUMENT_FRAGMENT_NODE : 11
    }
  }


