/* 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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.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 (tln.equals(name))
              {
                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;
  }
  
}
