/*
 * 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.fop.fo;

import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * Kind of a super-iterator that iterates through child nodes of an FONode,
 * in turn managing character iterators for each of them. Caveat: Because this
 * class is itself a CharIterator, and manages a collection of CharIterators, it
 * is easy to get confused.
 */
public class RecursiveCharIterator extends CharIterator {
    /** parent node for whose child nodes this iterator iterates */
    private FONode fobj;
    /** iterator for the child nodes */
    private Iterator childIter;

    /** current child object that is being managed by childIter*/
    private FONode curChild;
    /** CharIterator for curChild's characters */
    private CharIterator curCharIter;

    /**
     * Constructor which creates an iterator for all child nodes
     * @param fobj FONode for which an iterator should be created
     */
    public RecursiveCharIterator(FObj fobj) {
        // Set up first child iterator
        this.fobj = fobj;
        this.childIter = fobj.getChildNodes();
        getNextCharIter();
    }

    /**
     * Constructor which creates an iterator for only some child nodes
     * @param fobj FObj for which an iterator should be created
     * @param child FONode of the first child to include in iterator
     */
    public RecursiveCharIterator(FObj fobj, FONode child) {
        // Set up first child iterator
        this.fobj = fobj;
        this.childIter = fobj.getChildNodes(child);
        getNextCharIter();
    }

    /**
     * @return clone of this, cast as a CharIterator
     */
    public CharIterator mark() {
        return (CharIterator) this.clone();
    }

    /**
     * @return a clone of this
     */
    public Object clone() {
        RecursiveCharIterator ci = (RecursiveCharIterator) super.clone();
        ci.childIter = fobj.getChildNodes(ci.curChild);
        // Need to advance to the next child, else we get the same one!!!
        ci.childIter.next();
        ci.curCharIter = (CharIterator) curCharIter.clone();
        return ci;
    }

    /**
     * Replaces the current character in the CharIterator with a specified
     * character
     * @param c the character which should be used to replace the current
     * character
     */
    public void replaceChar(char c) {
        if (curCharIter != null) {
            curCharIter.replaceChar(c);
        }
    }

    /**
     * advances curChild to the next child in the collection, and curCharIter
     * to the CharIterator for that item, or sets them to null if the iterator
     * has no more items
     */
    private void getNextCharIter() {
        if (childIter != null && childIter.hasNext()) {
            this.curChild = (FONode) childIter.next();
            this.curCharIter = curChild.charIterator();
        } else {
            curChild = null;
            curCharIter = null;
        }
    }

    /**
     * @return true if there are more items in the CharIterator
     */
    public boolean hasNext() {
        while (curCharIter != null) {
            if (!curCharIter.hasNext()) {
                getNextCharIter();
            } else {
                return true;
            }
        }
        return false;
    }

    /**
     * {@inheritDoc}
     */
    public char nextChar() throws NoSuchElementException {
        if (curCharIter != null) {
            return curCharIter.nextChar();
        } else {
            throw new NoSuchElementException();
        }
    }

    /**
     * {@inheritDoc}
     */
    public void remove() {
        if (curCharIter != null) {
            curCharIter.remove();
        }
    }
}

