/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id$
 */
package org.apache.xml.dtm.ref;

import org.apache.xml.dtm.DTMAxisIterator;

/**
 * This class serves as a default base for implementations of mutable
 * DTMAxisIterators.
 */
public abstract class DTMAxisIteratorBase implements DTMAxisIterator
{

  /** The position of the last node within the iteration, as defined by XPath.
   * Note that this is _not_ the node's handle within the DTM. Also, don't
   * confuse it with the current (most recently returned) position.
   */
  protected int _last = -1;

  /** The position of the current node within the iteration, as defined by XPath.
   * Note that this is _not_ the node's handle within the DTM!
   */
  protected int _position = 0;

  /** The position of the marked node within the iteration;
   * a saved itaration state that we may want to come back to.
   * Note that only one mark is maintained; there is no stack.
   */
  protected int _markedNode;

  /** The handle to the start, or root, of the iteration.
   * Set this to END to construct an empty iterator.
   */
  protected int _startNode = DTMAxisIterator.END;

  /** True if the start node should be considered part of the iteration.
   * False will cause it to be skipped.
   */
  protected boolean _includeSelf = false;

  /** True if this iteration can be restarted. False otherwise (eg, if
   * we are iterating over a stream that can not be re-scanned, or if
   * the iterator was produced by cloning another iterator.)
   */
  protected boolean _isRestartable = true;
  
  /**
   * Get start to END should 'close' the iterator,
   * i.e. subsequent call to next() should return END.
   *
   * @return The root node of the iteration.
   */
  public int getStartNode()
  {
    return _startNode;
  }

  /**
   * @return A DTMAxisIterator which has been reset to the start node,
   * which may or may not be the same as this iterator.
   * */
  public DTMAxisIterator reset()
  {

    final boolean temp = _isRestartable;

    _isRestartable = true;

    setStartNode(_startNode);

    _isRestartable = temp;

    return this;
  }

  /**
   * Set the flag to include the start node in the iteration. 
   *
   *
   * @return This default method returns just returns this DTMAxisIterator,
   * after setting the flag.
   * (Returning "this" permits C++-style chaining of
   * method calls into a single expression.)
   */
  public DTMAxisIterator includeSelf()
  {

    _includeSelf = true;

    return this;
  }

  /** Returns the position of the last node within the iteration, as
   * defined by XPath.  In a forward iterator, I believe this equals the number of nodes which this
   * iterator will yield. In a reverse iterator, I believe it should return
   * 1 (since the "last" is the first produced.)
   *
   * This may be an expensive operation when called the first time, since
   * it may have to iterate through a large part of the document to produce
   * its answer.
   *
   * @return The number of nodes in this iterator (forward) or 1 (reverse).
   */
  public int getLast()
  {

    if (_last == -1)		// Not previously established
    {
      // Note that we're doing both setMark() -- which saves _currentChild
      // -- and explicitly saving our position counter (number of nodes
      // yielded so far).
      //
      // %REVIEW% Should position also be saved by setMark()?
      // (It wasn't in the XSLTC version, but I don't understand why not.)

      final int temp = _position; // Save state
      setMark();

      reset();			// Count the nodes found by this iterator
      do
      {
        _last++;
      }
      while (next() != END);

      gotoMark();		// Restore saved state
      _position = temp;
    }

    return _last;
  }

  /**
   * @return The position of the current node within the set, as defined by
   * XPath. Note that this is one-based, not zero-based.
   */
  public int getPosition()
  {
    return _position == 0 ? 1 : _position;
  }

  /**
   * @return true if this iterator has a reversed axis, else false
   */
  public boolean isReverse()
  {
    return false;
  }

  /**
   * Returns a deep copy of this iterator. Cloned iterators may not be
   * restartable. The iterator being cloned may or may not become
   * non-restartable as a side effect of this operation.
   *
   * @return a deep copy of this iterator.
   */
  public DTMAxisIterator cloneIterator()
  {

    try
    {
      final DTMAxisIteratorBase clone = (DTMAxisIteratorBase) super.clone();

      clone._isRestartable = false;

      // return clone.reset();
      return clone;
    }
    catch (CloneNotSupportedException e)
    {
      throw new org.apache.xml.utils.WrappedRuntimeException(e);
    }
  }

  /**
   * Do any final cleanup that is required before returning the node that was
   * passed in, and then return it. The intended use is
   * <br />
   * <code>return returnNode(node);</code>
   *
   * %REVIEW% If we're calling it purely for side effects, should we really
   * be bothering with a return value? Something like
   * <br />
   * <code> accept(node); return node; </code>
   * <br />
   * would probably optimize just about as well and avoid questions
   * about whether what's returned could ever be different from what's
   * passed in.
   *
   * @param node Node handle which iteration is about to yield.
   *
   * @return The node handle passed in.  */
  protected final int returnNode(final int node)
  {
    _position++;

    return node;
  }

  /**
   * Reset the position to zero. NOTE that this does not change the iteration
   * state, only the position number associated with that state.
   *
   * %REVIEW% Document when this would be used?
   *
   * @return This instance.
   */
  protected final DTMAxisIterator resetPosition()
  {

    _position = 0;

    return this;
  }
  
  /**
   * Returns true if all the nodes in the iteration well be returned in document 
   * order.
   * 
   * @return true as a default.
   */
  public boolean isDocOrdered()
  {
    return true;
  }
  
  /**
   * Returns the axis being iterated, if it is known.
   * 
   * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple 
   * types.
   */
  public int getAxis()
  {
    return -1;
  }
  
  public void setRestartable(boolean isRestartable) {
    _isRestartable = isRestartable;
  }  

  /**
   * Return the node at the given position.
   * 
   * @param position The position
   * @return The node at the given position.
   */
  public int getNodeByPosition(int position)
  {
    if (position > 0) {
      final int pos = isReverse() ? getLast() - position + 1
                                   : position;
      int node;
      while ((node = next()) != DTMAxisIterator.END) {
        if (pos == getPosition()) {
          return node;
        }
      }
    }
    return END;
  }
  
}
