/**
 * @author mitsunoriogihara
 *
 */
public class ArrayBasedStack<E> implements StackInt<E> {

	private Object[] data;
	private int INIT_SIZE = 100;
	private int size;
	private int capacity;
	ArrayBasedStack() {
		data = new Object[INIT_SIZE];
		size = 0;
		capacity = INIT_SIZE;
	}
	
	private void expand() {
		Object[] newData = new Object[capacity*2];
		for (int i=0; i<capacity; i++) {
			newData[i] = data[i];
		}
		capacity *= 2;
		data = newData;
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		StackInt<Integer> s = new ArrayBasedStack<Integer>();
		for (int i=0; i<200; i++) {
			s.push(i);
		}
		while (!s.empty()) {
			System.out.println(s.pop());
		}
		s.push(10);
		System.out.println(s.peek());
		System.out.println(s.pop());
		try {
			System.out.println(s.peek());
		} catch (IndexOutOfBoundsException e) {
			System.out.println(e.getMessage());
		}
	}

	/* (non-Javadoc)
	 * @see chapter3Stack.StackInt#isEmpty()
	 */
	@Override
	public boolean empty() {
		return (size==0);
	}


	/* (non-Javadoc)
	 * @see chapter3Stack.StackInt#peek()
	 */
	@Override
	public E peek() {
		if (size==0) throw new IndexOutOfBoundsException("stack empty");
		return (E)data[size-1];
	}

	/* (non-Javadoc)
	 * @see chapter3Stack.StackInt#pop()
	 */
	@Override
	public E pop() {
		if (size==0) throw new IndexOutOfBoundsException("stack empty");
		Object o = data[size-1];
		size--;
		return (E)o;
	}

	/* (non-Javadoc)
	 * @see chapter3Stack.StackInt#push(java.lang.Object)
	 */
	@Override
	public void push(E o) {
		if (size==capacity) {
			expand();
		}
		data[size] = o;
		size++;
	}

}
