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 3: return tcrCount;
      case 4: return tcrCount;
      default: return tcrMoney;
    }
  }

  /**
   * 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)((data.swing.CountingStockTableModel.Record)
		      record).getDescriptor();
    // Anzahl im Automaten ermitteln
    int count =
      ((data.swing.CountingStockTableModel.Record)record).getCount();

    // Spalteneintrag zurueckgeben
    switch (index) {
      case 0:
	return videoCassette.getName();
      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.");

    }
  }

}