/* DefaultTableModel.java --
   Copyright (C) 2002, 2004, 2005, 2006, 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.table;

import java.io.Serializable;
import java.util.Vector;

import javax.swing.event.TableModelEvent;

/**
 * A two dimensional data structure used to store <code>Object</code> 
 * instances, usually for display in a <code>JTable</code> component.
 * 
 * @author	Andrew Selkirk
 */
public class DefaultTableModel extends AbstractTableModel
  implements Serializable
{
  static final long serialVersionUID = 6680042567037222321L;

  /**
   * Storage for the rows in the table (each row is itself 
   * a <code>Vector</code>).
   */
  protected Vector dataVector;

  /**
   * Storage for the column identifiers.
   */
  protected Vector columnIdentifiers;

  /**
   * Creates an empty table with zero rows and zero columns.
   */
  public DefaultTableModel() 
  {
    this(0, 0);
  }
  
  /**
   * Creates a new table with the specified number of rows and columns.
   * All cells in the table are initially empty (set to <code>null</code>).
   * 
   * @param numRows  the number of rows.
   * @param numColumns  the number of columns.
   */
  public DefaultTableModel(int numRows, int numColumns) 
  {
    Vector defaultNames = new Vector(numColumns);
    Vector data = new Vector(numRows);
    for (int i = 0; i < numColumns; i++) 
      {
        defaultNames.add(super.getColumnName(i));
      }          
    for (int r = 0; r < numRows; r++) 
      {
        Vector tmp = new Vector(numColumns);
        tmp.setSize(numColumns);
        data.add(tmp);
      }
    setDataVector(data, defaultNames);
  }
  
  /**
   * Creates a new table with the specified column names and number of
   * rows.  The number of columns is determined by the number of column
   * names supplied.
   *   
   * @param columnNames the column names.
   * @param numRows the number of rows.
   */
  public DefaultTableModel(Vector columnNames, int numRows) 
  {
    if (numRows < 0)
      throw new IllegalArgumentException("numRows < 0");
    Vector data = new Vector();
    int numColumns = 0;

    if (columnNames != null)
      numColumns = columnNames.size();
    
    while (0 < numRows--) 
      {
        Vector rowData = new Vector();
        rowData.setSize(numColumns);
        data.add(rowData);
      }
    setDataVector(data, columnNames);
  }

  /**
   * Creates a new table with the specified column names and row count.
   * 
   * @param columnNames the column names.
   * @param numRows the number of rows.
   */
  public DefaultTableModel(Object[] columnNames, int numRows) 
  {
    this(convertToVector(columnNames), numRows);
  }
  
  /**
   * Creates a new table with the specified data values and column names.
   * 
   * @param data the data values.
   * @param columnNames the column names.
   */
  public DefaultTableModel(Vector data, Vector columnNames) 
  {
    setDataVector(data, columnNames);
  }

  /**
   * Creates a new table with the specified data values and column names.
   * 
   * @param data the data values.
   * @param columnNames the column names.
   */
  public DefaultTableModel(Object[][] data, Object[] columnNames) 
  {
    this(convertToVector(data), convertToVector(columnNames));
  }

  /**
   * Returns the vector containing the row data for the table.
   * 
   * @return The data vector.
   */
  public Vector getDataVector() 
  {
    return dataVector;
  }

  /**
   * Sets the data and column identifiers for the table.  The data vector
   * contains a <code>Vector</code> for each row in the table - if the
   * number of objects in each row does not match the number of column
   * names specified, the row data is truncated or expanded (by adding
   * <code>null</code> values) as required.
   * 
   * @param data the data for the table (a vector of row vectors).
   * @param columnNames the column names.
   * 
   * @throws NullPointerException if either argument is <code>null</code>.
   */
  public void setDataVector(Vector data, Vector columnNames) 
  {
    if (data == null)
      dataVector = new Vector();
    else
      dataVector = data;
    setColumnIdentifiers(columnNames);
  }

  /**
   * Sets the data and column identifiers for the table.
   * 
   * @param data the data for the table.
   * @param columnNames the column names.
   * 
   * @throws NullPointerException if either argument is <code>null</code>.
   */
  public void setDataVector(Object[][] data, Object[] columnNames) 
  {
    setDataVector(convertToVector(data), 
                  convertToVector(columnNames));
  }
  
  /**
   * Sends the specified <code>event</code> to all registered listeners.
   * This method is equivalent to 
   * {@link AbstractTableModel#fireTableChanged(TableModelEvent)}.
   * 
   * @param event the event.
   */
  public void newDataAvailable(TableModelEvent event) 
  {
    fireTableChanged(event);
  }

  /**
   * Sends the specified <code>event</code> to all registered listeners.
   * This method is equivalent to 
   * {@link AbstractTableModel#fireTableChanged(TableModelEvent)}.
   * 
   * @param event the event.
   */
  public void newRowsAdded(TableModelEvent event) 
  {
    fireTableChanged(event);
  }

  /**
   * Sends the specified <code>event</code> to all registered listeners.
   * This method is equivalent to 
   * {@link AbstractTableModel#fireTableChanged(TableModelEvent)}.
   * 
   * @param event the event.
   */
  public void rowsRemoved(TableModelEvent event) 
  {
    fireTableChanged(event);
  }

  /**
   * Sets the column identifiers, updates the data rows (truncating
   * or padding each row with <code>null</code> values) to match the 
   * number of columns, and sends a {@link TableModelEvent} to all
   * registered listeners.
   * 
   * @param columnIdentifiers the column identifiers.
   */
  public void setColumnIdentifiers(Vector columnIdentifiers) 
  {
    this.columnIdentifiers = columnIdentifiers;
    setColumnCount(columnIdentifiers == null ? 0 : columnIdentifiers.size());
  }
  
  /**
   * Sets the column identifiers, updates the data rows (truncating
   * or padding each row with <code>null</code> values) to match the 
   * number of columns, and sends a {@link TableModelEvent} to all
   * registered listeners.
   * 
   * @param columnIdentifiers the column identifiers.
   */
  public void setColumnIdentifiers(Object[] columnIdentifiers) 
  {
    setColumnIdentifiers(convertToVector(columnIdentifiers));
  }

  /**
   * This method is obsolete, use {@link #setRowCount(int)} instead.
   * 
   * @param numRows the number of rows.
   */
  public void setNumRows(int numRows) 
  {
    setRowCount(numRows);
  }

  /**
   * Sets the number of rows in the table.  If <code>rowCount</code> is less
   * than the current number of rows in the table, rows are discarded.
   * If <code>rowCount</code> is greater than the current number of rows in
   * the table, new (empty) rows are added.
   * 
   * @param rowCount the row count.
   */
  public void setRowCount(int rowCount) 
  {
    int existingRowCount = dataVector.size();
    if (rowCount < existingRowCount) 
    {
      dataVector.setSize(rowCount);
      fireTableRowsDeleted(rowCount, existingRowCount - 1);      
    }
    else 
    {
      int rowsToAdd = rowCount - existingRowCount;
      addExtraRows(rowsToAdd, columnIdentifiers.size());
      fireTableRowsInserted(existingRowCount, rowCount - 1);
    }
  }

  /**
   * Sets the number of columns in the table.  Existing rows are truncated
   * or padded with <code>null</code> values to match the new column count.
   * A {@link TableModelEvent} is sent to all registered listeners.
   * 
   * @param columnCount the column count.
   */
  public void setColumnCount(int columnCount) 
  {
    for (int i = 0; i < dataVector.size(); ++i)
      {
        ((Vector) dataVector.get(i)).setSize(columnCount);
      }
    if (columnIdentifiers != null)  
      columnIdentifiers.setSize(columnCount);
    fireTableStructureChanged();
  }

  /**
   * Adds a column with the specified name to the table.  All cell values
   * for the column are initially set to <code>null</code>.
   * 
   * @param columnName the column name (<code>null</code> permitted).
   */
  public void addColumn(Object columnName) 
  {
    addColumn(columnName, (Object[]) null);
  }

  /**
   * Adds a column with the specified name and data values to the table.  
   * 
   * @param columnName the column name (<code>null</code> permitted).
   * @param columnData the column data.
   */
  public void addColumn(Object columnName, Vector columnData) 
  {
    Object[] dataArray = null;
    if (columnData != null) 
    {
      int rowCount = dataVector.size();
      if (columnData.size() < rowCount)
        columnData.setSize(rowCount);
      dataArray = columnData.toArray();
    }
    addColumn(columnName, dataArray);
  }

  /**
   * Adds a column with the specified name and data values to the table.
   * 
   * @param columnName the column name (<code>null</code> permitted).
   * @param columnData the column data.
   */
  public void addColumn(Object columnName, Object[] columnData) 
  {
    if (columnData != null)
    {
      // check columnData array for cases where the number of items
      // doesn't match the number of rows in the existing table
      if (columnData.length > dataVector.size()) 
      {
        int rowsToAdd = columnData.length - dataVector.size();
        addExtraRows(rowsToAdd, columnIdentifiers.size());
      }
      else if (columnData.length < dataVector.size())
      {
        Object[] tmp = new Object[dataVector.size()];
        System.arraycopy(columnData, 0, tmp, 0, columnData.length);
        columnData = tmp;
      }
    }
    for (int i = 0; i < dataVector.size(); ++i)
      {
        ((Vector) dataVector.get(i)).add(columnData == null ? null : columnData[i]);
      }
    columnIdentifiers.add(columnName);
    fireTableStructureChanged();
  }

  /**
   * Adds a new row containing the specified data to the table and sends a
   * {@link TableModelEvent} to all registered listeners.
   * 
   * @param rowData the row data (<code>null</code> permitted).
   */
  public void addRow(Vector rowData) 
  {
    int rowIndex = dataVector.size();
    dataVector.add(rowData);
    newRowsAdded(new TableModelEvent(
      this, rowIndex, rowIndex, -1, TableModelEvent.INSERT)
    );
  }

  /**
   * Adds a new row containing the specified data to the table and sends a
   * {@link TableModelEvent} to all registered listeners.
   * 
   * @param rowData the row data (<code>null</code> permitted).
   */
  public void addRow(Object[] rowData) 
  {
    addRow(convertToVector(rowData));
  }

  /**
   * Inserts a new row into the table.
   * 
   * @param row the row index.
   * @param rowData the row data.
   */
  public void insertRow(int row, Vector rowData) 
  {
    dataVector.add(row, rowData);
    fireTableRowsInserted(row, row);
  }

  /**
   * Inserts a new row into the table.
   * 
   * @param row the row index.
   * @param rowData the row data.
   */
  public void insertRow(int row, Object[] rowData) 
  {
    insertRow(row, convertToVector(rowData));
  }

  /**
   * Moves the rows from <code>startIndex</code> to <code>endIndex</code>
   * (inclusive) to the specified row.
   * 
   * @param startIndex the start row.
   * @param endIndex the end row.
   * @param toIndex the row to move to.
   */
  public void moveRow(int startIndex, int endIndex, int toIndex) 
  {
    Vector removed = new Vector();
    for (int i = endIndex; i >= startIndex; i--)
    {
      removed.add(this.dataVector.remove(i));
    }
    for (int i = 0; i <= endIndex - startIndex; i++) 
    {
      dataVector.insertElementAt(removed.get(i), toIndex);  
    }
    int firstRow = Math.min(startIndex, toIndex);
    int lastRow = Math.max(endIndex, toIndex + (endIndex - startIndex));
    fireTableRowsUpdated(firstRow, lastRow);
  }

  /**
   * Removes a row from the table and sends a {@link TableModelEvent} to
   * all registered listeners.
   * 
   * @param row the row index.
   */
  public void removeRow(int row) 
  {
    dataVector.remove(row);
    fireTableRowsDeleted(row, row);
  }

  /**
   * Returns the number of rows in the model.
   * 
   * @return The row count.
   */
  public int getRowCount() 
  {
    return dataVector.size();
  }

  /**
   * Returns the number of columns in the model.
   * 
   * @return The column count.
   */
  public int getColumnCount() 
  {
    return columnIdentifiers == null ? 0 : columnIdentifiers.size();
  }

  /**
   * Get the name of the column. If the column has the column identifier set,
   * the return value is the result of the .toString() method call on that
   * identifier. If the identifier is not explicitly set, the returned value
   * is calculated by {@link AbstractTableModel#getColumnName(int)}.
   * 
   * @param column the column index.
   * 
   * @return The column name.
   */
  public String getColumnName(int column)
  {
    String result = "";
    if (columnIdentifiers == null) 
      result = super.getColumnName(column);
    else 
    {
      if (column < getColumnCount())
      {
        checkSize();
        Object id = columnIdentifiers.get(column);
        if (id != null) 
          result = id.toString();
        else
          result = super.getColumnName(column);
      }
      else
        result = super.getColumnName(column);
    }
    return result;
  }

  /**
   * Returns <code>true</code> if the specified cell can be modified, and
   * <code>false</code> otherwise.  For this implementation, the method
   * always returns <code>true</code>.
   * 
   * @param row the row index.
   * @param column the column index.
   * 
   * @return <code>true</code> in all cases.
   */
  public boolean isCellEditable(int row, int column) 
  {
    return true;
  }

  /**
   * Returns the value at the specified cell in the table.
   * 
   * @param row the row index.
   * @param column the column index.
   * 
   * @return The value (<code>Object</code>, possibly <code>null</code>) at 
   *         the specified cell in the table.
   */
  public Object getValueAt(int row, int column) 
  {
    return ((Vector) dataVector.get(row)).get(column);
  }

  /**
   * Sets the value for the specified cell in the table and sends a 
   * {@link TableModelEvent} to all registered listeners.
   * 
   * @param value the value (<code>Object</code>, <code>null</code> permitted).
   * @param row the row index.
   * @param column the column index.
   */
  public void setValueAt(Object value, int row, int column) 
  {
    ((Vector) dataVector.get(row)).set(column, value);
    fireTableCellUpdated(row, column);
  }

  /**
   * Converts the data array to a <code>Vector</code>.
   * 
   * @param data the data array (<code>null</code> permitted).
   * 
   * @return A vector (or <code>null</code> if the data array 
   *         is <code>null</code>).
   */
  protected static Vector convertToVector(Object[] data) 
  {
    if (data == null)
      return null;
    Vector vector = new Vector(data.length);
    for (int i = 0; i < data.length; i++) 
      vector.add(data[i]);
    return vector;          
  }
  
  /**
   * Converts the data array to a <code>Vector</code> of rows.
   * 
   * @param data the data array (<code>null</code> permitted).
   * 
   * @return A vector (or <code>null</code> if the data array 
   *         is <code>null</code>.
   */
  protected static Vector convertToVector(Object[][] data) 
  {
    if (data == null)
      return null;
    Vector vector = new Vector(data.length);
    for (int i = 0; i < data.length; i++)
      vector.add(convertToVector(data[i]));
    return vector;
  }

  /**
   * This method adds some rows to <code>dataVector</code>.
   *
   * @param rowsToAdd number of rows to add
   * @param nbColumns size of the added rows
   */
  private void addExtraRows(int rowsToAdd, int nbColumns)
  {
    for (int i = 0; i < rowsToAdd; i++) 
      {
        Vector tmp = new Vector();
        tmp.setSize(columnIdentifiers.size());
        dataVector.add(tmp);
      } 
  }

  /**
   * Checks the real columns/rows sizes against the ones returned by
   * <code>getColumnCount()</code> and <code>getRowCount()</code>.
   * If the supposed one are bigger, then we grow <code>columIdentifiers</code>
   * and <code>dataVector</code> to their expected size.
   */
  private void checkSize()
  {
    int columnCount = getColumnCount();
    int rowCount = getRowCount();
    
    if (columnCount > columnIdentifiers.size())
      columnIdentifiers.setSize(columnCount);
           
    if (rowCount > dataVector.size())
      {
        int rowsToAdd = rowCount - dataVector.size();
        addExtraRows(rowsToAdd, columnCount);
      }
  }
}
