/* DomXPathResult.java -- 
   Copyright (C) 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 java.util.Collection;
import java.util.Iterator;
import org.w3c.dom.Node;
import org.w3c.dom.xpath.XPathException;
import org.w3c.dom.xpath.XPathResult;

/**
 * An XPath result object.
 *
 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
 */
class DomXPathResult
implements XPathResult
{

  final Object value;
  final short type;
  Iterator iterator;

  DomXPathResult (Object value, short requestedType)
  {
    this.value = value;
    if (value instanceof Boolean)
      {
        type = XPathResult.BOOLEAN_TYPE;
      }
    else if (value instanceof Double)
      {
        type = XPathResult.NUMBER_TYPE;
      }
    else if (value instanceof String)
      {
        type = XPathResult.STRING_TYPE;
      }
    else if (value instanceof Collection)
      {
        Collection ns = (Collection) value;
        switch (requestedType)
          {
          case XPathResult.ANY_TYPE:
          case XPathResult.ANY_UNORDERED_NODE_TYPE:
            type = (ns.size () == 1) ? XPathResult.FIRST_ORDERED_NODE_TYPE :
              XPathResult.ORDERED_NODE_ITERATOR_TYPE;
            break;
          default:
            type = requestedType;
          }
        iterator = ns.iterator ();
      }
    else
      {
        throw new IllegalArgumentException ();
      }
  }

  public boolean getBooleanValue()
  {
    if (type == XPathResult.BOOLEAN_TYPE)
      {
        return ((Boolean) value).booleanValue ();
      }
    throw new XPathException (XPathException.TYPE_ERR, value.toString ());
  }

  public boolean getInvalidIteratorState()
  {
    return iterator == null;
  }

  public double getNumberValue()
  {
    if (type == XPathResult.NUMBER_TYPE)
      {
        return ((Double) value).doubleValue ();
      }
    throw new XPathException (XPathException.TYPE_ERR, value.toString ());
  }

  public short getResultType()
  {
    return type;
  }

  public Node getSingleNodeValue()
  {
    switch (type)
      {
      case XPathResult.FIRST_ORDERED_NODE_TYPE:
      case XPathResult.ORDERED_NODE_ITERATOR_TYPE:
      case XPathResult.ORDERED_NODE_SNAPSHOT_TYPE:
      case XPathResult.UNORDERED_NODE_ITERATOR_TYPE:
      case XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE:
        Collection ns = (Collection) value;
        if (ns.isEmpty ())
          {
            return null;
          }
        else
          {
            return (Node) ns.iterator ().next ();
          }
      }
    throw new XPathException (XPathException.TYPE_ERR, value.toString ());
  }

  public int getSnapshotLength()
  {
    switch (type)
      {
      case XPathResult.FIRST_ORDERED_NODE_TYPE:
      case XPathResult.ORDERED_NODE_ITERATOR_TYPE:
      case XPathResult.ORDERED_NODE_SNAPSHOT_TYPE:
      case XPathResult.UNORDERED_NODE_ITERATOR_TYPE:
      case XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE:
        return ((Collection) value).size ();
      }
    throw new XPathException (XPathException.TYPE_ERR, value.toString ());
  }

  public String getStringValue()
  {
    if (type == XPathResult.STRING_TYPE)
      {
        return (String) value;
      }
    throw new XPathException (XPathException.TYPE_ERR, value.toString ());
  }

  public Node iterateNext()
  {
    if (iterator != null)
      {
        if (iterator.hasNext ())
          {
            return (Node) iterator.next ();
          }
        else
          {
            iterator = null;
            return null;
          }
      }
    throw new XPathException (XPathException.TYPE_ERR, value.toString ());
  }

  public Node snapshotItem(int index)
  {
    switch (type)
      {
      case XPathResult.FIRST_ORDERED_NODE_TYPE:
      case XPathResult.ORDERED_NODE_ITERATOR_TYPE:
      case XPathResult.ORDERED_NODE_SNAPSHOT_TYPE:
      case XPathResult.UNORDERED_NODE_ITERATOR_TYPE:
      case XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE:
        Collection ns = (Collection) value;
        Node[] nodes = new Node[ns.size ()];
        ns.toArray (nodes);
        return nodes[index];
      }
    throw new XPathException (XPathException.TYPE_ERR, value.toString ());
  }

  public String toString ()
  {
    return getClass ().getName () + "[type=" + typeName (type) + ",value=" +
      value + ']';
  }

  private String typeName (short type)
  {
    switch (type)
      {
      case XPathResult.BOOLEAN_TYPE:
        return "BOOLEAN_TYPE";
      case XPathResult.NUMBER_TYPE:
        return "NUMBER_TYPE";
      case XPathResult.STRING_TYPE:
        return "STRING_TYPE";
      case XPathResult.FIRST_ORDERED_NODE_TYPE:
        return "FIRST_ORDERED_NODE_TYPE";
      case XPathResult.ORDERED_NODE_ITERATOR_TYPE:
        return "ORDERED_NODE_ITERATOR_TYPE";
      case XPathResult.ORDERED_NODE_SNAPSHOT_TYPE:
        return "ORDERED_NODE_SNAPSHOT_TYPE";
      case XPathResult.UNORDERED_NODE_ITERATOR_TYPE:
        return "UNORDERED_NODE_ITERATOR_TYPE";
      case XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE:
        return "UNORDERED_NODE_SNAPSHOT_TYPE";
      default:
        return "(unknown)";
      }
  }

}
