import java.util.Random;
import java.util.ArrayList;

/**
 *
 * Speichert eine Reihe von Spielkarten fuer BlackJack. Damit kann
 * sowohl die Hand eines Spielers als auch des Dealers abgespeichert werden.
 * Es ist mueglich, den Wert der Kartenhand zu ermitteln und festzustellen, ob es
 * sich um eine Triple-7 handelt.
 *
 * @version 1.0 vom 27.06.2012
 * @author Thomas Schaller
 */

public class Kartenhand {

    // Anfang Attribute
    private ArrayList<Karte> karten;            // es kuennen max. 312 Karten gespeichert werden
    // Ende Attribute

    // Anfang Methoden
    public Kartenhand() {
        karten = new ArrayList<Karte>();
    }

    /** Erzeugt einen gemischten Kartenstapel mit 6 Kartenbluettern a 52 Karten.
     */
    public void erzeugeKartenblatt() {
        // 6 Kartenbluetter erzeugen. Der Kartenstapel ist dann noch sortiert.
        for (int i=0; i<6 ; i++ ) {
            for (int j=0; j<4 ; j++) {
                for (int k=0;k < 13 ;k++ ) {
                    karten.add(new Karte(j, k+1));
                } // end of for
            } // end of for
        } // end of for

        // Kartenstapel mischen. 10000 mal zufuellig 2 Karten vertauschen
        Random r = new Random();
        for (int i=0; i<10000 ; i++ ) {
            int j = r.nextInt(312);
            int k = r.nextInt(312);
            Karte m = karten.get(j);
            karten.set(j,karten.get(k));
            karten.set(k, m);
        } // end of for
    }

    /** Fuegt der Hand eine Karte hinzu. Es sind maximal 10 Karten mueglich.
     * @param k Die Karte, die der Hand hinzugefuegt werden soll
     */
    public void add(Karte k) {
        karten.add(k);
    }

    /** Entfernt die oberste Karte von der Kartenhand.
     * @return Referenz auf die oberste Karte
     */
    public Karte remove() {
        return karten.remove(karten.size()-1);
    }

    /** Liefert die Anzahl der Karten auf der Hand.
     * @return Anzahl der Karten
     */
    public int getAnzahl() {
        return karten.size();
    }

    /** Liefert die Summe der Kartenwerte. Dabei werden die Asse so
     * gewertet, dass es fuer den Spieler optimal ist, d.h. sie werden als 11 gewertet,
     * solange die 21 nicht ueberschritten ist.
     * @return Summe der Kartenwerte
     */
    public int getSumme() {
        int summe=0;        // Summe der Kartenwerte
        int anzahlAsse=0;   // Anzahl der mit 1 bewerteten Asse

        for (Karte k : karten) {
            int kartenwert = k.getWert();
            if (kartenwert > 10) {  // Alle Bilder mit 10 bewerten
                kartenwert = 10;
            } // end of if
            if (kartenwert == 1) {  // Asse zunuechst mit 1 bewerten, aber zuehlen
                anzahlAsse++;
            } // end of if
            summe += kartenwert;
        } // end of for
        while (anzahlAsse > 0 && summe <= 11) { // Wenn noch Asse mit 1 bewertet wurden und eine Bewertung mit 11 nicht zum ueberkaufen fuehrt
            summe += 10;   // Ass mit 11 statt 1 bewerten.
            anzahlAsse--;
        } // end of if
        return summe;
    }

    /** Liefert eine Karte aus der Kartenhand. Der Benutzer ist dafuer verantwortlich,
     * nur Karten abzufragen, die es auch gibt.
     * @param nr Nummer der Karte, die geliefert werden soll
     * @return Referenz auf Karte
     */
    public Karte getKarte(int nr) {
        return karten.get(nr);
    }

    /** Testet, ob die Kartenhand ein Blackjack ist
     * @return true, falls es sich um einen Blackjack handelt, sonst false
     */
    public boolean isBlackJack() {
        return (karten.size() == 2) && (getSumme()==21);  // Mit zwei Karten kann man nur dann 21 erreichen, wenn es ein Blackjack ist
    }

    /** Testet, ob die Kartenhand eine Triple-7 ist
     * @return true, falls die Kartenhand genau 3x Siebener enthuelt, sonst false
     */
    public boolean isTripleSeven() {
        if (karten.size() == 3) {    // Es sind 3 Karten
            for (int i=0; i<3 ; i++) {
                if (karten.get(i).getWert()!= 7) {  // eine Karte ist keine 7
                    return false;
                } // end of if
            } // end of for
            return true;
        } // end of if
        return false;
    }

    /** Die Kartenhand wird als String zurueckgegeben. Das ist zum Testen der Klassen hilfreich.
     * @return Die Beschreibungen der Karten durch Kommas getrennt.
     */
    public String toString() {
        String s = "";
        for (Karte k : karten) {
            s = s + k.toString()+", ";
        }
        return s;
    }

    // Ende Methoden
} // end of Kartenhand
