
// 
// CLASS:
// - Element
// 
// VERSION:
// - 1.0.0 - 20070725 - Loose design, based off of ListChain, has not been tested
// - 1.0.1 - 20070808 - Redesigned and restructured, updated data model when creating an element to use hash array
// - 1.1.0 - 20070813 - Added methods, "addClass", "getAll", "getByClass", "getById", "getByTagName", "removeClass"
// - 1.1.1 - 20070921 - Fixed "removeClass" method
// - 1.2.0 - 20071004 - Added method, "hasClass", fixed bug with "addClass" method
// 

var Element = 
{
  addClass: function (element, className)
  {
    // Initialize
    var pattern = new RegExp('(^| )' + className + '( |$)');
    var success = true;
    
    // Execute
    if (element)
    {
      if (element.className == '')
      {
        element.className = className;
      }
      
      else if (!pattern.test(element.className))
      {
        element.className += ' ' + className;
      }
      
      else
      {
        success = false;
      }
    }
    
    return success;
  },
  
  append: function (parent, child)
  {
    parent.appendChild(child);
  },
  
  create: function (data)
  {
    // Tag
    var element = document.createElement(data.tag);
    
    // Attribute
    if (undefined !== data.attribute && data.attribute && data.attribute.length >= 1)
    {
      for (var i = 0; i < data.attribute.length; i++)
      {
        element.setAttribute(data.attribute[i][0], data.attribute[i][1]);
      }
    }
    
    // Text
    if (undefined !== data.text)
    {
      element.appendChild(document.createTextNode(data.text));
    }
    
    return element;
  },
  
  get: function (targetName, element)
  {
    // Prepare arguments
    if (typeof element == 'undefined')
    {
      element = document;
    }
    
    // Initialize
    var patternClass = new RegExp('^\\..+');
    var patternId = new RegExp('^#.+');
    
    // Execute
    if (patternClass.test(targetName))
    {
      targetName = targetName.substr(1, targetName.length);
      element = this.getByClass(targetName, element);
    }
    
    else if (patternId.test(targetName))
    {
      targetName = targetName.substr(1, targetName.length);
      element = this.getById(targetName, element);
    }
    
    else
    {
      element = this.getByTag(targetName, element);
    }
    
    return element;
  },
  
  getAll: function (element)
  {
    // Prepare arguments
    if (typeof element == 'undefined')
    {
      element = document;
    }
    
    // Initialize
    var data;
    
    // Execute
      // IE handle
    if (typeof element.all != 'undefined')
    {
      data = element.all
    }
    
      // Others handle
    else if (typeof element.getElementsByTagName != 'undefined')
    {
      data = element.getElementsByTagName('*');
    }
    
    return data;
  },
  
  getAttribute: function (attributeName, element)
  {
    var data = '';
    
    if (element && typeof element.attributes != 'undefined' && element.attributes)
    {
      for (var i = 0; i < element.attributes.length; i++)
      {
        if (element.attributes[i].nodeName.toLowerCase() == attributeName.toLowerCase())
        {
          data = element.attributes[i].nodeValue;
        }
      }
    }
    
    return data;
  },
  
  getByClass: function (className, element)
  {
    // Prepare arguments
    if (typeof element == 'undefined')
    {
      element = document;
    }
    
    // Initialize
    var elementList = [];
    var elements = this.getAll(element);
    var pattern = new RegExp('(^| )' + className + '( |$)');
    
    // Execute
    for (var i = 0; i < elements.length; i++)
    {
      if (typeof elements[i].className != 'undefined')
      {
        if (pattern.test(elements[i].className))
        {
          if (elements[i].nodeType == 1)
          {
            elementList[elementList.length] = elements[i];
          }
        }
      }
    }
    
    return elementList;
  },
  
  getById: function (idName, element)
  {
    // Prepare arguments
    if (typeof element == 'undefined')
    {
      element = document;
    }
    
    return element.getElementById(idName);
  },
  
  getByName: function (name, element)
  {
    // Prepare arguments
    if (typeof element == 'undefined')
    {
      element = document;
    }
    
    // Initialize
    var elementList = [];
    var elements = this.getAll(element);
    var nodeName = '';
    var pattern = new RegExp('(^| )' + name + '( |$)');
    
    // Execute
    for (var i = 0; i < elements.length; i++)
    {
      nodeName = Element.getAttribute('name', elements[i]);
      
      if (nodeName && pattern.test(elements[i].className))
      {
        if (elements[i].nodeType == 1)
        {
          elementList[elementList.length] = elements[i];
        }
      }
    }
    
    return elementList;
  },
  
  getByTag: function (tagName, element)
  {
    // Prepare arguments
    if (typeof element == 'undefined')
    {
      element = document;
    }
    
    return element.getElementsByTagName(tagName);
  },
  
  hasClass: function (element, className)
  {
    // Initialize
    var pattern = new RegExp('(^| )' + className + '( |$)');
    var success = true;
    
    // Execute
    if (element)
    {
      if (!pattern.test(element.className))
      {
        success = false;
      }
    }
    
    return success;
  },
  
  remove: function (parent, child)
  {
    parent.removeChild(child);
  },
  
  removeAllChild: function (parent)
  {
    while (parent.firstChild)
    {
      parent.removeChild(parent.firstChild);
    }
  },
  
  removeClass: function (element, className)
  {
    // Initialize
    var pattern = new RegExp('(^| )' + className + '( |$)');
    var success = true;
    
    // Execute
    element.className = element.className.replace(pattern, '');
    element.className = element.className.replace(' $', '');
    
    return success;
  },
  
  setAttribute: function (element, name, value)
  {
    element.setAttribute(name, value);
  }
};

