package de.jaujau.spiellogik;



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

import de.jaujau.daten.Farbe;
import de.jaujau.daten.Kartensatz;
import de.jaujau.daten.Spieler;
import de.jaujau.daten.Wert;


/**
 * Diese Klasse steuert den Computer Gegner
 * @author Moritz Köppe
 */
public class Computer_gegner {

  //
  // Fields
  //
  private Wert letztekartewert;
  private Farbe letztekartefarbe;
  private ArrayList<Integer> hand;
  private boolean farbeInHand = false;
  private boolean wertInHand = false;
  private boolean bubeInHand = false;
  private Kartensatz kartensatz;
  //
  // Constructors
  //
  public Computer_gegner (Kartensatz karten) { 
	  kartensatz = karten;
  };
  
  
  /**
   * @param        kartensatz
   */
  public void pruefeZug(Kartensatz kartensatz)
  {
  }  
  /**
   * Funktion sucht aus, welche Karte der Computer Gegner legt, nach verschiedenen Parametern
   * Zuerst sollen Karten gelegt werden, welche den aktuell geltenden Effekt kontern, falls einer liegt
   * Danach werden Effektkarten der aktuellen Farbe gelegt
   * Als nächstes Werden Karten der aktuellen Farbe gelegt
   * Dann Karten die den aktuellenw Wert besitzen
   * Zuletzt Buben um sich eine Farbe zu wünschen
   * @param boolean, muss Spieler ziehen?
   * @param boolean, muss Spieler aussetzen?
   * @return Kartenindex der Karte die gelegt werden soll
   */
  public int cpu_Zug(boolean ziehen, boolean aussetzen, Kartensatz karten) {
	  kartensatz = karten; 																	//Erzeugt ein Abbild des aktuellen Kartensatzes, mit Stand der Karten
	  letztekartewert = kartensatz.getKarte(kartensatz.getletzteKarte()).getWERT();			//Speichert den Wert der Karte, die zuletzt gelegt wurde
	  letztekartefarbe = kartensatz.getKarte(kartensatz.getletzteKarte()).getFARBE(); 		//Speichert die Farbe der Karte, die zuletzt gelegt wurde
	  hand = kartensatz.getHand(Spieler.COMPUTER);											//Speichert die Karten, die der Computer aktuell auf der Hand hat
	  farbeInHand = false;																	//Speichert, ob die aktuell liegende Farbe in der Hand des Computers vorhanden ist
	  wertInHand = false;																	//Speichert, ob der aktuell liegende Wert in der Hand des Computers vorhanden ist
	  int rueckgabeindex = -1;																//Speichert den Kartenindex, der Karte, die gelegt werden soll. Standard -1 für ziehen, falls keine passende Karte auf Hand 
	  bubeInHand = false;																	//SPeichert, ob ein Bube in der Hand vorhanden ist
	  
	  
	  boolean achtInHand  = false; //Debugging
	  
	  for(int i = 0; i < hand.size(); i++) {												//Schleife geht alle Karten in der Hand des Computers durch
		  Farbe farbeHK = kartensatz.getKarte(hand.get(i)).getFARBE();						//Holt sich die Farbe der aktuellen Handkarte
		  Wert wertHK = kartensatz.getKarte(hand.get(i)).getWERT();							//Holt sich den Wert der aktuellen Handkarte
		  
		  if(farbeHK == letztekartefarbe && wertHK != Wert.BUBE) {							//Prüft ob Farbe der aktuellen Handkarte zur offen liegenden Karte passt
			  farbeInHand = true;
		  }
		  
		  if(wertHK == letztekartewert) {													//Prüft ob Wert der aktuellen Handkarte zur liegenden Karte passt
			  wertInHand = true;
		  }
		  
		  if(wertHK == Wert.BUBE) {															//Prüft, ob ein Bube (Wünscher) auf der Hand vorhanden ist
			  bubeInHand = true;
		  }
		  
		  //Debugging:
		  if((wertHK == Wert.ACHT && farbeHK == letztekartefarbe) || (wertHK == Wert.ACHT && letztekartewert == Wert.ACHT)) {
			  achtInHand = true;
		  }
	  }
	  
	  //Teil zum Debuging, wo der Bot zuerst versucht 8 zu legen:
	  
	  if(achtInHand = true) {
		  for (int i = 0; i < hand.size(); i++) {
			  Farbe farbeHK = kartensatz.getKarte(hand.get(i)).getFARBE();
			  Wert wertHK = kartensatz.getKarte(hand.get(i)).getWERT();
			  if((farbeHK == letztekartefarbe && wertHK == Wert.ACHT) || (wertHK == letztekartewert && wertHK == Wert.ACHT)) {
				  return hand.get(i);
			  }
		  }
	  }
	  
	  //Debuging Teil ends
	  
	  
	  
	  
	  //Wählt aus, welche Karte gelegt wird
	  if ((aussetzen || ziehen) && wertInHand) {											//Muss der Computer aussetzen oder ziehen, versucht er eine passende Konterkarte zu legen											
		  rueckgabeindex = wertLegen(letztekartewert);
	  }
	  else if((wertInHand || farbeInHand) && !aussetzen && !ziehen) {						
		  if (hand.size() > 3) {															//Hat der Computer viele Karten in der Hand versucht er passende Farben zu legen, bei weniger Karten passende Werte
			  if(farbeInHand && !aussetzen && !ziehen) {									//Hat der Computer die Farbe auf der Hand, versucht er diese zu legen
				  rueckgabeindex = farbeLegen(letztekartefarbe);
			  }
			  else if(wertInHand && !aussetzen && !ziehen) {								//Hat der Computer nicht die passende Farbe, aber einen passenden Wert, legt er diesen
				  rueckgabeindex = wertLegen(letztekartewert);
			  }
		  }
		  else {
			  if(wertInHand && !aussetzen && !ziehen) {										//Hat der Computer die Wert auf der Hand, versucht er diese zu legen
				  rueckgabeindex = wertLegen(letztekartewert);
			  }
			  else if(farbeInHand && !aussetzen && !ziehen) {								//Hat der Computer nicht den passenden Wert, aber eine passende Farbe, legt er diese
				  rueckgabeindex = farbeLegen(letztekartefarbe);
			  }
			  
		  }
	  }
	  else if(bubeInHand && !aussetzen && !ziehen) {										//Hat der Computer weder die passende Farbe, noch den passenden Wert auf der Hand, aber einen Wünscher, legt er diesen
		  rueckgabeindex = wertLegen(Wert.BUBE);
	  }
	  else if(aussetzen && !wertInHand) {													//Muss der Computer aussetzen und kann nicht reagieren, gibt er eine -2 zurück
		  rueckgabeindex = -2;
	  }
	  
	  
	  
	  return rueckgabeindex;																		
  }
  
  /**
   * Funktion sucht Karte passend zur gesuchten Farbe aus der Hand und gibt diese zurück
   * Passen mehrere Karten, gibt sie die letzte passende zurück
   * @param Farbe, Farbe zu der eine Karte gesucht wird
   * @return integer Index der zurückgegebenen Karte
   */
  private int farbeLegen(Farbe gesuchteFarbe) {
	  int ind = -1;
	  
	  for(int i = 0; i < hand.size(); i++) {
		  Farbe farbeHK = kartensatz.getKarte(hand.get(i)).getFARBE();
		  Wert wertHK = kartensatz.getKarte(hand.get(i)).getWERT();
		  if(farbeHK == gesuchteFarbe && wertHK != Wert.BUBE) {
			  ind = hand.get(i);
		  }
	  }
	  return ind;
  }
  
  /**
   * Funktion sucht Karte passend zum gesuchten Wert aus der Hand und gibt diese zurück
   * Passen mehrere Karten, gibt sie die letzte passende zurück
   * @param Wert, Wert zu dem eine passende Karte gesucht wird
   * @return integer Index der zurückgegebenen Karte
   */
  private int wertLegen(Wert gesuchterWert) {
	  int ind = -1;
	  
	  for(int i = 0; i < hand.size(); i++) {
		  Wert wertHK = kartensatz.getKarte(hand.get(i)).getWERT();
		  if(wertHK == gesuchterWert) {
			  ind = hand.get(i);
		  }
	  }
	  return ind;
  }
  
  /**
   * Funktion wählt für den Computer aus, welche Farbe er sich bei einem Wünscher aussucht
   * Dazu wird geschaut, von welcher Farbe er am meisten Karten auf der Hand hat
   * @param Kartensatz aktueller Stand des Kartensatzes
   * @return Farbe gewählte Farbe
   */
  public Farbe farbeAussuchen(Kartensatz karten) {
	  kartensatz = karten;
	  Farbe wahl = Farbe.KREUZ;	
	  hand = kartensatz.getHand(Spieler.COMPUTER);											//Speichert die Karten, die der Computer aktuell auf der Hand hat
	  
	  int hoechsteAnzahl = 0;
	  int anzahl = 0;
	  
	  Farbe[] farben = {Farbe.KREUZ, Farbe.PIK, Farbe.HERZ, Farbe.KARO};
	  
	  for (int i = 0; i < farben.length; i++) {
		  anzahl = farbeZahl(farben[i]);
		  if (anzahl > hoechsteAnzahl) {
			  hoechsteAnzahl = anzahl;
			  wahl = farben[i];
		  }
		  if (hand.size() < 6 && hand.size() > 2) {
			  if(zufall(10) > 7) {
				  wahl = farben[zufall(4)];
			  }
		  }
		  if (hand.size() < 3) {
			  if(zufall(10) > 5) {
				  wahl = farben[zufall(4)];
			  }
		  }
	  }
	  
	  return wahl;
  }
  
  /**
   * Funktion, die eine zufällige Zahl zwischen 0 und einer andere Zahl r-1 ausgibt
   * @param int r 
   * @return int zufällige Zahl
   */
  private int zufall(int r){
		Random zufall = new Random();
		
		int diced = 0;
		diced = zufall.nextInt(r);
		return diced;
	}
  
  /**
   * Funktion zählt für die jeweilige Farbe, wie viele Karten der Farbe auf der Hand des Computer sind
   * @param farbe, für welche gezählt werden soll
   * @return integer Wie viele Karten der Farbe auf der Hand sind
   */
  private int farbeZahl(Farbe farbe) {
	  int anzahl = 0;
	  
	  for (int i = 0; i < hand.size(); i++) {
		  Farbe farbeHK = kartensatz.getKarte(hand.get(i)).getFARBE();
		  if (farbeHK == farbe) {
			  anzahl ++;
		  }
	  }
	  
	  return anzahl;
  }
  /**
   * Dies ist nur eine Testfunktion
   * @return Integer, gibt immer 1 zurück
   */
  public int cpuTest() {
	  return 1;
  }

}
