/*
 * Copyright (C) 2007 Esmertec AG.
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed 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.
 */

package com.android.mms.dom;

import java.util.ArrayList;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class NodeListImpl implements NodeList {
    private ArrayList<Node> mSearchNodes;
    private ArrayList<Node> mStaticNodes;
    private Node mRootNode;
    private String mTagName;
    private boolean mDeepSearch;

    /*
     * Internal Interface
     */

    /**
     * Constructs a NodeList by searching for all descendants or the direct
     * children of a root node with a given tag name.
     * @param rootNode The root <code>Node</code> of the search.
     * @param tagName The tag name to be searched for. If null, all descendants
     *              will be returned.
     * @param deep Limit the search to the direct children of rootNode if false,
     *              to all descendants otherwise.
     */
    public NodeListImpl(Node rootNode, String tagName, boolean deepSearch) {
        mRootNode = rootNode;
        mTagName  = tagName;
        mDeepSearch = deepSearch;
    }

    /**
     * Constructs a NodeList for a given static node list.
     * @param nodes The static node list.
     */
    public NodeListImpl(ArrayList<Node> nodes) {
        mStaticNodes = nodes;
    }

    /*
     * NodeListImpl Interface
     */

    public int getLength() {
        if (mStaticNodes == null) {
            fillList(mRootNode);
            return mSearchNodes.size();
        } else {
            return mStaticNodes.size();
        }
    }

    public Node item(int index) {
        Node node = null;
        if (mStaticNodes == null) {
            fillList(mRootNode);
            try {
                node = mSearchNodes.get(index);
            } catch (IndexOutOfBoundsException e) {
                // Do nothing and return null
            }
        } else {
            try {
                node = mStaticNodes.get(index);
            } catch (IndexOutOfBoundsException e) {
                // Do nothing and return null
            }
        }
        return node;
    }

    /**
     * A preorder traversal is done in the following order:
     * <ul>
     *   <li> Visit root.
     *   <li> Traverse children from left to right in preorder.
     * </ul>
     * This method fills the live node list.
     * @param The root of preorder traversal
     * @return The next match
     */
    private void fillList(Node node) {
        // (Re)-initialize the container if this is the start of the search.
        // Visit the root of this iteration otherwise.
        if (node == mRootNode) {
            mSearchNodes = new ArrayList<Node>();
        } else {
            if ((mTagName == null) || node.getNodeName().equals(mTagName)) {
                mSearchNodes.add(node);
            }
        }

        // Descend one generation...
        node = node.getFirstChild();

        // ...and visit in preorder the children if we are in deep search
        // or directly add the children to the list otherwise.
        while (node != null) {
            if (mDeepSearch) {
                fillList(node);
            } else {
                if ((mTagName == null) || node.getNodeName().equals(mTagName)) {
                    mSearchNodes.add(node);
                }
            }
            node = node.getNextSibling();
        }
    }
}
