package nxm.ucl.libg;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Vector;
import javax.swing.AbstractListModel;

/** Generic Data list model for JList that stores a Vector of data.
    Allows initialization with array of Objects.
    Allows removing all items from the data model.
    Allows adding an array of Objects to the data model.
    Allows sorting with a specified Comparator or null for natural order.

   TODO: remove this in NeXtMidas 3.5.x or later

   @author Neon Ngo
   @since NeXtMidas 2.5.0
   @version $Id: DataListModel.java,v 1.7 2013/01/04 21:10:15 ntn Exp $
*/
@SuppressWarnings("rawtypes") // <-- NOTE: JDK7 has some rawtypes Xlint warnings that CANNOT be fixed since we still support JDK6
class DataListModel extends AbstractListModel {
  /** NOTE: this should be changed if the structure/fields of this class changes. */
  private static final long serialVersionUID = 2012122801331L; // for Serializable interface

  private Vector<Object> data;

  public DataListModel() {
    data = new Vector<Object>();
  }

  /** Constructs a Model object initialized with an array of Objects.
      @param objects  an array of Objects
  */
  public DataListModel(final Object[] objects) {
    data = new Vector<Object>();
    if (objects == null || objects.length <= 0) {
      return; // ignore null & empty objects
    }
    data.ensureCapacity(objects.length);

    for (int i = 0, len = objects.length; i<len; i++) {
      data.addElement(objects[i]);
    }
  }

  public int getSize() {
    return data.size();
  }

  public Object getElementAt(int index) {
    if ( index >= 0 && index < data.size() ) {
      return data.elementAt(index);
    } else {
      return null;
    }
  }

  /** Add an Object to the list model */
  public void addElement(Object anObject) {
    data.addElement(anObject);
    fireIntervalAdded(this,data.size()-1, data.size()-1);
  }

  /** Add all items in array of Objects to the list model */
  public void addElements(Object[] objects) {
    if (objects == null || objects.length <= 0) return; // ignore null & empty objects

    int index0 = data.size();
    data.addAll(Arrays.asList(objects));
    fireIntervalAdded(this, index0, data.size()-1); // fires event as a group to be more efficient
  }

  /** Add all items in strings array to the list model, with a prefix. */
  public void addElements(String prefix, String[] strings) {
    if (strings == null || strings.length <= 0) {
      return; // ignore null & empty strings
    }
    int index0 = data.size();

    for (int i = 0, len = strings.length; i<len; i++) {
      data.addElement(prefix + strings[i]);
    }
    // fires event as a group to be more efficient
    fireIntervalAdded(this, index0, data.size()-1);
  }

  /** Empties the list. */
  public void removeAllElements() {
    if (data.size() > 0) {
      int lastIndex = data.size() - 1;
      data.removeAllElements();
      fireIntervalRemoved(this, 0, lastIndex);
    }
  }

  /** Sort list with the specified comparator using {@link Collections#sort(java.util.List, Comparator)}. */
  public void sortBy(Comparator<Object> comparator) {
    Collections.sort(data, comparator);
    int lastIndex = data.size() - 1;
    fireContentsChanged(this, 0, lastIndex);
  }
}
