/*
 * 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.
 */

package org.apache.axis2.util;

import java.util.ArrayList;
import java.util.EmptyStackException;

/**
 * An implementation of the {@link java.util.Stack} API that is based on an <code>ArrayList</code>
 * instead of a <code>Vector</code>, so it is not synchronized to protect against multi-threaded
 * access.  The implementation is therefore operates faster in environments where you do not need to
 * worry about multiple thread contention.
 * <p/>
 * The removal order of an <code>ArrayStack</code> is based on insertion order: The most recently
 * added element is removed first.  The iteration order is <i>not</i> the same as the removal order.
 *  The iterator returns elements from the bottom up, whereas the {@link #remove()} method removes
 * them from the top down.
 * <p/>
 * Unlike <code>Stack</code>, <code>ArrayStack</code> accepts null entries.
 */
public class ArrayStack extends ArrayList {

    /** Ensure serialization compatibility */
    private static final long serialVersionUID = 2130079159931574599L;

    /**
     * Constructs a new empty <code>ArrayStack</code>. The initial size is controlled by
     * <code>ArrayList</code> and is currently 10.
     */
    public ArrayStack() {
        super();
    }

    /**
     * Constructs a new empty <code>ArrayStack</code> with an initial size.
     *
     * @param initialSize the initial size to use
     * @throws IllegalArgumentException if the specified initial size is negative
     */
    public ArrayStack(int initialSize) {
        super(initialSize);
    }

    /**
     * Return <code>true</code> if this stack is currently empty.
     * <p/>
     * This method exists for compatibility with <code>java.util.Stack</code>. New users of this
     * class should use <code>isEmpty</code> instead.
     *
     * @return true if the stack is currently empty
     */
    public boolean empty() {
        return isEmpty();
    }

    /**
     * Returns the top item off of this stack without removing it.
     *
     * @return the top item on the stack
     * @throws EmptyStackException if the stack is empty
     */
    public Object peek() throws EmptyStackException {
        int n = size();
        if (n <= 0) {
            throw new EmptyStackException();
        } else {
            return get(n - 1);
        }
    }

    /**
     * Returns the n'th item down (zero-relative) from the top of this stack without removing it.
     *
     * @param n the number of items down to go
     * @return the n'th item on the stack, zero relative
     * @throws EmptyStackException if there are not enough items on the stack to satisfy this
     *                             request
     */
    public Object peek(int n) throws EmptyStackException {
        int m = (size() - n) - 1;
        if (m < 0) {
            throw new EmptyStackException();
        } else {
            return get(m);
        }
    }

    /**
     * Pops the top item off of this stack and return it.
     *
     * @return the top item on the stack
     * @throws EmptyStackException if the stack is empty
     */
    public Object pop() throws EmptyStackException {
        int n = size();
        if (n <= 0) {
            throw new EmptyStackException();
        } else {
            return remove(n - 1);
        }
    }

    /**
     * Pushes a new item onto the top of this stack. The pushed item is also returned. This is
     * equivalent to calling <code>add</code>.
     *
     * @param item the item to be added
     * @return the item just pushed
     */
    public Object push(Object item) {
        add(item);
        return item;
    }

    /**
     * Returns the one-based position of the distance from the top that the specified object exists
     * on this stack, where the top-most element is considered to be at distance <code>1</code>.  If
     * the object is not present on the stack, return <code>-1</code> instead.  The
     * <code>equals()</code> method is used to compare to the items in this stack.
     *
     * @param object the object to be searched for
     * @return the 1-based depth into the stack of the object, or -1 if not found
     */
    public int search(Object object) {
        int i = size() - 1;        // Current index
        int n = 1;                 // Current distance
        while (i >= 0) {
            Object current = get(i);
            if ((object == null && current == null) ||
                    (object != null && object.equals(current))) {
                return n;
            }
            i--;
            n++;
        }
        return -1;
    }

    /**
     * Returns the element on the top of the stack.
     *
     * @return the element on the top of the stack
     * @throws EmptyStackException if the stack is empty
     */
    public Object get() {
        int size = size();
        if (size == 0) {
            throw new EmptyStackException();
        }
        return get(size - 1);
    }

    /**
     * Removes the element on the top of the stack.
     *
     * @return the removed element
     * @throws EmptyStackException if the stack is empty
     */
    public Object remove() {
        int size = size();
        if (size == 0) {
            throw new EmptyStackException();
        }
        return remove(size - 1);
    }

}
