import java.util.ArrayList;

/**
 * Spielleitung fuer das Kartenspiel BlackJack.
 * Der Spielleiter verwaltet Referenzen auf die Spieler. Auueerdem wird
 * automatisch ein Dealer erzeugt. Blackjack wird mit 6 Kartenbluettern
 * gespielt, die komplett gemischt werden. Wenn mehr als 250 Karten
 * verbraucht wurden, kommen alle Karten wieder ins Spiel.
 *
 * @version 1.0 vom 20.06.2012
 * @author Thomas Schaller
 */

public class Spielleitung {

    // Anfang Attribute
    private ArrayList<Spieler> spieler;                  // Bis zu 5 Spieler+Croupier kuennen teilnehmen
    private Kartenhand kartenstapel = new Kartenhand();  // Stapel mit unbenutzen Karten
    // Ende Attribute

    public Spielleitung() {
        spieler = new ArrayList<Spieler>();
        kartenstapel.erzeugeKartenblatt();             // Kartenstapel erzeugen.

        Spieler croupier = new Spieler(0);             // erzeuge Croupier (mit Guthaben 0)
        addSpieler(croupier);                          // Croupier ist immer erster Spieler
    }

    // Anfang Methoden

    /** Meldet Spieler bei der Spielleitung an. Der Spieler wird ueber die Spielleitung informiert.
     * @param s Spieler, der am Spiel teilnehmen muechte.
     */
    public void addSpieler(Spieler s) {
        s.setSpielleiter(this);
        spieler.add(s);
    }

    /** Wertet eine Runde aus. Dazu bekommt der Dealer seine Karte. Er zieht so lange Karten bis er
    mindestens 17 Punkte erreicht hat. Danach wird ermittelt, welche Spieler gewonnen haben. Die
    Spieler werden ueber Gewinn oder Niederlage informiert.
     */
    public void auswerten() {
        // Dealer erhuelt seine Karten
        Kartenhand dealer = spieler.get(0).getKarten();
        while (dealer.getSumme()<17) {
            spieler.get(0).zieheKarte();
        } // end of while

        // Gewinne ermitteln

        for (Spieler s: spieler) {
            Kartenhand k = s.getKarten();
            double gewinnfaktor = 0;
            if (k.getSumme()<=21) { // nur wer kleiner 22 kann gewinnen
                if (dealer.getSumme()>21) { // Dealer hat sich ueberkauft
                    gewinnfaktor = 2;  // Man gewinnt einfachen Einsatz
                }
                if (k.getSumme()>dealer.getSumme()) { // Spieler hat mehr Punkte als Dealer
                    gewinnfaktor = 2;  // Man gewinnt einfachen Einsatz
                }
                if (!k.isBlackJack() && k.getSumme() == dealer.getSumme() &&  !dealer.isBlackJack()) { // Gleichstand und kein BlackJack bei Dealer
                    gewinnfaktor = 1;  // Unentschieden. Man erhuelt Einsatz zurueck
                }
                if (k.isBlackJack() && dealer.isBlackJack()) {  // BlackJack gewinn nur, wenn Dealer keinen BlackJack hat
                    gewinnfaktor = 1;  // Unentschieden
                }  // end of if
                if (k.isBlackJack() && !dealer.isBlackJack()) {  // BlackJack gewinn nur, wenn Dealer keinen BlackJack hat
                    gewinnfaktor = 2.5;  // Man gewinnt 1,5 fachen Einsatz
                }  // end of if
                if (k.isTripleSeven()) { // Triple-Seven gewinnt auch bei Punktegleichstand (auch gegen BlackJack des Dealers)
                    gewinnfaktor = 2.5;  // Man gewinnt 1,5 fachen Einsatz
                }
            }
            s.abrechnen(gewinnfaktor);
        } // end of for

    }

    /** Zieht eine Karte vom Kartenstapel.
     * @return Referenz auf die gezogene Karte
     */
    public Karte getKarte() {
        return kartenstapel.remove();
    }

    /** Liefert eine Referenz auf den Croupier
     * @return Referenz auf den Croupier
     */
    public Spieler getCroupier() {
        return spieler.get(0);  // Spieler 0 ist immer der Croupier
    }

    /** Liefert eine Refernz auf einen Spieler
     * @param nr Nummer des Spielers (1-n)
     * @return Referenz auf nr. Spieler
     */
    public Spieler getSpieler(int nr) {
        return spieler.get(nr);  // Spieler 0 ist immer der Croupier
    }

    /** Eine neue Runde wird gestartet.
     *   Alle Spieler werden ueber die neue Runde informiert (die alten Kartenhuende werden geluescht) und
     *  kontrolliert, ob noch genuegend Karten auf dem Stapel sind.
     */
    public void neueRunde() {
        // Spieler informieren
        for (Spieler s : spieler) {
            s.neueRunde();
        } // end of for
        // Kartenstapel kontrollieren
        if (kartenstapel.getAnzahl()<100) {
            kartenstapel.erzeugeKartenblatt();
        } // end of if
    }

    // Ende Methoden
}
