package net.sf.taverna.t2.activities.xpath.ui.config.xmltree;

import java.awt.event.*;
import javax.swing.*;
import java.beans.*;

/**
 *  This class listens for changes made to the data in the table via the
 *  TableCellEditor. When editing is started, the value of the cell is saved
 *  When editing is stopped the new value is saved. When the oold and new
 *  values are different, then the provided Action is invoked.
 *
 *  The source of the Action is a TableCellListener instance.
 *  
 *  TODO: update to work with Java 1.6, when Taverna is migrated to that version
 *        (see the next TODO tag - this is where the change needs to be made) 
 *  
 *  @author Robert Camick
 *  
 *  @see <a href="http://tips4java.wordpress.com/2009/06/07/table-cell-listener/">http://tips4java.wordpress.com/2009/06/07/table-cell-listener/</a>
 *  @see <a href="http://www.camick.com/java/source/TableCellListener.java">http://www.camick.com/java/source/TableCellListener.java</a>
 */
public class TableCellListener implements PropertyChangeListener, Runnable
{
  private JTable table;
  private Action action;

  private int row;
  private int column;
  private Object oldValue;
  private Object newValue;

  /**
   *  Create a TableCellListener.
   *
   *  @param table   the table to be monitored for data changes
   *  @param action  the Action to invoke when cell data is changed
   */
  public TableCellListener(JTable table, Action action)
  {
    this.table = table;
    this.action = action;
    this.table.addPropertyChangeListener( this );
  }

  /**
   *  Create a TableCellListener with a copy of all the data relevant to
   *  the change of data for a given cell.
   *
   *  @param row  the row of the changed cell
   *  @param column  the column of the changed cell
   *  @param oldValue  the old data of the changed cell
   *  @param newValue  the new data of the changed cell
   */
  private TableCellListener(JTable table, int row, int column, Object oldValue, Object newValue)
  {
    this.table = table;
    this.row = row;
    this.column = column;
    this.oldValue = oldValue;
    this.newValue = newValue;
  }

  /**
   *  Get the column that was last edited - value as in table model, not in the UI
   *
   *  @return the column that was edited
   */
  public int getColumn()
  {
    return column;
  }

  /**
   *  Get the new value in the cell
   *
   *  @return the new value in the cell
   */
  public Object getNewValue()
  {
    return newValue;
  }

  /**
   *  Get the old value of the cell
   *
   *  @return the old value of the cell
   */
  public Object getOldValue()
  {
    return oldValue;
  }

  /**
   *  Get the row that was last edited - value as in table model, not in the UI
   *
   *  @return the row that was edited
   */
  public int getRow()
  {
    return row;
  }

  /**
   *  Get the table of the cell that was changed
   *
   *  @return the table of the cell that was changed
   */
  public JTable getTable()
  {
    return table;
  }
  
  //
  //  Implement the PropertyChangeListener interface
  //
  public void propertyChange(PropertyChangeEvent e)
  {
    //  A cell has started/stopped editing

    if ("tableCellEditor".equals(e.getPropertyName()))
    {
      if (table.isEditing())
        processEditingStarted();
      else
        processEditingStopped();
    }
  }

  /*
   *  Save information of the cell about to be edited
   */
  private void processEditingStarted()
  {
    //  The invokeLater is necessary because the editing row and editing
    //  column of the table have not been set when the "tableCellEditor"
    //  PropertyChangeEvent is fired.
    //  This results in the "run" method being invoked

    SwingUtilities.invokeLater( this );
  }
  
  /*
   *  See above.
   */
  public void run()
  {
//    TODO - the next line is a correct implementation for Java 1.6    
//    row = table.convertRowIndexToModel( table.getEditingRow() );
    
//    in Java 1.5 which is currently used, tables are not easily sortable
//    (and that is the case for the XPath Activity, where this class is used) --
//    hence, row numbers in the view and in the model will always be identical
//    --> HACK: just use the row number from the view...
    row = table.getEditingRow();
    
    column = table.convertColumnIndexToModel( table.getEditingColumn() );
    oldValue = table.getModel().getValueAt(row, column);
    newValue = null;
  }

  /*
   *  Update the Cell history when necessary
   */
  private void processEditingStopped()
  {
    newValue = table.getModel().getValueAt(row, column);

    //  The data has changed, invoke the supplied Action

    if (! newValue.equals(oldValue))
    {
      //  Make a copy of the data in case another cell starts editing
      //  while processing this change

      TableCellListener tcl = new TableCellListener(
        getTable(), getRow(), getColumn(), getOldValue(), getNewValue());

      ActionEvent event = new ActionEvent(
        tcl,
        ActionEvent.ACTION_PERFORMED,
        "");
      action.actionPerformed(event);
    }
  }
}
