/* DomNamedNodeMap.java -- 
   Copyright (C) 1999,2000,2001,2004 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;

import org.w3c.dom.DOMException;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

/**
 * <p> "NamedNodeMap" implementation. </p>
 * Used mostly to hold element attributes, but sometimes also
 * to list notations or entities.
 *
 * @author David Brownell 
 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
 */
public class DomNamedNodeMap
  implements NamedNodeMap
{

  final DomNode owner;
  final short type;
  
  DomNode first;
  int length;
  boolean readonly;
  
  // package private
  DomNamedNodeMap(DomNode owner, short type)
  {
    this.owner = owner;
    this.type = type;
  }

  /**
   * Exposes the internal "readonly" flag.  In DOM, all NamedNodeMap
   * objects found in a DocumentType object are read-only (after
   * they are fully constructed), and those holding attributes of
   * a readonly element will also be readonly.
   */
  public final boolean isReadonly()
  {
    return readonly;
  }  
    
  /**
   * Sets the internal "readonly" flag so the node and its
   * children can't be changed.
   */
  public void makeReadonly()
  {
    readonly = true;
    for (DomNode ctx = first; ctx != null; ctx = ctx.next)
      {
        ctx.makeReadonly();
      }
  }
  
  /**
   * <b>DOM L1</b>
   * Returns the named item from the map, or null; names are just
   * the nodeName property.
   */
  public Node getNamedItem(String name)
  {
    for (DomNode ctx = first; ctx != null; ctx = ctx.next)
      {
        if (ctx.getNodeName().equals(name))
          {
            return ctx;
          }
      }
    return null;
  }

  /**
   * <b>DOM L2</b>
   * Returns the named item from the map, or null; names are the
   * localName and namespaceURI properties, ignoring any prefix.
   */
  public Node getNamedItemNS(String namespaceURI, String localName)
  {
    if ("".equals(namespaceURI))
      {
        namespaceURI = null;
      }
    for (DomNode ctx = first; ctx != null; ctx = ctx.next)
      {
        String name = ctx.getLocalName();
        if ((localName == null && name == null) ||
            (localName != null && localName.equals(name)))
          {
            String uri = ctx.getNamespaceURI();
            if ("".equals(uri))
              {
                uri = null;
              }
            if ((namespaceURI == null && uri == null) ||
                (namespaceURI != null && namespaceURI.equals(uri)))
              {
                return ctx;
              }
          }
      }
    return null;
  }

  /**
   * <b>DOM L1</b>
   * Stores the named item into the map, optionally overwriting
   * any existing node with that name.  The name used is just
   * the nodeName attribute.
   */
  public Node setNamedItem(Node arg)
  {
    return setNamedItem(arg, false);
  }

  /**
   * <b>DOM L2</b>
   * Stores the named item into the map, optionally overwriting
   * any existing node with that fully qualified name.  The name
   * used incorporates the localName and namespaceURI properties,
   * and ignores any prefix.
   */
  public Node setNamedItemNS(Node arg)
  {
    return setNamedItem(arg, true);
  }

  Node setNamedItem(Node arg, boolean ns)
  {
    if (readonly)
      {
        throw new DomDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
      }

    DomNode node = (DomNode) arg;
    if (node.owner != owner.owner)
      {
        throw new DomDOMException(DOMException.WRONG_DOCUMENT_ERR);
      }
    if (node.nodeType != type)
      {
        throw new DomDOMException(DOMException.HIERARCHY_REQUEST_ERR);
      }
    if (node.nodeType == Node.ATTRIBUTE_NODE)
      {
        DomNode element = node.parent;
        if (element != null && element != owner)
          {
            throw new DomDOMException(DOMException.INUSE_ATTRIBUTE_ERR);
          }
        node.parent = owner;
        node.depth = owner.depth + 1;
      }
    
    String nodeName = node.getNodeName();
    String localName = ns ? node.getLocalName() : null;
    String namespaceURI = ns ? node.getNamespaceURI() : null;
    if ("".equals(namespaceURI))
      {
        namespaceURI = null;
      }
    
    // maybe attribute ADDITION events (?)
    DomNode last = null;
    for (DomNode ctx = first; ctx != null; ctx = ctx.next)
      {
        boolean test = false;
        if (ns)
          {
            String tln = ctx.getLocalName();
            if (tln == null)
              {
                tln = ctx.getNodeName();
              }
            if (tln.equals(localName))
              {
                String tu = ctx.getNamespaceURI();
                if ((tu == null && namespaceURI == null) ||
                    (tu != null && tu.equals(namespaceURI)))
                  {
                    test = true;
                  }
              }
          }
        else
          {
            test = ctx.getNodeName().equals(nodeName);
          }
        if (test)
          {
            // replace
            node.previous = ctx.previous;
            node.next = ctx.next;
            if (ctx.previous != null)
              {
                ctx.previous.next = node;
              }
            if (ctx.next != null)
              {
                ctx.next.previous = node;
              }
            if (first == ctx)
              {
                first = node;
              }
            reparent(node, nodeName, ctx.index);
            ctx.parent = null;
            ctx.next = null;
            ctx.previous = null;
            ctx.setDepth(0);
            ctx.index = 0;
            return ctx;
          }
        last = ctx;
      }
    // append
    if (last != null)
      {
        last.next = node;
        node.previous = last;
      }
    else
      {
        first = node;
      }
    length++;
    reparent(node, nodeName, 0);
    return null;
  }

  void reparent(DomNode node, String nodeName, int i)
  {
    node.parent = owner;
    node.setDepth(owner.depth + 1);
    // index renumbering
    for (DomNode ctx = node; ctx != null; ctx = ctx.next)
      {
        ctx.index = i++;
      }
    // cache xml:space
    boolean xmlSpace = "xml:space".equals(nodeName);
    if (xmlSpace && owner instanceof DomElement)
      {
        ((DomElement) owner).xmlSpace = node.getNodeValue();
      }
  }

  /**
   * <b>DOM L1</b>
   * Removes the named item from the map, or reports an exception;
   * names are just the nodeName property.
   */
  public Node removeNamedItem(String name)
  {
    return removeNamedItem(null, name, false);
  }

  /**
   * <b>DOM L2</b>
   * Removes the named item from the map, or reports an exception;
   * names are the localName and namespaceURI properties.
   */
  public Node removeNamedItemNS(String namespaceURI, String localName)
  {
    return removeNamedItem(namespaceURI, localName, true);
  }

  Node removeNamedItem(String uri, String name, boolean ns)
  {
    if (readonly)
      {
        throw new DomDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
      }

    // report attribute REMOVAL event?

    for (DomNode ctx = first; ctx != null; ctx = ctx.next)
      {
        boolean test = false;
        String nodeName = ctx.getNodeName();
        if (ns)
          {
            String tln = ctx.getLocalName();
            if (name != null && name.equals(tln))
              {
                String tu = ctx.getNamespaceURI();
                if ((tu == null && uri == null) ||
                    (tu != null && tu.equals(uri)))
                  {
                    test = true;
                  }
              }
          }
        else
          {
            test = nodeName.equals(name);
          }
        if (test)
          {
            // uncache xml:space
            boolean xmlSpace = "xml:space".equals(nodeName);
            if (xmlSpace && owner instanceof DomElement)
              {
                ((DomElement) owner).xmlSpace = "";
              }
            // is this a default attribute?
            if (ctx.nodeType == Node.ATTRIBUTE_NODE)
              {
                String def = getDefaultValue(ctx.getNodeName());
                if (def != null)
                  {
                    ctx.setNodeValue(def);
                    ((DomAttr) ctx).setSpecified(false);
                    return null;
                  }
              }
            // remove
            if (ctx == first)
              {
                first = ctx.next;
              }
            if (ctx.previous != null)
              {
                ctx.previous.next = ctx.next;
              }
            if (ctx.next != null)
              {
                ctx.next.previous = ctx.previous;
              }
            length--;
            ctx.previous = null;
            ctx.next = null;
            ctx.parent = null;
            ctx.setDepth(0);
            ctx.index = 0;
            return ctx;
          }
      }    
    throw new DomDOMException(DOMException.NOT_FOUND_ERR);
  }
  
  String getDefaultValue(String name)
  {
    DomDoctype doctype = (DomDoctype) owner.owner.getDoctype();
    if (doctype == null)
      {
        return null;
      }
    DTDAttributeTypeInfo info =
      doctype.getAttributeTypeInfo(owner.getNodeName(), name);
    if (info == null)
      {
        return null;
      }
    return info.value;
  }

  /**
   * <b>DOM L1</b>
   * Returns the indexed item from the map, or null.
   */
  public Node item(int index)
  {
    DomNode ctx = first;
    int count = 0;
    while (ctx != null && count < index)
      {
        ctx = ctx.next;
        count++;
      }
    return ctx;
  }

  /**
   * <b>DOM L1</b>
   * Returns the length of the map.
   */
  public int getLength()
  {
    return length;
  }
  
}
