import sale.*;
import data.*;
import data.ooimpl.*;
import data.swing.*;
import data.events.*;
import util.swing.*;

import java.util.*;

import javax.swing.*;
import javax.swing.table.*;


/**
 * Ein TableEntryDescriptor zur ausführlichen Darstellung des
 * Videobestandes.
 */
public class EditableVideoStockTED extends AbstractTableEntryDescriptor
{

  //// attributes ////////////////////////////////////////////////////////////

  private CountingStockImpl videoCountingStock;     // darzustellender Bestand
  private DataBasket db;                            // verwendeter Datenkorb

  // Variablen zur Formatierung der Darstellung
  private TableCellRenderer tcrMoney;
  private TableCellRenderer tcrName;
  private TableCellRenderer tcrCount;

  //// constructor ///////////////////////////////////////////////////////////

  /**
   * Erzeugt ein neues Objekt der Klasse <CODE>EditableVideoStockTED</CODE>.
   * Es wird der darzustellende <CODE>CountingStock</CODE> und der zu
   * verwendende <CODE>DataBasket</CODE> &uuml;bergeben.
   */
  public EditableVideoStockTED(CountingStockImpl videoCountingStock, DataBasket db)
  {
    super();
    this.videoCountingStock = videoCountingStock;
    this.db = db;
    // Initialisierung der Variablen zu Darstellung der
    // einzelnen Formate
    tcrMoney = new CurrencyRenderer((Currency)Shop.getTheShop().getCatalog("DM"));
    tcrName  = new DefaultTableCellRenderer();
    tcrCount = new DefaultTableCellRenderer();

    // Ausrichtung fuer die Darstellung der Anzahl
    ((DefaultTableCellRenderer)tcrCount).setHorizontalAlignment(
      SwingConstants.CENTER);
  }

  //// public methods ////////////////////////////////////////////////////////

  /**
   * Liefert die Anzahl der anzuzeigenden Spalten.
   */
  public int getColumnCount()
  {
    return 5;
  }

  /**
   * Liefert die Spaltennamen.
   */
  public String getColumnName(int index)
  {
    return (new String[] {"Name",
                          "Buy",
                          "Sell",
                          "Pieces in Stock",
                          "Rent Pieces"})[index];
  }

  /**
   * Legt die Darstellung f&uuml;r die einzelnen Spalten fest.
   */
  public TableCellRenderer getCellRenderer(int index)
  {
    switch (index) 
    {
      case 0: return tcrName;
      case 1: return tcrMoney;
      case 2: return tcrMoney;
      default: return tcrCount;
    }
  }

  /**
   * Wird aufgerufen, wenn <CODE>getCellRenderer()</CODE> oder
   * <CODE>getCellEditor() null</CODE> zur&uuml;ckgeben. 
   */
  public Class getColumnClass(int index)
  {
    return null;
  }

  /**
   * Liefert den Zelleninhalt f&uuml;r das &uuml;bergebene Objekt
   * und die angegebene Spalte.
   */
  public Object getValueAt(Object record, int index)
  {
    // Videokassette bestimmen
    VideoCassette videoCassette = (VideoCassette)((CountingStockTableModel.Record)record).getDescriptor();
    // Anzahl im Automaten ermitteln
    int count = ((CountingStockTableModel.Record)record).getCount();

    // Spalteneintrag zurueckgeben
    switch (index) 
    {
      case 0:
        if (videoCassette != null) 
          return videoCassette.getName();
        else 
          return "";
      case 1: 
        return ((QuoteValue)videoCassette.getValue()).getOffer();
      case 2: 
        return ((QuoteValue)videoCassette.getValue()).getBid();
      case 3:   
        return new IntegerValue(count);
      case 4:
      // Anzahl der ausgeliehenen Videos ermitteln
        int rented = 0;
        try {
          Iterator i = VideoMachine.getAllCustomer().iterator();
          while (i.hasNext()) 
          {
          rented = rented +
            ((Customer)i.next()).getStoringStock().countItems(
              videoCassette.getName(), null);
          }
        }
         catch (NullPointerException npe) {}
        // und zurueckgeben
         return new IntegerValue(rented);
      default:
        return null;
    }
  }

  /**
   * Definiert die Spalten, die editierbar sein sollen.
   */
  public boolean isElementEditable(Object record, int index)
  {
    return ((index == 1) || (index == 2));
  }

  /**
   * Liefert f&uuml;r die zu editierenden Spalten den
   * <CODE>TableCellEditor</CODE> zur&uuml;ck. In diesem Fall
   * eine Instanz der Klasse <CODE>DMCellEditor</CODE>.
   */
  public TableCellEditor getCellEditor(int index)
  {
    // Preise zu editieren?
    if (index == 1 || index == 2)
      return new DMCellEditor(new String[1], "");
     // restliche Felder
    else
      return super.getCellEditor(index);
  }

  /**
   * &Uuml;bertr&auml;gt den eingegebenen Wert in das jeweilige
   * Objekt.
   */
  public void setValueAt(Object record, int index, Object value)
  {
    VideoCassette videoCassette =
     (VideoCassette)((data.swing.CountingStockTableModel.Record)
       record).getDescriptor();
    try {
      VideoCassette videoCassetteToEdit =
        (VideoCassette)videoCountingStock.getCatalog(null).get(
          videoCassette.getName(), db, true);
      QuoteValue quoteValue = (QuoteValue)videoCassetteToEdit.getValue();
      if (index == 1)
        videoCassetteToEdit.setValue(new QuoteValue(quoteValue.getBid(),(Value)value));
      if (index == 2)
        videoCassetteToEdit.setValue(new QuoteValue((Value)value,quoteValue.getOffer()));
    }
    catch (VetoException ve) {
      JOptionPane.showMessageDialog(null,
        "The editing of that food item was vetoed. It might be in use.");
    }
  }

}