/* DomHTMLElement.java --
   Copyright (C) 2005 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package gnu.xml.dom.html2;

import gnu.xml.dom.DomDOMException;
import gnu.xml.dom.DomElement;
import gnu.xml.dom.DomEvent;
import org.w3c.dom.DOMException;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.events.UIEvent;
import org.w3c.dom.html2.HTMLElement;

/**
 * Abstract implementation of an HTML element node.
 *
 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
 */
public abstract class DomHTMLElement
  extends DomElement
  implements HTMLElement
{

  protected DomHTMLElement(DomHTMLDocument owner, String namespaceURI,
                           String name)
  {
    super(owner, namespaceURI, name);
  }

  /**
   * Returns the value of the specified attribute.
   * The attribute name is case insensitive.
   */
  protected String getHTMLAttribute(String name)
  {
    if (hasAttributes())
      {
        NamedNodeMap attrs = getAttributes();
        int len = attrs.getLength();
        for (int i = 0; i < len; i++)
          {
            Node attr = attrs.item(i);
            String attrName = attr.getLocalName();
            if (attrName == null)
              {
                attrName = attr.getNodeName();
              }
            if (attrName.equalsIgnoreCase(name))
              {
                return attr.getNodeValue();
              }
          }
      }
    return "";
  }

  protected int getIntHTMLAttribute(String name)
  {
    String value = getHTMLAttribute(name);
    if (value == null)
      {
        return -1;
      }
    try
      {
        return Integer.parseInt(value);
      }
    catch (NumberFormatException e)
      {
        return -1;
      }
  }

  protected boolean getBooleanHTMLAttribute(String name)
  {
    String value = getHTMLAttribute(name);
    return value != null;
  }

  /**
   * Sets the value of the specified attribute.
   * The attribute name is case insensitive.
   */
  protected void setHTMLAttribute(String name, String value)
  {
    Node attr;
    NamedNodeMap attrs = getAttributes();
    int len = attrs.getLength();
    for (int i = 0; i < len; i++)
      {
        attr = attrs.item(i);
        String attrName = attr.getLocalName();
        if (attrName == null)
          {
            attrName = attr.getNodeName();
          }
        if (attrName.equalsIgnoreCase(name))
          {
            if (value != null)
              {
                attr.setNodeValue(value);
              }
            else
              {
                attrs.removeNamedItem(attr.getNodeName());
              }
            return;
          }
      }
    if (value != null)
      {
        // Create a new attribute
        DomHTMLDocument doc = (DomHTMLDocument) getOwnerDocument();
        // XXX namespace URI for attribute?
        attr = doc.createAttribute(name);
        attr.setNodeValue(value);
      }
  }

  protected void setIntHTMLAttribute(String name, int value)
  {
    setHTMLAttribute(name, Integer.toString(value));
  }

  protected void setBooleanHTMLAttribute(String name, boolean value)
  {
    setHTMLAttribute(name, value ? name : null);
  }

  /**
   * Returns the first parent element with the specified name.
   */
  protected Node getParentElement(String name)
  {
    for (Node parent = getParentNode(); parent != null;
         parent = parent.getParentNode())
      {
        String parentName = parent.getLocalName();
        if (parentName == null)
          {
              parentName = parent.getNodeName();
          }
        if (name.equalsIgnoreCase(parentName))
          {
            return parent;
          }
      }
    return null;
  }

  /**
   * Returns the first child element with the specified name.
   */
  protected Node getChildElement(String name)
  {
    for (Node child = getFirstChild(); child != null;
         child = child.getNextSibling())
      {
        String childName = child.getLocalName();
        if (childName == null)
          {
            childName = child.getLocalName();
          }
        if (name.equalsIgnoreCase(childName))
          {
            return child;
          }
      }
    return null;
  }

  /**
   * Returns the index of this element among elements of the same name,
   * relative to its parent.
   */
  protected int getIndex()
  {
    int index = 0;
    Node parent = getParentNode();
    if (parent != null)
      {
        for (Node ctx = parent.getFirstChild(); ctx != null;
             ctx = ctx.getNextSibling())
          {
            if (ctx == this)
              {
                return index;
              }
            index++;
          }
      }
    throw new DomDOMException(DOMException.NOT_FOUND_ERR);
  }

  protected void dispatchUIEvent(String name)
  {
    UIEvent event = new DomEvent.DomUIEvent(name);
    dispatchEvent(event);
  }

  public String getId()
  {
    return getHTMLAttribute("id");
  }

  public void setId(String id)
  {
    setHTMLAttribute("id", id);
  }

  public String getTitle()
  {
    return getHTMLAttribute("title");
  }

  public void setTitle(String title)
  {
    setHTMLAttribute("title", title);
  }

  public String getLang()
  {
    return getHTMLAttribute("lang");
  }

  public void setLang(String lang)
  {
    setHTMLAttribute("lang", lang);
  }

  public String getDir()
  {
    return getHTMLAttribute("dir");
  }

  public void setDir(String dir)
  {
    setHTMLAttribute("dir", dir);
  }

  public String getClassName()
  {
    return getHTMLAttribute("class");
  }

  public void setClassName(String className)
  {
    setHTMLAttribute("class", className);
  }

}
