package de.jaujau.spiellogik;

import java.util.Random;

import de.jaujau.daten.Audio;
import de.jaujau.daten.Farbe;
import de.jaujau.daten.Kartensatz;
import de.jaujau.daten.Spieler;
import de.jaujau.daten.Wert;
import de.jaujau.gui.Dashboard_GUI;



/**
 * Diese Klasse organisiert den Spielablauf
 * @author Fabian Keller 
 */
public class Spiel {

	private Spieler amZug;
	private Wert gelegterWert;
	private Audio audio;
	private Kartensatz kartensatz;
	private Spielzug spielzug;
	private Computer_gegner computerGegner;
	private boolean aussetzen;
	private boolean zwei_ziehen;
	private int kartenZiehen;
	private Dashboard_GUI dashboard;
	private boolean spielGewonnen;
	
	public Spiel(Dashboard_GUI dashboard_gui) {
		audio = new Audio();
		kartensatz = new Kartensatz();
		computerGegner = new Computer_gegner(kartensatz);
		spielzug = new Spielzug(kartensatz);
		dashboard = dashboard_gui;
		spielGewonnen = false;
	}
	
	public boolean getAussetzen() {
		return aussetzen;
	}


	public boolean getZwei_ziehen() {
		return zwei_ziehen;
	}

	
	public Kartensatz getKartensatz() {
		return kartensatz;
	}


	public Spieler getamZug() {
		return amZug;		
	}
	
	
	/**
	 * Initialisiert ein Spiel
	 * @param dashboard
	 */
	public void spiel(Dashboard_GUI dashboard) {
		System.out.println("\nSPIEL Spiel gestartet.");
		Random zufallszahl = new Random();
		int zahl = zufallszahl.nextInt(2);
		if(zahl == 1) { //Starter durch zufall bestimmen
			amZug = Spieler.SPIELER;
			System.out.println("SPIEL Spieler startet");
		}
		else { 
			amZug = Spieler.COMPUTER;
			System.out.println("SPIEL Computer startet");
		}
		for(int i = 0; i < 7; i++) { //Jeder bekommt 7 Karten
			kartensatz.ziehen(Spieler.COMPUTER);
			kartensatz.ziehen(Spieler.SPIELER);
		}
		//FUNKTION erste Karte
		int kartenindex = zufallszahl.nextInt(32);
		while(kartensatz.getHand(Spieler.COMPUTER).contains(kartenindex)||kartensatz.getHand(Spieler.SPIELER).contains(kartenindex)) {
			kartenindex = zufallszahl.nextInt(32);
		}
		kartensatz.ablegen(kartenindex); //nicht in der Hand befindliche Karte zum Start aufdecken
		System.out.println("SPIEL Kartenhand von COMPUTER: " + kartensatz.getHand(Spieler.COMPUTER));
		System.out.println("SPIEL Kartenhand von SPIELER:  " + kartensatz.getHand(Spieler.SPIELER));
		effekteSetzen();
		if(amZug == Spieler.COMPUTER) {
			int computerZug = computerGegner.cpu_Zug(zwei_ziehen, aussetzen, kartensatz);
			System.out.println("\nSPIEL Computerauswahl: " + computerZug);
			switch(computerZug) {
			case -2: //aussetzen anzeigen?
				aussetzen = false;
				alternieren(dashboard);
				break;
			case -1:
				karteZiehen();
				break;
			default:
				karteLegen(computerZug);
				break;
			}	
		}
		else if(amZug == Spieler.SPIELER) {
			if(aussetzen) dashboard.showaussetzen();
		}
		return;			
	}
	
	
	/**
	 * Organisiert den Spielablauf
	 * @param dashboard
	 */
	private void alternieren(Dashboard_GUI dashboard) {
		if(spielGewonnen) return;
		if(amZug == Spieler.SPIELER) {
			amZug = Spieler.COMPUTER;
			dashboard.aktualisiereGUI(); //Komplette GUI wird aktualisiert
			System.out.println("\nSPIEL Computer am Zug");
			int computerZug = computerGegner.cpu_Zug(zwei_ziehen, aussetzen, kartensatz);
			System.out.println("SPIEL Computerauswahl: " + computerZug);
			switch(computerZug) {
			case -2: 
				aussetzen = false;
				alternieren(dashboard);
				break;
			case -1:
				karteZiehen();
				break;
			default:
				karteLegen(computerZug);
				break;
			}	
			
		}
		else {
			amZug = Spieler.SPIELER;
			dashboard.aktualisiereGUI();
			System.out.println("\nSPIEL Spieler am Zug");
			if(aussetzen) {
				System.out.println("\nSPIEL Aussetzen möglich");
				dashboard.aktualisiereGUI();
				dashboard.showaussetzen();	
				dashboard.aktualisiereGUI();
			}
		}
	}
	
	
	/**
	 * Wird aufgerufen wenn das Spiel entschieden wurde
	 * @param spieler Spieler, welcher gewonnen hat
	 */
	private void gewinn(Spieler spieler) {
		System.out.println("HERZLICHEN GLÜCKWUNSCH " + spieler + ". DU HAST GEWONNEN");
		dashboard.gewonnen(spieler);
		spielGewonnen = true;
	}
	
	
	/**
	 * Bietet die Möglichkeit auszusetzen
	 */
	public void aussetzen() {
		if(spielGewonnen) return;
		aussetzen = false;//alternieren wird aufgerufen bevor GUI fertig abgearbeitet.
		alternieren(dashboard);
	}
	
	/**
	   * falls eine Karte gelegt werden kann wird diese gelegt 	
	   * @param       	kartenindex
	   */
	public void karteLegen(int kartenindex) {
		if(spielGewonnen) return;
 		System.out.println("SPIEL Versuche Karte " + kartenindex + " zu legen");
		if (spielzug.pruefeZug(kartenindex, zwei_ziehen, aussetzen, kartensatz)) { //gewählte Karte kann gelegt werden
			System.out.println("SPIEL pruefeZug positiv");
			System.out.println("SPIEL Lege Karte " + kartenindex);
			kartensatz.ablegen(kartenindex);
			if(kartensatz.getHand(amZug).size() == 1) {
				audio.spieleJau();
			}
			if(kartensatz.getHand(amZug).isEmpty()) {
				audio.spieleJauJau();
				gewinn(amZug);
				return;
				//Spieler hat gewonnen, keine Karte mehr auf der Hand -- Was passiert?
				// Spieler Gewonnen aufrufen, Punkte aktualisieren
				// Highscore Page oder Startseite aufrufen
			}
			System.out.println("SPIEL Kartenhand von COMPUTER: " + kartensatz.getHand(Spieler.COMPUTER));
			System.out.println("SPIEL Kartenhand von SPIELER:  " + kartensatz.getHand(Spieler.SPIELER));
			effekteSetzen();
			if(kartensatz.getKarte(kartenindex).getWERT() == Wert.BUBE) {
				if(amZug == Spieler.COMPUTER)	alternieren(dashboard);
			}
		}		
	}
	
	
	/**
	   * falls eine oder mehrere Karten gezogen werden können, wird dies ausgeführt 
	   */
	public void karteZiehen(){
		if(spielGewonnen) return;
		if(!aussetzen) {
			if(zwei_ziehen) { //mehrere ziehen
				System.out.println("\nSPIEL " + kartenZiehen + " Karten gezogen");
				for(int i = 0; i < kartenZiehen; i++) {	
					kartensatz.ziehen(amZug);
				}
				kartenZiehen = 0;
				zwei_ziehen = false;	
			}
			else { //Normales ziehen
				kartensatz.ziehen(amZug);
				System.out.println("\nSPIEL 1 Karte gezogen");
			}
			alternieren(dashboard);
		}
		else { //AussetzenButton 
			return;
		}
	}
	
	
	/**
	 * Setzt die Wünscher Farbe
	 * @param farbe
	 */
	public void wuenscher(Farbe farbe) {
		kartensatz.SetWunschfarbe(farbe);
		alternieren(dashboard);
	}
	
	
	/**
	   * setzt Effekt-Variablen und Wunschfarbe für einen Wünscher 
	   */
	private void effekteSetzen() {
		if(spielGewonnen) return;
		gelegterWert = kartensatz.getKarte(kartensatz.getletzteKarte()).getWERT();
		if(gelegterWert == Wert.ACHT) {
			aussetzen = true;
		}
		if(gelegterWert == Wert.SIEBEN) {
			zwei_ziehen = true;
			kartenZiehen += 2;
		}
		if(gelegterWert == Wert.BUBE) {
			if(amZug == Spieler.COMPUTER) {
				kartensatz.SetWunschfarbe(computerGegner.farbeAussuchen(kartensatz));
			}
			else {
				dashboard.showwunsch(true);
			}
		}
		System.out.println("\nSPIEL Effekte gesetzt:\nSPIEL Aussetzen: " + aussetzen + "\nSPIEL Zwei_Ziehen: " + zwei_ziehen + "\nSPIEL Anzahl: " + kartenZiehen);
	}	
}
