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

// player keeps track of all player-specific variables, as well as some basic logic functions to support more complex table logic

package player

import (
	"golang.org/x/mobile/exp/sprite"
	"hearts/logic/card"
)

// Returns a player instance with playerIndex equal to index
func NewPlayer(index int, name string, tex sprite.SubTex) *Player {
	return &Player{
		hand:        nil,
		tricks:      make([]*card.Card, 0),
		score:       0,
		playerIndex: index,
		playerName:  name,
		playerImage: tex,
		donePassing: false,
		doneTaking:  false,
		doneScoring: false,
	}
}

type Player struct {
	hand        []*card.Card
	passedFrom  []*card.Card
	passedTo    []*card.Card
	tricks      []*card.Card
	score       int
	playerIndex int
	playerName  string
	playerImage sprite.SubTex
	donePassing bool
	doneTaking  bool
	donePlaying bool
	doneScoring bool
}

// Returns the hand of p
func (p *Player) GetHand() []*card.Card {
	return p.hand
}

// Returns the cards that have been passed to p
func (p *Player) GetPassedTo() []*card.Card {
	return p.passedTo
}

// Returns the cards that p passed
func (p *Player) GetPassedFrom() []*card.Card {
	return p.passedFrom
}

// Returns the score of p
func (p *Player) GetScore() int {
	return p.score
}

// Returns the playerIndex of p
func (p *Player) GetPlayerIndex() int {
	return p.playerIndex
}

func (p *Player) GetName() string {
	return p.playerName
}

func (p *Player) GetImage() sprite.SubTex {
	return p.playerImage
}

// Returns true if p has finished the pass phase of the current round
func (p *Player) GetDonePassing() bool {
	return p.donePassing
}

// Returns true if p has finished the take phase of the current round
func (p *Player) GetDoneTaking() bool {
	return p.doneTaking
}

// Returns true if p has finished the play phase of the current trick
func (p *Player) GetDonePlaying() bool {
	return p.donePlaying
}

// Returns true if p has finished the score phase of the current round
func (p *Player) GetDoneScoring() bool {
	return p.doneScoring
}

// Adds card to the hand of p
func (p *Player) AddToHand(card *card.Card) {
	p.hand = append(p.hand, card)
}

// Removes card from the hand of p, every time it appears
func (p *Player) RemoveFromHand(card *card.Card) {
	for i, c := range p.hand {
		if c == card {
			p.hand = append(p.hand[:i], p.hand[i+1:]...)
		}
	}
}

// Sets hand of p in one chunk of cards
func (p *Player) SetHand(cards []*card.Card) {
	p.hand = cards
}

// Sets passedTo of p to cards
func (p *Player) SetPassedTo(cards []*card.Card) {
	p.passedTo = cards
}

// Sets passedFrom of p to cards
func (p *Player) SetPassedFrom(cards []*card.Card) {
	p.passedFrom = cards
}

// Sets p.donePassing to isDone
func (p *Player) SetDonePassing(isDone bool) {
	p.donePassing = isDone
}

// Sets p.doneTaking to isDone
func (p *Player) SetDoneTaking(isDone bool) {
	p.doneTaking = isDone
}

// Sets p.donePlaying to isDone
func (p *Player) SetDonePlaying(isDone bool) {
	p.donePlaying = isDone
}

// Sets p.doneScoring to isDone
func (p *Player) SetDoneScoring(isDone bool) {
	p.doneScoring = isDone
}

// Adds cards to the tricks deck of p
func (p *Player) TakeTrick(cards []*card.Card) {
	p.tricks = append(p.tricks, cards...)
}

// Adds points to the total score of p
func (p *Player) UpdateScore(points int) {
	p.score += points
}

// Calculates and returns the total point value of the cards in the tricks deck of p
func (p *Player) CalculateScore() int {
	score := 0
	for _, c := range p.tricks {
		if c.GetSuit() == card.Heart {
			score += 1
		} else if c.GetSuit() == card.Spade && c.GetFace() == card.Queen {
			score += 13
		}
	}
	return score
}

// Sets the passedTo deck of p to a new empty list
func (p *Player) ResetPassedTo() {
	p.passedTo = make([]*card.Card, 0)
}

// Sets the passedFrom deck of p to a new empty list
func (p *Player) ResetPassedFrom() {
	p.passedFrom = make([]*card.Card, 0)
}

// Sets the tricks deck of p to a new empty list
func (p *Player) ResetTricks() {
	p.tricks = make([]*card.Card, 0)
}

// Resets the score of p to 0 for a new game
func (p *Player) ResetScore() {
	p.score = 0
}

// Given a suit, returns whether not there is at least one card of that suit in the hand of p
func (p *Player) HasSuit(suit card.Suit) bool {
	for _, c := range p.hand {
		if c.GetSuit() == suit {
			return true
		}
	}
	return false
}

// Returns true if p has at least one heart card in hand and no cards of any other suit
func (p *Player) HasOnlyHearts() bool {
	return !(p.HasSuit(card.Club) || p.HasSuit(card.Diamond) || p.HasSuit(card.Spade) || !p.HasSuit(card.Heart))
}

// Returns true if the hand of p doesn't contain any 0-point cards (all clubs and diamonds, and all spades aside from the queen)
func (p *Player) HasAllPoints() bool {
	for _, c := range p.hand {
		if !c.WorthPoints() {
			return false
		}
	}
	return true
}

// Returns true if p has the two of clubs in hand
func (p *Player) HasTwoOfClubs() bool {
	for _, c := range p.hand {
		if c.GetSuit() == card.Club && c.GetFace() == card.Two {
			return true
		}
	}
	return false
}
