/* DefaultTableColumnModel.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.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.Vector;

import javax.swing.DefaultListSelectionModel;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.EventListenerList;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;

/**
 * A model that stores information about the columns used in a {@link JTable}.
 * 
 * @see JTable#setColumnModel(TableColumnModel)
 * 
 * @author	Andrew Selkirk
 */
public class DefaultTableColumnModel
  implements TableColumnModel, PropertyChangeListener, ListSelectionListener,
             Serializable
{
  private static final long serialVersionUID = 6580012493508960512L;

  /**
   * Storage for the table columns.
   */
  protected Vector tableColumns;

  /**
   * A selection model that keeps track of column selections.
   */
  protected ListSelectionModel selectionModel;

  /**
   * The space between the columns (the default value is <code>1</code>).
   */
  protected int columnMargin;

  /**
   * Storage for the listeners registered with the model.
   */
  protected EventListenerList listenerList = new EventListenerList();

  /**
   * A change event used when notifying listeners of a change to the 
   * <code>columnMargin</code> field.  This single event is reused for all
   * notifications (it is lazily instantiated within the 
   * {@link #fireColumnMarginChanged()} method).
   */
  protected transient ChangeEvent changeEvent;

  /**
   * A flag that indicates whether or not columns can be selected. 
   */
  protected boolean columnSelectionAllowed;

  /**
   * The total width of all the columns in this model.
   */
  protected int totalColumnWidth;

  /**
   * Creates a new table column model with zero columns.  A default column 
   * selection model is created by calling {@link #createSelectionModel()}.
   * The default value for <code>columnMargin</code> is <code>1</code> and
   * the default value for <code>columnSelectionAllowed</code> is 
   * <code>false</code>.
   */
  public DefaultTableColumnModel()
  {
    tableColumns = new Vector();
    selectionModel = createSelectionModel();
    selectionModel.addListSelectionListener(this);
    columnMargin = 1;
    columnSelectionAllowed = false;
  }

  /**
   * Adds a column to the model then calls 
   * {@link #fireColumnAdded(TableColumnModelEvent)} to notify the registered
   * listeners.  The model registers itself with the column as a
   * {@link PropertyChangeListener} so that changes to the column width will
   * invalidate the cached {@link #totalColumnWidth} value.
   *
   * @param column  the column (<code>null</code> not permitted).
   * 
   * @throws IllegalArgumentException if <code>column</code> is 
   *     <code>null</code>.
   * 
   * @see #removeColumn(TableColumn)
   */
  public void addColumn(TableColumn column)
  {
    if (column == null)
      throw new IllegalArgumentException("Null 'col' argument.");
    tableColumns.add(column);
    column.addPropertyChangeListener(this);
    invalidateWidthCache();
    fireColumnAdded(new TableColumnModelEvent(this, 0, 
                                              tableColumns.size() - 1));
  }

  /**
   * Removes a column from the model then calls
   * {@link #fireColumnRemoved(TableColumnModelEvent)} to notify the registered
   * listeners.  If the specified column does not belong to the model, or is 
   * <code>null</code>, this method does nothing.
   *
   * @param column the column to be removed (<code>null</code> permitted).
   * 
   * @see #addColumn(TableColumn)
   */
  public void removeColumn(TableColumn column)
  {
    int index = this.tableColumns.indexOf(column);
    if (index < 0)
      return;
    tableColumns.remove(column);
    fireColumnRemoved(new TableColumnModelEvent(this, index, 0));    
    column.removePropertyChangeListener(this);
    invalidateWidthCache();
  }

  /**
   * Moves the column at index i to the position specified by index j, then 
   * calls {@link #fireColumnMoved(TableColumnModelEvent)} to notify registered
   * listeners.
   *
   * @param i index of the column that will be moved.
   * @param j index of the column's new location.
   * 
   * @throws IllegalArgumentException if <code>i</code> or <code>j</code> are
   *     outside the range <code>0</code> to <code>N-1</code>, where 
   *     <code>N</code> is the column count.
   */
  public void moveColumn(int i, int j)
  {
    int columnCount = getColumnCount();
    if (i < 0 || i >= columnCount)
      throw new IllegalArgumentException("Index 'i' out of range.");
    if (j < 0 || j >= columnCount)
      throw new IllegalArgumentException("Index 'j' out of range.");
    Object column = tableColumns.remove(i);
    tableColumns.add(j, column);
    fireColumnMoved(new TableColumnModelEvent(this, i, j));
  }

  /**
   * Sets the column margin then calls {@link #fireColumnMarginChanged()} to
   * notify the registered listeners.
   * 
   * @param margin  the column margin.
   * 
   * @see #getColumnMargin()
   */
  public void setColumnMargin(int margin)
  {
    columnMargin = margin;
    fireColumnMarginChanged();
  }

  /**
   * Returns the number of columns in the model.
   * 
   * @return The column count.
   */
  public int getColumnCount()
  {
    return tableColumns.size();
  }

  /**
   * Returns an enumeration of the columns in the model.
   * 
   * @return An enumeration of the columns in the model.
   */
  public Enumeration getColumns()
  {
    return tableColumns.elements();
  }

  /**
   * Returns the index of the {@link TableColumn} with the given identifier.
   *
   * @param identifier  the identifier (<code>null</code> not permitted).
   * 
   * @return The index of the {@link TableColumn} with the given identifier.
   * 
   * @throws IllegalArgumentException if <code>identifier</code> is 
   *         <code>null</code> or there is no column with that identifier.
   */
  public int getColumnIndex(Object identifier)
  {
    if (identifier == null)
      throw new IllegalArgumentException("Null identifier.");
    int columnCount = tableColumns.size();
    for (int i = 0; i < columnCount; i++) 
    {
      TableColumn tc = (TableColumn) tableColumns.get(i);
      if (identifier.equals(tc.getIdentifier()))
        return i;
    }
    throw new IllegalArgumentException("No TableColumn with that identifier.");
  }

  /**
   * Returns the column at the specified index.
   * 
   * @param columnIndex  the column index (in the range from <code>0</code> to 
   *     <code>N-1</code>, where <code>N</code> is the number of columns in 
   *     the model).
   * 
   * @return The column at the specified index.
   * 
   * @throws ArrayIndexOutOfBoundsException if <code>i</code> is not within
   *     the specified range.
   */
  public TableColumn getColumn(int columnIndex)
  {
    return (TableColumn) tableColumns.get(columnIndex);
  }

  /**
   * Returns the column margin.
   * 
   * @return The column margin.
   * 
   * @see #setColumnMargin(int)
   */
  public int getColumnMargin()
  {
    return columnMargin;
  }

  /**
   * Returns the index of the column that contains the specified x-coordinate.
   * This method assumes that:
   * <ul>
   * <li>column zero begins at position zero;</li>
   * <li>all columns appear in order;</li>
   * <li>individual column widths are taken into account, but the column margin
   *     is ignored.</li>
   * </ul>
   * If no column contains the specified position, this method returns 
   * <code>-1</code>.
   * 
   * @param x  the x-position.
   * 
   * @return The column index, or <code>-1</code>.
   */
  public int getColumnIndexAtX(int x)
  {    
    for (int i = 0; i < tableColumns.size(); ++i)
      {
        int w = ((TableColumn) tableColumns.get(i)).getWidth();
        if (0 <= x && x < w)
          return i;
        else
          x -= w;
      }
    return -1;
  }

  /**
   * Returns total width of all the columns in the model, ignoring the
   * {@link #columnMargin}.
   *
   * @return The total width of all the columns.
   */
  public int getTotalColumnWidth()
  {
    if (totalColumnWidth == -1)
      recalcWidthCache();
    return totalColumnWidth;
  }

  /**
   * Sets the selection model that will be used to keep track of the selected 
   * columns.
   *
   * @param model  the selection model (<code>null</code> not permitted).
   * 
   * @throws IllegalArgumentException if <code>model</code> is 
   *     <code>null</code>.
   *     
   * @see #getSelectionModel()
   */
  public void setSelectionModel(ListSelectionModel model)
  {
    if (model == null)
      throw new IllegalArgumentException();
    
    selectionModel.removeListSelectionListener(this);
    selectionModel = model;
    selectionModel.addListSelectionListener(this);
  }

  /**
   * Returns the selection model used to track table column selections.
   * 
   * @return The selection model.
   * 
   * @see #setSelectionModel(ListSelectionModel)
   */
  public ListSelectionModel getSelectionModel()
  {
    return selectionModel;
  }

  /**
   * Sets the flag that indicates whether or not column selection is allowed.
   *
   * @param flag  the new flag value.
   * 
   * @see #getColumnSelectionAllowed()
   */
  public void setColumnSelectionAllowed(boolean flag)
  {
    columnSelectionAllowed = flag;
  }

  /**
   * Returns <code>true</code> if column selection is allowed, and 
   * <code>false</code> if column selection is not allowed.
   *
   * @return A boolean.
   * 
   * @see #setColumnSelectionAllowed(boolean)
   */
  public boolean getColumnSelectionAllowed()
  {
    return columnSelectionAllowed;
  }

  /**
   * Returns an array containing the indices of the selected columns.
   *
   * @return An array containing the indices of the selected columns.
   */
  public int[] getSelectedColumns()
  {
    // FIXME: Implementation of this method was taken from private method 
    // JTable.getSelections(), which is used in various places in JTable
    // including selected row calculations and cannot be simply removed.
    // This design should be improved to illuminate duplication of code.
    
    ListSelectionModel lsm = this.selectionModel;    
    int sz = getSelectedColumnCount();
    int [] ret = new int[sz];

    int lo = lsm.getMinSelectionIndex();
    int hi = lsm.getMaxSelectionIndex();
    int j = 0;
    java.util.ArrayList ls = new java.util.ArrayList();
    if (lo != -1 && hi != -1)
      {
        switch (lsm.getSelectionMode())
          {
          case ListSelectionModel.SINGLE_SELECTION:
            ret[0] = lo;
            break;      
      
          case ListSelectionModel.SINGLE_INTERVAL_SELECTION:            
            for (int i = lo; i <= hi; ++i)
              ret[j++] = i;
            break;
            
          case ListSelectionModel.MULTIPLE_INTERVAL_SELECTION:        
            for (int i = lo; i <= hi; ++i)
              if (lsm.isSelectedIndex(i))        
                ret[j++] = i;
            break;
          }
      }
    return ret;
  }

  /**
   * Returns the number of selected columns in the model.
   * 
   * @return The selected column count.
   * 
   * @see #getSelectionModel()
   */
  public int getSelectedColumnCount()
  {
    // FIXME: Implementation of this method was taken from private method 
    // JTable.countSelections(), which is used in various places in JTable
    // including selected row calculations and cannot be simply removed.
    // This design should be improved to illuminate duplication of code.
   
    ListSelectionModel lsm = this.selectionModel;
    int lo = lsm.getMinSelectionIndex();
    int hi = lsm.getMaxSelectionIndex();
    int sum = 0;
    
    if (lo != -1 && hi != -1)
      {
        switch (lsm.getSelectionMode())
          {
          case ListSelectionModel.SINGLE_SELECTION:
            sum = 1;
            break;
            
          case ListSelectionModel.SINGLE_INTERVAL_SELECTION:
            sum = hi - lo + 1;
            break;
            
          case ListSelectionModel.MULTIPLE_INTERVAL_SELECTION:        
            for (int i = lo; i <= hi; ++i)
              if (lsm.isSelectedIndex(i))        
                ++sum;
            break;
          }
      }
     
     return sum;
  }

  /**
   * Registers a listener with the model, so that it will receive
   * {@link TableColumnModelEvent} notifications.
   *
   * @param listener the listener (<code>null</code> ignored).
   */
  public void addColumnModelListener(TableColumnModelListener listener)
  {
    listenerList.add(TableColumnModelListener.class, listener);
  }

  /**
   * Deregisters a listener so that it no longer receives notification of 
   * changes to this model.
   *
   * @param listener  the listener to remove
   */
  public void removeColumnModelListener(TableColumnModelListener listener)
  {
    listenerList.remove(TableColumnModelListener.class, listener);
  }

  /**
   * Returns an array containing the listeners that are registered with the
   * model.  If there are no listeners, an empty array is returned.
   * 
   * @return An array containing the listeners that are registered with the
   *     model.
   *     
   * @see #addColumnModelListener(TableColumnModelListener)
   * @since 1.4
   */
  public TableColumnModelListener[] getColumnModelListeners()
  {
    return (TableColumnModelListener[])
      listenerList.getListeners(TableColumnModelListener.class);
  }	  

  /**
   * Sends the specified {@link TableColumnModelEvent} to all registered 
   * listeners, to indicate that a column has been added to the model.  The
   * event's <code>toIndex</code> attribute should contain the index of the
   * added column.  
   * 
   * @param e  the event.
   * 
   * @see #addColumn(TableColumn)
   */
  protected void fireColumnAdded(TableColumnModelEvent e)
  {    
    TableColumnModelListener[] listeners = getColumnModelListeners();

    for (int i = 0; i < listeners.length; i++)
      listeners[i].columnAdded(e);        
  }

  /**
   * Sends the specified {@link TableColumnModelEvent} to all registered 
   * listeners, to indicate that a column has been removed from the model.  The
   * event's <code>fromIndex</code> attribute should contain the index of the
   * removed column.  
   * 
   * @param e  the event.
   * 
   * @see #removeColumn(TableColumn)
   */
  protected void fireColumnRemoved(TableColumnModelEvent e)
  {
    TableColumnModelListener[] listeners = getColumnModelListeners();

    for (int i = 0; i < listeners.length; i++)
      listeners[i].columnRemoved(e);        
  }

  /**
   * Sends the specified {@link TableColumnModelEvent} to all registered 
   * listeners, to indicate that a column in the model has been moved.  The
   * event's <code>fromIndex</code> attribute should contain the old column
   * index, and the <code>toIndex</code> attribute should contain the new
   * column index.  
   * 
   * @param e  the event.
   * 
   * @see #moveColumn(int, int)
   */
  protected void fireColumnMoved(TableColumnModelEvent e)
  {
    TableColumnModelListener[] listeners = getColumnModelListeners();

    for (int i = 0; i < listeners.length; i++)
      listeners[i].columnMoved(e);        
  }

  /**
   * Sends the specified {@link ListSelectionEvent} to all registered listeners,
   * to indicate that the column selections have changed.
   *
   * @param e  the event.
   * 
   * @see #valueChanged(ListSelectionEvent)
   */
  protected void fireColumnSelectionChanged(ListSelectionEvent e)
  {
    EventListener [] listeners = getListeners(TableColumnModelListener.class);
    for (int i = 0; i < listeners.length; ++i)
      ((TableColumnModelListener) listeners[i]).columnSelectionChanged(e);
  }

  /**
   * Sends a {@link ChangeEvent} to the model's registered listeners to 
   * indicate that the column margin was changed.  
   * 
   * @see #setColumnMargin(int)
   */
  protected void fireColumnMarginChanged()
  {
    EventListener[] listeners = getListeners(TableColumnModelListener.class);
    if (changeEvent == null && listeners.length > 0)
      changeEvent = new ChangeEvent(this);
    for (int i = 0; i < listeners.length; ++i)
      ((TableColumnModelListener) listeners[i]).columnMarginChanged(changeEvent);
  }

  /**
   * Returns an array containing the listeners (of the specified type) that 
   * are registered with this model.
   * 
   * @param listenerType  the listener type (must indicate a subclass of 
   *     {@link EventListener}, <code>null</code> not permitted).
   *
   * @return An array containing the listeners (of the specified type) that 
   *     are registered with this model.
   */
  public EventListener[] getListeners(Class listenerType)
  {
    return listenerList.getListeners(listenerType);
  }

  /**
   * Receives notification of property changes for the columns in the model.
   * If the <code>width</code> property for any column changes, we invalidate
   * the {@link #totalColumnWidth} value here. 
   *
   * @param event  the event.
   */
  public void propertyChange(PropertyChangeEvent event)
  {
    if (event.getPropertyName().equals("width"))
	  invalidateWidthCache(); 
  }

  /**
   * Receives notification of the change to the list selection model, and 
   * responds by calling 
   * {@link #fireColumnSelectionChanged(ListSelectionEvent)}.
   * 
   * @param e  the list selection event.
   * 
   * @see #getSelectionModel()
   */
  public void valueChanged(ListSelectionEvent e)
  {
    fireColumnSelectionChanged(e);
  }

  /**
   * Creates a default selection model to track the currently selected 
   * column(s).  This method is called by the constructor and returns a new
   * instance of {@link DefaultListSelectionModel}.
   *
   * @return A new default column selection model.
   */
  protected ListSelectionModel createSelectionModel()
  {    
    return new DefaultListSelectionModel();
  }

  /**
   * Recalculates the total width of the columns, if the cached value is
   * <code>-1</code>.  Otherwise this method does nothing.
   * 
   * @see #getTotalColumnWidth()
   */
  protected void recalcWidthCache()
  {
    if (totalColumnWidth == -1)
      {
        totalColumnWidth = 0;
        for (int i = 0; i < tableColumns.size(); ++i)
          {
            totalColumnWidth += ((TableColumn) tableColumns.get(i)).getWidth();
          }
      }
  }

  /**
   * Sets the {@link #totalColumnWidth} field to <code>-1</code>.
   * 
   * @see #recalcWidthCache()
   */
  private void invalidateWidthCache()
  {
    totalColumnWidth = -1;
  }
}
