package javakurs.uebung06;

import java.util.Hashtable;
import java.util.Map;

import javax.swing.table.AbstractTableModel;

/**
 * {@link SimplePropertiesTableModel} provides a simple table model for
 * Properties display in JTable, borrows most method implementations from
 * javax.swing.table.AbstractTableModel, a default implementation of the
 * interface javax.swing.table.TableModel
 *
 * @author Ulrich Schaefer, DFKI
 * @author Joerg Steffen, DFKI
 * @version $Id$
 */
public class SimplePropertiesTableModel
    extends AbstractTableModel {

  /**
   * This contains the maximum number of rows.
   */
  private static final int MAX_ROWS = 100;

  /**
   * This contains the array of table contents;<br/>
   * first dimension: columns (always of size 2)<br/>
   * second dimension: rows
   */
  private String[][] value;


  /**
   * This maps property names to table rows.
   */
  private Map<String, Integer> propertyMap;


  /**
   * This creates a new instance of {@link SimplePropertiesTableModel} and
   * initializes it with the given properties.
   *
   * @param props
   *          the properties used for initialization
   */
  public SimplePropertiesTableModel(PropertiesIF props) {

    int i = 0;
    this.propertyMap = new Hashtable<String, Integer>(props.size());
    this.value = new String[2][MAX_ROWS];
    for (Map.Entry<Object, Object> e : props.entrySet()) {
      this.propertyMap.put((String)e.getKey(), i);
      // column 0: property names
      this.value[0][i] = (String)e.getKey();
      // column 1: property values
      this.value[1][i] = (String)e.getValue();
      i++;
    }
  }


  /**
   * {@inheritDoc}
   */
  @Override
  public int getRowCount() {

    return this.propertyMap.size();
  }


  /**
   * {@inheritDoc}
   */
  @Override
  public int getColumnCount() {

    return 2;
  }


  /**
   * {@inheritDoc}
   */
  @Override
  public String getValueAt(int row, int column) {

    return this.value[column][row];
  }


  /**
   * {@inheritDoc}
   */
  @Override
  public void setValueAt(Object val, int row, int column) {

    this.value[column][row] = (String)val;
  }


  /**
   * {@inheritDoc}
   */
  @Override
  public String getColumnName(int column) {

    if (column == 0) {
      return "Produkt";
    }
    return "Anzahl";
  }


  /**
   * This returns the row number for the given property; -1 if no row with the
   * given property exists.
   *
   * @param propKey
   *          the key of the property
   * @return the table row
   */
  public int getRowForProperty(String propKey) {

    Integer row = this.propertyMap.get(propKey);
    if (null != row) {
      return row;
    }

    return -1;
  }


  /**
   * This adds the given property as a new row of the table.
   *
   * @param propKey
   *          the key of the property
   * @return the table row used for the new property
   */
  public int addProperty(String propKey) {

    int row = this.getRowCount();
    this.propertyMap.put(propKey, row);

    return row;
  }


  /**
   * This updates the given property in the table model.
   *
   * @param propKey
   *          the key of the property
   * @param propValue
   *          the value of the property
   */
  public void updateValue(String propKey, String propValue) {

    // get row with the entry for the given property
    int row = this.getRowForProperty(propKey);
    if (-1 != row) {
      // update amount of existing product
      this.setValueAt(propValue, row, 1);
      // inform GUI about the change
      fireTableRowsUpdated(row, row);
    }
    else {
      // property is new
      row = this.addProperty(propKey);
      this.setValueAt(propKey, row, 0);
      this.setValueAt(propValue, row, 1);
      // inform GUI about the change
      fireTableRowsInserted(row, row);
    }
  }
}
