import sale.*;
import data.*;
import data.ooimpl.*;
import data.stdforms.*;
import data.swing.*;
import data.events.*;
import users.*;

import java.util.*;

import javax.swing.*;


/**
 * Prozess zur Bestandsanzeige und zum Editieren des Bestandes.
 */
public class SeeVideoStockProcess extends SaleProcess
{

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

  // Gates
  protected UIGate selectionGate;

  // Transitions
  protected Transition newVideoTransition;
  protected Transition removeVideoTransition;


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

  /**
   * Erzeugt ein neues Objekt der Klasse <CODE>SeeVideoStockProcess</CODE>.
   */
  public SeeVideoStockProcess()
  {
    super ("SeeVideoProcess");
  }

  //// protected methods /////////////////////////////////////////////////////

  /**
   * Baut die Oberfl&auml;che f&uuml;r den Verleihvorgang auf.
   */
  protected void setupMachine()
  {
    // Auswahl-Gate anlegen
    selectionGate = new UIGate(null, null);

    // darzustellendes Formsheet erstellen
    final SingleTableFormSheet stfs =
      SingleTableFormSheet.create("See videos in stock and edit Process",
        (CountingStockImpl)Shop.getTheShop().getStock("Video-Countingstock"),
	selectionGate,
	getBasket(),
	true,
	new EditableVideoStockTED((CountingStockImpl)
	  Shop.getTheShop().getStock("Video-Countingstock"), getBasket()));


    // Transition zum Anlegen eines neuen Videos
    newVideoTransition = new Transition()
    {
      public Gate perform(SaleProcess pOwner, User usr)
      {
	// Anlegen eines neuen Videos
	// Eingabefelder erzeugen
	JTextField jTextField1 = new JTextField();
	JTextField jTextField2 = new JTextField();
	JTextField jTextField3 = new JTextField();
	JTextField jTextField4 = new JTextField();

	
	// neues JPanel anlegen und vertikales Boxlayout setzen
	JPanel jTextPanel = new JPanel();
	jTextPanel.setLayout(new BoxLayout(jTextPanel,
					   BoxLayout.Y_AXIS));

	// Label und Paßwortfelder einfuegen
	jTextPanel.add(new JLabel("Name"));
	jTextPanel.add(jTextField1);
	jTextPanel.add(new JLabel("Buy (in Pf)"));
	jTextPanel.add(jTextField2);
	jTextPanel.add(new JLabel("Sell (in Pf)"));
	jTextPanel.add(jTextField3);
	jTextPanel.add(new JLabel("Amount"));
	jTextPanel.add(jTextField4);
	
	// Dialog darstellen
	JOptionPane.showMessageDialog (null,
				       jTextPanel,
				       "New Video-Cassette",
				       JOptionPane.QUESTION_MESSAGE);

	// Video-Katalog holen
	Catalog videoCatalog =
	  Shop.getTheShop().getCatalog("Video-Catalog");

	// Video-Bestand holen
	CountingStock videoCountingStock =
	  (CountingStock)Shop.getTheShop().getStock("Video-Countingstock");

	// Name des Videos
	String name = jTextField1.getText();

	// Verkaufspreis
	int buy = 0;
	try {
	  buy = (new Integer(jTextField2.getText())).intValue();
	}
	catch (NumberFormatException ne) {}

	// Einkaufspreis
	int sell = 0;
	try {
	  sell = (new Integer(jTextField3.getText())).intValue();
	}
	catch (NumberFormatException ne) {}

	// Anzahl
	int amount = 0;
	try {
	  amount = (new Integer(jTextField4.getText())).intValue();
	}
	catch (NumberFormatException ne) {}

	// ueberpruefen, ob Eingabe korrekt
	if (sell > 0 && buy > 0 && amount > 0 && !name.equals("")) {
	  // in Katalog uebernehmen
	  try {
	    videoCatalog.add(new VideoCassette(name, new QuoteValue
	      (new IntegerValue (buy),
	       new IntegerValue (sell))), null);

	    // in Bestand uebernehmen
	    videoCountingStock.add(name, amount, null);
	  }

	  // Element existiert bereits
	  catch (DuplicateKeyException dke) {
	    JOptionPane.showMessageDialog(null,
	    "Element exists");
	  }

	}

	// Eingabe fehlerhaft
	else {
	  JOptionPane.showMessageDialog(null,
	    "The given input was not correct!");
	}

	// Auswahl-Gate zurueckgeben
	return selectionGate;
      }
    };

    // Transition zum Loeschen anlegen
    removeVideoTransition = new Transition()
    {
      public Gate perform(SaleProcess pOwner, User usr)
      {
	// markierte Zeile holen
	Object record = stfs.getSelectedRecord();
	VideoCassette videoCassette =
	  (VideoCassette)((data.swing.CountingStockTableModel.Record)
	  record).getDescriptor();

	// Anzahl der entliehenen Videos bestimmen
	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) {
	}


	// ueberpruefen, ob gewaehltes Video ausgeliehen
	if (rented <= 0) {
	  // loeschen des gewaehlten Eintrags
	  try {
	    // DataBasket db = new DataBasketImpl();
	    Shop.getTheShop().getCatalog("Video-Catalog").remove(
	      videoCassette, null);
	    // db.commit();
	  }
	  catch (VetoException ve) {
	    ve.printStackTrace();
	    JOptionPane.showMessageDialog(null,
	      "The selected item can't be removed!");
	  }
	}

	// ausgeliehen Videos vorhanden
	else {
	  JOptionPane.showMessageDialog(null,
	    "There are still rented videos!");
	}

	return selectionGate;
      }
    };


    // FormSheetContentCreator am Auswahl-Gate anmelden    
    stfs.addContentCreator(new FormSheetContentCreator()
    {
      protected void createFormSheetContent(FormSheet fs)
      {
	// alle vorhandenen Buttons entfernen
	fs.removeAllButtons();

	// neuen "New"-Button einbauen
	fs.addButton ("New", 100, new sale.Action()
	{
	  public void doAction (SaleProcess p, SalesPoint sp)
	  {
	    // Transition zum Erstellen eines neuen Videos als
	    // naechste Transition setzen
	    selectionGate.setNextTransition(newVideoTransition);
	  }
	});

	// neuen "Remove"-Button einbauen
	fs.addButton ("Remove", 101, new sale.Action()
	{
	  public void doAction (SaleProcess p, SalesPoint sp)
	  {
	    // Transition zum Loeschen eines Videos als naechste Transition
	    // setzen
	    selectionGate.setNextTransition(removeVideoTransition);
	  }
	});

	// neuen "Ok"-Button einbauen
	fs.addButton ("Ok", 102, new sale.Action()
	{
	  public void doAction (SaleProcess p, SalesPoint sp)
	  {
	    // Transition zum Commit-Gate als naechste Transition setzen
	    selectionGate.setNextTransition(
	      GateChangeTransition.CHANGE_TO_COMMIT_GATE);
	  }
	});

	// neuen "Cancel"-Button einbauen
	fs.addButton ("Cancel", 103, new sale.Action()
	{
	  public void doAction (SaleProcess p, SalesPoint sp)
	  {
	    // Transition zum Rollback-Gate als naechste Transition setzen
	    selectionGate.setNextTransition(
	      GateChangeTransition.CHANGE_TO_ROLLBACK_GATE);
	  }
	});

      }
    });
  }


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

  /**
   * Gibt das Startgate des Prozesses zur&uuml;ck.
   */
  public Gate getInitialGate()
  {
    // Automat aufbauen
    setupMachine();
 
    // ...und Auswahl-Gate als Startgate zurueckgeben
    return selectionGate;
  }

  /**
   * &Uuml;bergibt das Log-Gate. Hier das Stop-Gate, da beim Beenden des
   * Prozesses kein Log-Eintrag geschrieben werden soll.
   */
  public Gate getLogGate()
  {
    return getStopGate();
  }

}