import sale.*;
import log.*;
import users.*;
import data.*;
import data.ooimpl.*;

import java.io.*;
import java.util.*;
import java.lang.*;


/**
 * Diese Klasse ist der "Shop" der Anwendung. Sie stellt das Grundgerüst
 * für die Anwendung dar.
 */
public class VideoMachine extends Shop
{

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

  // Liste aller registrierten Kunden
  private static Set customerSet = new HashSet();


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

  /**
   * Konstruktor. Erzeugt ein neues Objekt vom Typ VideoAutomat.
   */
  public VideoMachine()
  {
    super();

    // Name und Preis fuer die Standart-Katalogeintraege
    String[] videos = {"Video 01", "Video 02", "Video 03", "Video 04",
                       "Video 05", "Video 06", "Video 07", "Video 08",
                       "Video 09", "Video 10"};
    int[] buy = {5000, 5000, 5000, 5000, 5000, 4000, 4000, 4000, 3000, 3000};
    int[] sell =
      {40000, 40000, 40000, 40000, 35000, 35000, 35000, 35000, 30000, 30000};


    // Eintragung in den Catalog und den Stock
    Catalog videoCatalog = new CatalogImpl("Video-Catalog");
    addCatalog(videoCatalog);

    for (int i = 0; i < videos.length; i++) {
      videoCatalog.add(new VideoCassette (videos[i], new QuoteValue
        (new IntegerValue (buy[i]), new IntegerValue (sell[i]))), null);
    }

    CountingStock cs = new CountingStockImpl("Video-Countingstock",
      (CatalogImpl)videoCatalog);
    addStock(cs);

    // Erstellen eines Bestands von je 5 Videos (sollte spaeter
    // vom Manager uebernommen werden
    Iterator cassettes = videoCatalog.keySet(null).iterator();
    while (cassettes.hasNext()) {
      cs.add((String)cassettes.next(), 5, null);
    }

    // Anlegen einer Waehrung und Erstellen eines dazugehoerigen
    // Geldbestandes
    addCatalog(new CurrencyImpl("DM"));

    MoneyBag coinSlot = new MoneyBagImpl("coin slot",
      (CurrencyImpl)getCatalog("DM"));
    coinSlot.add("1-Pfennig-Stueck", 100000, null);
    addStock(coinSlot);
  }


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

  /**
   * Die Main-Methode startet die Anwendung.
   */
  public static void main (String[] args)
  {
    // neuen Videoautomaten erzeugen
    VideoMachine vidMachine = new VideoMachine();
    setTheShop(vidMachine);

    // Datei zuweisen, in die das Log geschrieben werden soll
    try {
      Log.setGlobalOutputStream(new FileOutputStream("machine.log", true));
    }
    catch (IOException ioex) {
      System.err.println("Unable to create log file.");
    }

    // Verleih bzw. Kasse anlegen
    Counter c = new Counter("Video Rental");
    c.attach(new DataBasketImpl());
    c.attach(new User("SalespointUser"));
    vidMachine.addSalesPoint(c);

    // Titel setzen und starten
    vidMachine.setShopFrameTitle("Videoverleihautomat *** HOMECINEMA *** 24h");
    vidMachine.start();

    vidMachine.getShopFrame().setSize(640,480);
    vidMachine.getShopFrame().validate();
  }

  /**
    * Beendet das Programm ohne den Stand abzuspeichern.
    */
  public void quit()
  {
    if (Shop.getTheShop().shutdown (false)) {
      System.exit (0);
    }
  }

  /**
   * F&uuml;gt der Liste registrierter Kunden einen neuen hinzu.
   */
  public static void addCustomer(Customer customer)
  {
    customerSet.add(customer);
  }

  /**
   * L&ouml;scht den angegebenen Kunden aus der Liste registrierter
   * Kunden heraus.
   */
  public static void removeCustomer(Customer customer)
  {
    customerSet.remove(customer);
  }

  /**
   * Liefert eine Liste aller registrierter Kunden.
   */
  public static Set getAllCustomer()
  {
    return customerSet.isEmpty() ? null : customerSet;
  }


  /**
   * Liefert das Kundenobject zur &uuml;bergebenen Kundennummer.
   */
  public static Customer getCustomerByID(String customerID)
  {
    Iterator i = customerSet.iterator();
    while (i.hasNext()) {
      Customer customer = (Customer)i.next();
      if (customer.getCustomerID().equals(customerID))
	return customer;
    }
    return null;
  }
}