/* DefaultListModel.java --
   Copyright (C) 2002, 2004, 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package javax.swing;

import java.util.Enumeration;
import java.util.Vector;

/**
 * This is a default subclass of the {@link AbstractListModel}, used by
 * {@link javax.swing.JList} and similar objects as the model of a list of
 * values. The implementation is based on an underlying {@link
 * java.util.Vector}.
 *
 * @author Andrew Selkirk
 * @author Graydon Hoare (graydon@redhat.com)
 */

public class DefaultListModel extends AbstractListModel
{
  private static final long serialVersionUID = 2315945659722172272L;

  /**
   * The vector of elements in this list model.
   */
  private Vector elements = new Vector();

  /**
   * Gets an element of the list at the provided index.
   *
   * @param index The index of the element to get
   *
   * @return The object at the given index
   *
   * @throws ArrayIndexOutOfBoundsException If the provided index is
   * outside the bounds of the list <code>[0, size())</code>
   */
  public Object elementAt(int index)
  {
    return elements.elementAt(index);
  }

  /**
   * Convert the list to a string representation.
   *
   * @return A string representation of the list
   */
  public String toString()
  {
    return elements.toString();
  }

  /**
   * Gets the first index of a particular element in the list.
   *
   * @param element The element to search for
   *
   * @return The first index in the list at which an object
   * <code>obj</code> exists such that <code>obj.equals(element)</code> is
   * <code>true</code>; if no such object exists, the method returns
   * <code>-1</code>
   */
  public int indexOf(Object element)
  {
    return elements.indexOf(element);
  }

  /**
   * Gets the first index of a particular element in a list which occurs
   * <em>at or after</em> a particular index.
   *
   * @param element The element to search for
   * @param startIndex The index to begin searching at
   *
   * @return The first index in the list, greater than or equal to
   * <code>startIndex</code>, at which an object <code>obj</code> exists
   * such that <code>obj.equals(element)</code> is <code>true</code>; if no
   * such object exists, the method returns <code>-1</code>
   */
  public int indexOf(Object element, int startIndex)
  {
    return elements.indexOf(element, startIndex);
  }

  /**
   * Gets the last index of a particular element in the list.
   *
   * @param element The element to search for
   *
   * @return The last index in the list at which an object
   * <code>obj</code> exists such that <code>obj.equals(element)</code> is
   * <code>true</code>; if no such object exists, the method returns
   * <code>-1</code>
   */
  public int lastIndexOf(Object element)
  {
    return elements.lastIndexOf(element);
  }

  /**
   * Gets the last index of a particular element in a list which occurs
   * <em>at or before</em> a particular index.
   *
   * @param element The element to search for
   * @param endIndex The index to finish searching at
   *
   * @return The last index in the list, less than to or equal to
   * <code>endIndexIndex</code>, at which an object <code>obj</code> exists
   * such that <code>obj.equals(element)</code> is <code>true</code>; if no
   * such object exists, the method returns <code>-1</code>
   */
  public int lastIndexOf(Object element, int endIndex)
  {
    return elements.lastIndexOf(element, endIndex);
  }

  /**
   * Gets the list element at a particular index.
   *
   * @param index The index to get the list value at
   *
   * @return The list value at the provided index
   *
   * @throws ArrayIndexOutOfBoundsException If the provided index is
   * outside the bounds of the list <code>[0, size())</code>
   */
  public Object get(int index)
  {
    return elements.get(index);
  }

  /**
   * Sets the list element at a particular index.
   *
   * @param index The list index at which to set a value 
   * @param element The value to set at the specified index
   *
   * @return The value previously held at the specified index
   *
   * @throws ArrayIndexOutOfBoundsException If the provided index is
   * outside the bounds of the list <code>[0, size())</code>
   */
  public Object set(int index, Object element)
  {
    Object result;
    result = elements.set(index, element);
    fireContentsChanged(this, index, index);
    return result;
  }

  /**
   * Inserts an element at a particular index in the list. Each element at
   * index <code>i >= index</code> is shifted to position <code>i+1</code>.
   * If <code>index</code> is equal to <code>size()</code>, this is
   * equivalent to appending an element to the array. Any
   * <code>index</code> greater than <code>size()</code> is illegal.
   *
   * @param index The index to insert the element at
   * @param element The element to insert at the index
   *
   * @throws ArrayIndexOutOfBoundsException If the provided index is
   * outside the bounds <code>[0, size()]</code>
   */
  public void add(int index, Object element)
  {
    elements.add(index, element);
    fireIntervalAdded(this, index, index);
  }

  /**
   * Inserts an element at the end of the list. This is equivalent to
   * calling <code>list.add(list.size(), element)</code>.
   *
   * @param element The element to add to the list
   */
  public void addElement(Object element)
  {
    int s = elements.size();
    elements.add(element);
    fireIntervalAdded(this, s, s);
  }

  /**
   * Gets the number of elements in the list.
   *
   * @return The number of elements in the list
   */
  public int size()
  {
    return elements.size();
  }

  /**
   * Gets an array containing the elements of the list.
   *
   * @return An array of the objects in the list, in the order they occur
   * in the list
   */
  public Object[] toArray()
  {
    return elements.toArray();
  }

  /**
   * Determines whether a particular element is a member of the list.
   *
   * @param element The element to search for
   *
   * @return <code>true</code> if <code>element</code> is a member of the
   * list, otherwise <code>false</code>
   */
  public boolean contains(Object element)
  {
    return elements.contains(element);
  }

  /**
   * Copies the list into a provided array. The provided array must be at
   * least as large as the list.
   *
   * @param array The array to copy the list into
   * 
   * @throws IndexOutOfBoundsException if the array is too small to hold the
   * elements of the list
   */
  public void copyInto(Object[] array)
  {
    elements.copyInto(array);
  }

  /**
   * Erases all the elements of the list, setting the list's size to 0.
   */
  public void clear()
  {
    int s = elements.size();
    if (s > 0)
    {
      elements.clear();
      fireIntervalRemoved(this, 0, s - 1);
    }
  }

  /**
   * Removes the element at a particular index from the list.
   *
   * @param index The index of the element to remove
   *
   * @return The value at the index, which has been removed from the list
   *
   * @throws ArrayIndexOutOfBoundsException If the provided index is
   * outside the bounds of the list <code>[0, size())</code>
   */
  public Object remove(int index)
  {
    Object result;
    result = elements.remove(index);
    fireIntervalRemoved(this, index, index);
    return result;
  }

  /**
   * Determines whether the list is empty.
   *
   * @return <code>true</code> if the list is empty, otherwise
   * <code>false</code>
   */
  public boolean isEmpty()
  {
    return elements.isEmpty();
  }

  /**
   * Returns an {@link java.util.Enumeration} over the elements of the list.
   *
   * @return A new enumeration which iterates over the list
   */
  public Enumeration elements()
  {
    return elements.elements();
  }

  /**
   * Sets the capacity of the list to be equal to its size. The list's capacity
   * is the number of elements it can hold before it needs to be reallocated.
   * The list's size is the number of elements it currently holds. 
   */
  public void trimToSize()
  {
    elements.trimToSize();
  }

  /**
   * Ensures that the list's capacity is at least equal to
   * <code>size</code>. The list's capacity is the number of elements it
   * can hold before it needs to be reallocated.
   *
   * @param size The capacity to ensure the list can hold
   */
  public void ensureCapacity(int size)
  {
    elements.ensureCapacity(size);
  }

  /**
   * Sets the size of the list to a particular value. If the specified size
   * is greater than the current size, the values at the excess list
   * indices are set to <code>null</code>.  If the specified size is less
   * than the current size, the excess elements are removed from the list.
   *
   * @param size The new size to set the list to
   */
  public void setSize(int size)
  {
    int oldSize = elements.size();
    elements.setSize(size);
    if (oldSize < size) 
    {
      fireIntervalAdded(this, oldSize, size - 1); 
    }
    else if (oldSize > size) 
    {
      this.fireIntervalRemoved(this, size, oldSize - 1);
    }
  }

  /**
   * Gets the capacity of the list. The list's capacity is the number of
   * elements it can hold before it needs to be reallocated. 
   *
   * @return The capacity of the list
   */
  public int capacity()
  {
    return elements.capacity();
  }

  /**
   * Gets the first element in the list.
   *
   * @return The first element in the list
   */
  public Object firstElement()
  {
    return elements.firstElement();
  }

  /**
   * Gets the last element in the list.
   *
   * @return The last element in the list
   */
  public Object lastElement()
  {
    return elements.lastElement();
  }

  /**
   * Sets the list element at a particular index.
   *
   * @param element The value to set at the specified index
   * @param index The list index at which to set a value 
   *
   * @throws ArrayIndexOutOfBoundsException If the provided index is
   * outside the bounds of the list <code>[0, size())</code>
   */
  public void setElementAt(Object element, int index)
  {
    elements.setElementAt(element, index);
    fireContentsChanged(this, index, index);
  }

  /**
   * Removes the element at a particular index from the list.
   *
   * @param index The index of the element to remove
   *
   * @throws ArrayIndexOutOfBoundsException If the provided index is
   * outside the bounds of the list <code>[0, size())</code>
   */
  public void removeElementAt(int index)
  {
    elements.remove(index);
    fireIntervalRemoved(this, index, index);
  }

  /**
   * Inserts an element at a particular index in the list. Each element at
   * index <code>i >= index</code> is shifted to position <code>i+1</code>.
   * If <code>index</code> is equal to <code>size()</code>, this is
   * equivalent to appending an element to the array. Any
   * <code>index</code> greater than <code>size()</code> is illegal.
   *
   * @param element The element to insert at the index
   * @param index The index to insert the element at
   *
   * @throws ArrayIndexOutOfBoundsException If the provided index is
   * outside the bounds <code>[0, size()]</code>
   */
  public void insertElementAt(Object element, int index)
  {
    elements.insertElementAt(element, index);
    fireIntervalAdded(this, index, index);
  }

  /**
   * Removes the first occurrence of a particular element in the list. If the
   * element does not exist in the list, nothing happens.
   *
   * @param element The element to remove
   *
   * @return <code>true</code> if the element existed in the list (and was
   * removed), <code>false</code> otherwise
   */
  public boolean removeElement(Object element)
  {
    int index;
    index = elements.indexOf(element);
    if (index != -1)
      {
        elements.remove(index);
        fireIntervalRemoved(this, index, index);
        return true;
      }
    return false;
  }

  /**
   * Remove all elements in the list.
   */
  public void removeAllElements()
  {
    int size;
    size = size();
    if (size > 0)
      {
        elements.clear();
        fireIntervalRemoved(this, 0, size - 1);
      }
  }

  /**
   * Remove all elements between <code>startIndex</code> and
   * <code>endIndex</code> inclusive.
   *
   * @param startIndex The first index in the range to remove
   * @param endIndex The last index in the range to remove
   *
   * @throws ArrayIndexOutOfBoundsException if either index is outside the
   * valid range of indices for this list <code>[0, size())</code>
   * @throws IllegalArgumentException if <code>startIndex > endIndex</code>
   */
  public void removeRange(int startIndex, int endIndex)
  {
    int index;
    if (startIndex > endIndex)
      throw new IllegalArgumentException();
    for (index = endIndex; index >= startIndex; index--)
      elements.remove(index);
    fireIntervalRemoved(this, startIndex, endIndex);
  }

  /**
   * Gets the size of the list.
   *
   * @return The number of elements currently in the list
   */
  public int getSize()
  {
    return elements.size();
  }

  /**
   * Gets the list element at a particular index.
   *
   * @param index The index to get the list value at
   *
   * @return The list value at the provided index
   *
   * @throws ArrayIndexOutOfBoundsException If the provided index is
   * outside the bounds of the list <code>[0, size())</code>
   */
  public Object getElementAt(int index)
  {
    return elements.get(index);
  }
}
