import java.util.LinkedList;
import java.util.Random;

public class Blackjack {
  //aces only count as 1, not as 11
  
  private class Card {
    private int rank, value, suit;
    private boolean used;
    
    public Card(int rank, int value, int suit) {
      this.rank = rank;
      this.value = value;
      this.suit = suit;
      used = false;
    }  
    public void deal () {  used = true; }
    public void reset () { used = false; }
    public int getValue() { return value; }
    public int getRank() {  return rank;  }
    public int getSuit() {  return suit;  }
    public boolean getUsed() {  return used;  }   
  }
  
  Random rng;
  LinkedList<Card> dealer, player;
  int cardsUsed, dealerHand, playerHand, win, lose;
  Card[] deck = new Card[52];
  
  public Blackjack() {
    int temp = -1;
    int place = -10;
    //loop through all 52 spots
    for (int i = 1; i <= 4; i++) {
      for (int j = 1; j <= 13; j++) {
        place = (13*(i-1))+(j-1);
        if (j > 10) { temp = 10; }
        else { temp = j; }
        deck[place] = new Card(j, temp, i);
      }
    }
    rng = new Random();
  }
  
  //deal the next hand
  public void dealHand() {
    if (cardsUsed > 35) {  shuffle();  }
    dealer = new LinkedList<Card>();
    player = new LinkedList<Card>();
    dealerHand = 0;
    playerHand = 0;
    
    Card one = dealCard();
    Card two = dealCard();
    Card three = dealCard();
    Card four = dealCard();
    player.add(one);
    player.add(three);
    dealer.add(two);
    dealer.add(four);
    playerHand += one.getValue() + three.getValue();
    dealerHand += four.getValue() + two.getValue();
    System.out.println("You have: " + expandPlayer() + "for a total of: " + playerHand);
    System.out.println("Dealer shows: " + expandDealer(false) + "what would you like to do?");        
  }
  
  //get an expanded string for the dealers hand, hiding the first card if needed
  public String expandDealer(boolean done) {
    String ret = "";
    int i = 1;
    if (done) {   i = 0;  }
    for (; i < dealer.size(); i++) {
      ret += dealer.get(i).getValue() + ", ";
    }
    return ret;
  }
  //get an expanded string for the players hand
  public String expandPlayer() {
    String ret = "";
    for (int i =0; i < player.size(); i++) {
      ret += player.get(i).getValue() + " ";
    }
    return ret;
  }
  
  public void hit() {
    Card next = dealCard(); //get next card
    cardsUsed++; 
    player.add(next);
    playerHand += next.getValue();
    if (playerHand > 21) {  System.out.println("You busted."); determineResult(); }
    else {
      System.out.println("You have: " + expandPlayer() + "for a total of: " + playerHand);
      System.out.println("Dealer shows: " + expandDealer(false) + "what would you like to do?");    
    }
  }
  public void stay() {
    while (dealerHand < 17) {
      Card a = dealCard();
      dealer.add(a);
      dealerHand += a.getValue();
    }
    determineResult();
  }
  
  public int getCardsUsed() { return cardsUsed; }
  
  public void determineResult() {
    System.out.println("You have: " + expandPlayer() + "for a total of: " + playerHand);
    System.out.println("Dealer shows: " + expandDealer(true) + "for a total of: " + dealerHand);     
    //player busts
    if (playerHand > 21) {
      lose++;
      System.out.println ("You lost.");
    }
    //dealer busts, or else, player has higher hand than dealer
    else if (dealerHand > 21 || playerHand > dealerHand) {
      System.out.println ("You won.");
    }
    //nobody busted and dealer has higher hand
    else {
      System.out.println ("You lost.");
    }
  }
  public void reset() {
    shuffle();
    win = 0;
    lose = 0;
  }
  public void getRecord() {
    System.out.println("You have won: " + win + " games and lost: " + lose + " games");
  }
  public void shuffle() {
    cardsUsed = 0;
    int place = -1;
    //loop through all 52
    for (int i = 1; i <= 4; i++) {
      for (int j = 1; j <= 13; j++) {
        place = (13*(i-1))+(j-1);
        deck[place].reset();
      }
    }
    rng = new Random();
  }
  
  
  public Card dealCard() {
    //nextInt calls for the next random number UP TO BUT NOT INCLUDING the
    //paramter, in this case it will return an int from 0 to 51
    int temp = rng.nextInt(52);
    while (deck[temp].getUsed()) {  temp = rng.nextInt();  }
    deck[temp].deal();
    return deck[temp];
  }
}