/* 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., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 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;

/**
 * The default implementation of {@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 &gt; 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);
  }
}
