// 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"}
	images := []sprite.SubTex{texs["player0.jpeg"], texs["player1.jpeg"], texs["player2.jpeg"], texs["player3.jpeg"]}
	for i := 0; i < numPlayers; i++ {
		players = append(players, player.NewPlayer(i, names[i], images[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.Right,
	}
}

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 true if this move was valid based on game logic
func (t *Table) ValidPlayLogic(c *card.Card, playerIndex int) bool {
	player := t.players[playerIndex]
	if t.firstPlayer == playerIndex {
		if !t.firstTrick {
			if c.GetSuit() != card.Heart || t.heartsBroken {
				return true
			} else {
				if player.HasOnlyHearts() {
					return true
				}
			}
		} else if c.GetSuit() == card.Club && c.GetFace() == card.Two {
			return true
		}
	} else {
		firstPlayedSuit := t.trick[t.firstPlayer].GetSuit()
		if c.GetSuit() == firstPlayedSuit || !player.HasSuit(firstPlayedSuit) {
			if !t.firstTrick {
				return true
			} else if !c.WorthPoints() {
				return true
			} else if player.HasAllPoints() {
				return true
			}
		}
	}
	return false
}

// 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
}
