// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// table contains and manages the logic half of the game state

package table

import (
	"golang.org/x/mobile/exp/sprite"
	"hearts/img/direction"
	"hearts/logic/card"
	"hearts/logic/player"
	"math/rand"
	"sort"
)

// Returns a table instance with player set length numPlayers
func InitializeGame(numPlayers int, texs map[string]sprite.SubTex) *Table {
	players := make([]*player.Player, 0)
	names := []string{"YoungSeok", "Dan", "Emily", "Ross"}
	iconImages := []sprite.SubTex{texs["player0.jpeg"], texs["player1.jpeg"], texs["player2.jpeg"], texs["player3.jpeg"]}
	deviceImages := []sprite.SubTex{texs["laptopIcon.png"], texs["watchIcon.png"], texs["tabletIcon.png"], texs["phoneIcon.png"]}
	for i := 0; i < numPlayers; i++ {
		players = append(players, player.NewPlayer(i, names[i], iconImages[i], deviceImages[i]))
	}
	t := makeTable(players)
	t.GenerateClassicCards()
	t.NewRound()
	return t
}

// Given a group of players, returns a table instance with that group as its player set
func makeTable(p []*player.Player) *Table {
	return &Table{
		players:      p,
		trick:        make([]*card.Card, len(p)),
		firstPlayer:  -1,
		allCards:     nil,
		heartsBroken: false,
		firstTrick:   true,
		winCondition: 100,
		dir:          direction.None,
	}
}

type Table struct {
	// players contains all players in the game, indexed by playerIndex
	players []*player.Player
	// trick contains all cards in the current trick, indexed by the playerIndex of the player who played them
	trick []*card.Card
	// firstPlayer is the index in trick of the card played first
	firstPlayer int
	// allCards contains all 52 cards in the deck. GenerateCards() populates this
	allCards []*card.Card
	// heartsBroken returns true if a heart has been played yet in the round, otherwise false
	heartsBroken bool
	// firstTrick returns true if the current trick is the first in the round, otherwise false
	firstTrick bool
	// winCondition is the number of points needed to win the game
	// traditionally 100, could set higher or lower for longer or shorter game
	winCondition int
	// dir is the current round's passing direction
	dir direction.Direction
}

// Returns the player set of t
func (t *Table) GetPlayers() []*player.Player {
	return t.players
}

// Returns the current trick of t
func (t *Table) GetTrick() []*card.Card {
	return t.trick
}

// Returns the index in t.players and t.trick of the designated first player in the current round
func (t *Table) GetFirstPlayer() int {
	return t.firstPlayer
}

// Returns the deck of all cards stored in t
func (t *Table) GetAllCards() []*card.Card {
	return t.allCards
}

func (t *Table) GetDir() direction.Direction {
	return t.dir
}

// Sets the firstplayer variable of t to index
func (t *Table) SetFirstPlayer(index int) {
	t.firstPlayer = index
}

// Returns the index of the player whose turn it is, -1 if this cannot be determined at this time
func (t *Table) WhoseTurn() int {
	allNil := true
	for i, c := range t.trick {
		nextPlayerIndex := (i + 1) % len(t.players)
		if c != nil {
			allNil = false
			if t.trick[nextPlayerIndex] == nil {
				return nextPlayerIndex
			}
		}
	}
	if allNil {
		return t.firstPlayer
	}
	return -1
}

// This function generates a traditional deck of 52 cards, with 13 in each of the four suits
// Each card has a suit (Club, Diamond, Spade, or Heart)
// Each card also has a face from Two to Ace (Aces are high in Hearts)
func (t *Table) GenerateClassicCards() {
	cardsPerSuit := 13
	t.allCards = make([]*card.Card, 0)
	cardFaces := []card.Face{card.Two, card.Three, card.Four, card.Five, card.Six, card.Seven, card.Eight, card.Nine,
		card.Ten, card.Jack, card.Queen, card.King, card.Ace}
	for i := 0; i < cardsPerSuit; i++ {
		t.allCards = append(t.allCards, card.NewCard(cardFaces[i], card.Club))
		t.allCards = append(t.allCards, card.NewCard(cardFaces[i], card.Diamond))
		t.allCards = append(t.allCards, card.NewCard(cardFaces[i], card.Spade))
		t.allCards = append(t.allCards, card.NewCard(cardFaces[i], card.Heart))
	}
	sort.Sort(card.CardSorter(t.allCards))
}

// Given a card and the index of its player, adds that card to the appropriate spot in the current trick
func (t *Table) SetPlayedCard(c *card.Card, playerIndex int) {
	t.trick[playerIndex] = c
	if c.GetSuit() == card.Heart && !t.heartsBroken {
		t.heartsBroken = true
	}
}

// Returns true if there are exactly three cards being passed (specified by Hearts logic)
func (t *Table) ValidPass(cardsPassed []*card.Card) bool {
	return len(cardsPassed) == 3
}

// Returns whether it is valid for the player at playerIndex to play a card
func (t *Table) ValidPlayOrder(playerIndex int) bool {
	return t.WhoseTurn() == playerIndex
}

// Given a card and the index of its player, returns "" if this move was valid based on game logic
// Otherwise returns a string explaining the error
func (t *Table) ValidPlayLogic(c *card.Card, playerIndex int) string {
	validPlay := ""
	player := t.players[playerIndex]
	if t.firstPlayer == playerIndex {
		if !t.firstTrick {
			if c.GetSuit() != card.Heart || t.heartsBroken {
				return validPlay
			} else {
				if player.HasOnlyHearts() {
					return validPlay
				} else {
					return "Hearts have not been broken"
				}
			}
		} else if c.GetSuit() == card.Club && c.GetFace() == card.Two {
			return validPlay
		} else {
			return "Must open with the Two of Clubs"
		}
	} else {
		firstPlayedSuit := t.trick[t.firstPlayer].GetSuit()
		if c.GetSuit() == firstPlayedSuit || !player.HasSuit(firstPlayedSuit) {
			if !t.firstTrick {
				return validPlay
			} else if !c.WorthPoints() {
				return validPlay
			} else if player.HasAllPoints() {
				return validPlay
			} else {
				return "Point cards not allowed in the first round"
			}
		} else {
			return "Must follow suit"
		}
	}
	return "Invalid play"
}

// Returns true if all players have their initial dealt hands
func (t *Table) AllDoneDealing() bool {
	for _, p := range t.players {
		if len(p.GetHand()) == 0 {
			return false
		}
	}
	return true
}

// Returns true if all players have taken the cards passed to them
func (t *Table) AllDonePassing() bool {
	for _, p := range t.players {
		if !p.GetDonePassing() {
			return false
		}
	}
	return true
}

// Returns true if all players have finished looking at their scores
func (t *Table) AllReadyForNewRound() bool {
	for _, p := range t.players {
		if !p.GetDoneScoring() {
			return false
		}
	}
	return true
}

// Returns true if all players are out of cards, indicating the end of a round
func (t *Table) RoundOver() bool {
	for _, p := range t.players {
		if len(p.GetHand()) > 0 {
			return false
		}
	}
	return true
}

// Calculates who should take the cards in the current trick and sends them. Sets next first player accordingly. Returns true if the round is over
func (t *Table) SendTrick() (bool, int) {
	trickSuit := t.trick[t.firstPlayer].GetSuit()
	highestCardFace := card.Two
	highestIndex := -1
	for i := 0; i < len(t.trick); i++ {
		curCard := t.trick[i]
		if curCard.GetSuit() == trickSuit && curCard.GetFace() >= highestCardFace {
			highestCardFace = curCard.GetFace()
			highestIndex = i
		}
	}
	// resets all players' donePlaying bools
	for _, p := range t.players {
		p.SetDonePlaying(false)
	}
	// clear trick
	t.players[highestIndex].TakeTrick(t.trick)
	t.trick = make([]*card.Card, len(t.players))
	if t.firstTrick {
		t.firstTrick = false
	}
	if t.RoundOver() {
		return true, highestIndex
	}
	// set first player for next trick to whoever received the current trick
	t.SetFirstPlayer(highestIndex)
	return false, highestIndex
}

// Returns the score of the current round
// Accounts for a player possibly shooting the moon
func (t *Table) ScoreRound() []int {
	allPoints := 26
	roundScores := make([]int, len(t.players))
	shotMoon := false
	shooter := -1
	for i := 0; i < len(t.players); i++ {
		roundScores[i] = t.players[i].CalculateScore()
		if roundScores[i] == allPoints {
			shotMoon = true
			shooter = i
		}
	}
	if shotMoon {
		for i := 0; i < len(t.players); i++ {
			if i == shooter {
				roundScores[i] = 0
			} else {
				roundScores[i] = allPoints
			}
		}
	}
	return roundScores
}

// Adds the scores of the current round to the players total scores
func (t *Table) UpdatePlayerScores(roundScores []int) {
	for i := 0; i < len(t.players); i++ {
		t.players[i].UpdateScore(roundScores[i])
	}
}

// Returns set of hands with random, even card distribution
func (t *Table) Deal() [][]*card.Card {
	numPlayers := len(t.players)
	allHands := make([][]*card.Card, numPlayers)
	shuffle := rand.Perm(len(t.allCards))
	for i := 0; i < len(t.allCards); i++ {
		allHands[i%numPlayers] = append(allHands[i%numPlayers], t.allCards[shuffle[i]])
	}
	return allHands
}

// Returns an array of the current round's scores, and an array of the game winners
// The winners array is empty if the game hasn't been won yet, contains all playerIndices of the winners if it has
func (t *Table) EndRound() ([]int, []int) {
	roundScores := t.ScoreRound()
	t.UpdatePlayerScores(roundScores)
	lowestScore := -1
	winningPlayers := make([]int, 0)
	winTriggered := false
	t.dir = (t.dir + 1) % 4
	for _, p := range t.players {
		p.ResetTricks()
		if p.GetScore() >= t.winCondition {
			winTriggered = true
		}
		if p.GetScore() < lowestScore || lowestScore == -1 {
			lowestScore = p.GetScore()
		}
	}
	if winTriggered {
		for _, p := range t.players {
			if p.GetScore() == lowestScore {
				winningPlayers = append(winningPlayers, p.GetPlayerIndex())
			}
		}
	}
	return roundScores, winningPlayers
}

// Resets stats for a new round of the game
func (t *Table) NewRound() {
	t.heartsBroken = false
	t.firstTrick = true
	players := t.GetPlayers()
	for _, p := range players {
		if t.dir != direction.None {
			p.SetDonePassing(false)
			p.SetDoneTaking(false)
			t.SetFirstPlayer(-1)
		} else {
			p.SetDonePassing(true)
			p.SetDoneTaking(true)
			if p.HasTwoOfClubs() {
				t.SetFirstPlayer(p.GetPlayerIndex())
			}
		}
		p.SetDoneScoring(false)
	}
}

// Resets table for start of new game
func (t *Table) NewGame() {
	for _, p := range t.players {
		p.ResetPassedTo()
		p.ResetPassedFrom()
		p.ResetTricks()
		p.ResetScore()
	}
	t.NewRound()
	t.dir = direction.Right
}
