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

package table

import (
	"math/rand"
	"sprites/card"
	"sprites/player"
)

func NewTable(p []*player.Player) *Table {
	return &Table{
		players:      p,
		trick:        make([]*card.Card, len(p)),
		firstPlayed:  -1,
		allCards:     nil,
		heartsBroken: false,
		firstTrick:   true,
		winCondition: 100,
	}
}

type Table struct {
	//players and trick should each have 4 elements
	players []*player.Player
	trick   []*card.Card
	//firstPlayed is the index in trick of the card played first
	firstPlayed  int
	allCards     []*card.Card
	heartsBroken bool
	firstTrick   bool
	winCondition int
}

func (t *Table) GetPlayers() []*player.Player {
	return t.players
}

func (t *Table) SetFirstPlayed(index int) {
	t.firstPlayed = index
}

func (t *Table) GenerateCards() {
	t.allCards = make([]*card.Card, 0)
	for i := 0; i < 13; i++ {
		t.allCards = append(t.allCards, card.NewCard(i+2, "C"))
		t.allCards = append(t.allCards, card.NewCard(i+2, "D"))
		t.allCards = append(t.allCards, card.NewCard(i+2, "S"))
		t.allCards = append(t.allCards, card.NewCard(i+2, "H"))
	}
}

func (t *Table) PlayCard(c *card.Card, playerIndex int) {
	t.trick[playerIndex] = c
	if c.GetSuit() == "H" && t.heartsBroken == false {
		t.heartsBroken = true
	}
}

func (t *Table) ValidPlay(c *card.Card, playerIndex int) bool {
	player := t.players[playerIndex]
	if t.firstPlayed == playerIndex {
		if t.firstTrick == false {
			if c.GetSuit() != "H" || t.heartsBroken == true {
				return true
			} else if player.HasSuit("C") == false && player.HasSuit("D") == false && player.HasSuit("S") == false {
				return true
			}
		} else if c.GetSuit() == "C" && c.GetNum() == 2 {
			return true
		}
	} else {
		firstPlayedSuit := t.trick[t.firstPlayed].GetSuit()
		if c.GetSuit() == firstPlayedSuit || player.HasSuit(firstPlayedSuit) == false {
			if t.firstTrick == false {
				return true
			} else if c.GetSuit() == "D" || c.GetSuit() == "C" || (c.GetSuit() == "S" && c.GetNum() != 12) {
				return true
			} else if player.HasAllPoints() == true {
				return true
			}
		}
	}
	return false
}

func (t *Table) SendTrick() {
	trickSuit := t.trick[t.firstPlayed].GetSuit()
	highest := -1
	highestIndex := -1
	for i := 0; i < len(t.trick); i++ {
		curCard := t.trick[i]
		if curCard.GetSuit() == trickSuit && curCard.GetNum() > highest {
			highest = curCard.GetNum()
			highestIndex = i
		}
	}
	//clear trick
	t.players[highestIndex].TakeTrick(t.trick)
	for i := 0; i < len(t.trick); i++ {
		t.trick[i] = nil
	}
	if t.firstTrick == true {
		t.firstTrick = false
	}
}

func (t *Table) ScoreRound() {
	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] == 26 {
			shotMoon = true
			shooter = i
		}
	}
	//if the moon was shot
	if shotMoon == true {
		for i := 0; i < len(t.players); i++ {
			if i == shooter {
				roundScores[i] = 0
			} else {
				roundScores[i] = 26
			}
		}
	}
	//sending scores to players
	for i := 0; i < len(t.players); i++ {
		t.players[i].UpdateScore(roundScores[i])
	}
}

func (t *Table) Deal() {
	numPlayers := len(t.players)
	if t.allCards == nil {
		t.GenerateCards()
	}
	shuffle := rand.Perm(52)
	for i := 0; i < len(t.allCards); i++ {
		t.players[i%numPlayers].AddToHand(t.allCards[shuffle[i]])
	}
}

//returns -1 if the game hasn't been won, playerIndex of the winner if it has
func (t *Table) EndRound() int {
	t.ScoreRound()
	for _, p := range t.players {
		p.ResetTricks()
		if p.GetScore() >= 100 {
			return p.GetPlayerIndex()
		}
	}
	return -1
}

func (t *Table) NewRound() {
	t.heartsBroken = false
	t.firstTrick = true
	t.Deal()
}
