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

// view handles the loading of new UI screens.
// Currently supported screens: Opening, Table, Pass, Take, Play, Score
// Future support: All screens part of the discovery process

package view

import (
	"fmt"
	"sort"
	"strconv"

	"hearts/img/coords"
	"hearts/img/direction"
	"hearts/img/reposition"
	"hearts/img/staticimg"
	"hearts/img/texture"
	"hearts/img/uistate"
	"hearts/logic/card"

	"golang.org/x/mobile/exp/f32"
	"golang.org/x/mobile/exp/sprite"
)

func ReloadView(u *uistate.UIState) {
	switch u.CurView {
	case uistate.Discovery:
		LoadDiscoveryView(u)
	case uistate.Arrange:
		LoadArrangeView(u)
	case uistate.Table:
		LoadTableView(u)
	case uistate.Pass:
		LoadPassView(u)
	case uistate.Take:
		LoadTakeView(u)
	case uistate.Play:
		LoadPlayView(u)
	case uistate.Split:
		LoadSplitView(true, u)
	}
}

// Arrange view: For seating players
func LoadArrangeView(u *uistate.UIState) {
	u.M.Lock()
	fmt.Println("ARRANGE LOCKED")
	reposition.ResetAnims(u)
	resetImgs(u)
	resetScene(u)
	u.CurView = uistate.Arrange
	addHeader(u)
	watchImg := u.Texs["WatchSpotUnpressed.png"]
	watchAlt := u.Texs["WatchSpotPressed.png"]
	arrangeBlockLength := u.WindowSize.X - 4*u.Padding
	if u.WindowSize.Y < u.WindowSize.X {
		arrangeBlockLength = u.WindowSize.Y - u.CardDim.Y
	}
	arrangeDim := coords.MakeVec(arrangeBlockLength/3-4*u.Padding, arrangeBlockLength/3-4*u.Padding)
	// player 0 seat
	addArrangePlayer(0, arrangeDim, arrangeBlockLength, u)
	// player 1 seat
	addArrangePlayer(1, arrangeDim, arrangeBlockLength, u)
	// player 2 seat
	addArrangePlayer(2, arrangeDim, arrangeBlockLength, u)
	// player 3 seat
	addArrangePlayer(3, arrangeDim, arrangeBlockLength, u)
	// table
	watchPos := coords.MakeVec((u.WindowSize.X-arrangeDim.X)/2, (u.WindowSize.Y+arrangeBlockLength)/2-2*arrangeDim.Y-4*u.Padding)
	u.Buttons["joinTable"] = texture.MakeImgWithAlt(watchImg, watchAlt, watchPos, arrangeDim, true, u)
	quitImg := u.Texs["QuitUnpressed.png"]
	quitAlt := u.Texs["QuitPressed.png"]
	quitDim := u.CardDim
	quitPos := coords.MakeVec(u.Padding, u.TopPadding+10)
	u.Buttons["exit"] = texture.MakeImgWithAlt(quitImg, quitAlt, quitPos, quitDim, true, u)
	if u.IsOwner {
		startImg := u.Texs["StartBlue.png"]
		startAlt := u.Texs["StartBluePressed.png"]
		startDim := coords.MakeVec(2*u.CardDim.X, u.CardDim.Y)
		startPos := u.WindowSize.MinusVec(startDim).Minus(u.BottomPadding)
		display := u.CurTable.AllReadyForNewRound()
		u.Buttons["start"] = texture.MakeImgWithAlt(startImg, startAlt, startPos, startDim, true, u)
		var emptyTex sprite.SubTex
		if !display {
			u.Eng.SetSubTex(u.Buttons["start"].GetNode(), emptyTex)
		}
	}
	u.M.Unlock()
	fmt.Println("UNLOCKED")
}

// Waiting view: Displays the word "Waiting". To be displayed when players are waiting for a new round to be dealt
// TODO(emshack): Integrate this with Arrange view and Score view so that a separate screen is not necessary
func LoadWaitingView(u *uistate.UIState) {
	u.M.Lock()
	fmt.Println("WAITING LOCKED")
	reposition.ResetAnims(u)
	resetImgs(u)
	resetScene(u)
	center := u.WindowSize.DividedBy(2)
	maxWidth := u.WindowSize.X - 2*u.Padding
	scaler := float32(3)
	textImgs := texture.MakeStringImgCenterAlign("Waiting...", "", "", true, center, scaler, maxWidth, u)
	for _, img := range textImgs {
		u.BackgroundImgs = append(u.BackgroundImgs, img)
	}
	u.M.Unlock()
	fmt.Println("UNLOCKED")
}

// Discovery view: Displays a menu of possible games to join
func LoadDiscoveryView(u *uistate.UIState) {
	u.M.Lock()
	fmt.Println("DISCOVERY LOCKED")
	reposition.ResetAnims(u)
	resetImgs(u)
	resetScene(u)
	u.CurView = uistate.Discovery
	newGameImg := u.Texs["NewGameUnpressed.png"]
	newGameAlt := u.Texs["NewGamePressed.png"]
	newGameDim := coords.MakeVec(2*u.CardDim.X, u.CardDim.Y)
	newGamePos := coords.MakeVec((u.WindowSize.X-newGameDim.X)/2, u.TopPadding)
	u.Buttons["newGame"] = texture.MakeImgWithAlt(newGameImg, newGameAlt, newGamePos, newGameDim, true, u)
	buttonNum := 1
	for _, d := range u.DiscGroups {
		if d != nil {
			dataMap := d.GameStartData
			creatorID := int(dataMap["ownerID"].(float64))
			if u.UserData[creatorID] != nil {
				bgBannerDim := coords.MakeVec(u.WindowSize.X, u.CardDim.Y+(4*u.Padding/5))
				bgBannerPos := coords.MakeVec(0, newGamePos.Y+float32(buttonNum)*(bgBannerDim.Y+u.Padding))
				playerIconImg := u.Texs[u.UserData[creatorID]["avatar"].(string)]
				playerIconDim := u.CardDim
				playerIconPos := coords.MakeVec(u.BottomPadding, bgBannerPos.Y+2*u.Padding/5)
				u.BackgroundImgs = append(u.BackgroundImgs,
					texture.MakeImgWithoutAlt(playerIconImg, playerIconPos, playerIconDim, u))
				creatorName := u.UserData[creatorID]["name"].(string)
				gameText := creatorName + "'s game"
				scaler := float32(6)
				maxWidth := u.WindowSize.X - 3*u.CardDim.X - 4*u.Padding
				left := coords.MakeVec(playerIconPos.X+playerIconDim.X+u.Padding, playerIconPos.Y+playerIconDim.Y/2-10)
				textImgs := texture.MakeStringImgLeftAlign(gameText, "", "", true, left, scaler, maxWidth, u)
				for _, img := range textImgs {
					u.BackgroundImgs = append(u.BackgroundImgs, img)
				}
				joinGameImg := u.Texs["JoinGameUnpressed.png"]
				joinGameAlt := u.Texs["JoinGamePressed.png"]
				joinGamePos := coords.MakeVec(u.WindowSize.X-u.BottomPadding-newGameDim.X, newGamePos.Y+float32(buttonNum)*(bgBannerDim.Y+u.Padding))
				u.Buttons[fmt.Sprintf("joinGame-%d", buttonNum)] = texture.MakeImgWithAlt(joinGameImg, joinGameAlt, joinGamePos, newGameDim, true, u)
				u.Buttons[fmt.Sprintf("joinGame-%d", buttonNum)].SetInfo(d.LogAddr)
				buttonNum++
			}
		}
	}
	u.M.Unlock()
	fmt.Println("UNLOCKED")
}

// Table View: Displays the table. Intended for public devices
func LoadTableView(u *uistate.UIState) {
	u.M.Lock()
	fmt.Println("TABLE LOCKED")
	reposition.ResetAnims(u)
	resetImgs(u)
	resetScene(u)
	u.CurView = uistate.Table
	scaler := float32(6)
	maxWidth := 4 * u.TableCardDim.X
	// adding four drop targets for trick
	dropTargetImage := u.Texs["trickDrop.png"]
	dropTargetAlt := u.Texs["trickDropBlue.png"]
	dropTargetDimensions := u.CardDim
	dropTargetX := (u.WindowSize.X - u.CardDim.X) / 2
	dropTargetY := u.WindowSize.Y/2 + u.CardDim.Y/2 + u.Padding
	dropTargetPos := coords.MakeVec(dropTargetX, dropTargetY)
	u.DropTargets = append(u.DropTargets,
		texture.MakeImgWithAlt(dropTargetImage, dropTargetAlt, dropTargetPos, dropTargetDimensions, true, u))
	// take trick button
	takeTrickImage := u.Texs["TakeTrickTableUnpressed.png"]
	takeTrickAlt := u.Texs["TakeTrickTablePressed.png"]
	takeTrickDim := coords.MakeVec(u.CardDim.X, u.CardDim.Y)
	takeTrickPos := coords.MakeVec(dropTargetX, dropTargetY-u.Padding-takeTrickDim.Y)
	u.Buttons["takeTrick"] = texture.MakeImgWithAlt(takeTrickImage, takeTrickAlt, takeTrickPos, takeTrickDim, true, u)
	if !u.CurTable.TrickOver() {
		var emptyTex sprite.SubTex
		u.Eng.SetSubTex(u.Buttons["takeTrick"].GetNode(), emptyTex)
	}
	// card on top of first drop target
	dropCard := u.CurTable.GetTrick()[0]
	if dropCard != nil {
		texture.PopulateCardImage(dropCard, u)
		dropCard.SetInitial(dropTargetPos)
		dropCard.Move(dropTargetPos, dropTargetDimensions, u.Eng)
		u.Cards = append(u.Cards, dropCard)
	}
	// second drop target
	dropTargetY = (u.WindowSize.Y - u.CardDim.Y) / 2
	dropTargetX = u.WindowSize.X/2 - 3*u.CardDim.X/2 - u.Padding
	dropTargetPos = coords.MakeVec(dropTargetX, dropTargetY)
	u.DropTargets = append(u.DropTargets,
		texture.MakeImgWithAlt(dropTargetImage, dropTargetAlt, dropTargetPos, dropTargetDimensions, true, u))
	// card on top of second drop target
	dropCard = u.CurTable.GetTrick()[1]
	if dropCard != nil {
		texture.PopulateCardImage(dropCard, u)
		dropCard.SetInitial(dropTargetPos)
		dropCard.Move(dropTargetPos, dropTargetDimensions, u.Eng)
		u.Cards = append(u.Cards, dropCard)
	}
	// third drop target
	dropTargetX = (u.WindowSize.X - u.CardDim.X) / 2
	dropTargetY = u.WindowSize.Y/2 - 3*u.CardDim.Y/2 - u.Padding
	dropTargetPos = coords.MakeVec(dropTargetX, dropTargetY)
	u.DropTargets = append(u.DropTargets,
		texture.MakeImgWithAlt(dropTargetImage, dropTargetAlt, dropTargetPos, dropTargetDimensions, true, u))
	// card on top of third drop target
	dropCard = u.CurTable.GetTrick()[2]
	if dropCard != nil {
		texture.PopulateCardImage(dropCard, u)
		dropCard.SetInitial(dropTargetPos)
		dropCard.Move(dropTargetPos, dropTargetDimensions, u.Eng)
		u.Cards = append(u.Cards, dropCard)
	}
	// fourth drop target
	dropTargetY = (u.WindowSize.Y - u.CardDim.Y) / 2
	dropTargetX = u.WindowSize.X/2 + u.CardDim.X/2 + u.Padding
	dropTargetPos = coords.MakeVec(dropTargetX, dropTargetY)
	u.DropTargets = append(u.DropTargets,
		texture.MakeImgWithAlt(dropTargetImage, dropTargetAlt, dropTargetPos, dropTargetDimensions, true, u))
	// card on top of fourth drop target
	dropCard = u.CurTable.GetTrick()[3]
	if dropCard != nil {
		texture.PopulateCardImage(dropCard, u)
		dropCard.SetInitial(dropTargetPos)
		dropCard.Move(dropTargetPos, dropTargetDimensions, u.Eng)
		u.Cards = append(u.Cards, dropCard)
	}
	// number of tricks each player has taken
	SetNumTricksTable(u)
	// adding 4 player icons, text, and device icons
	playerIconImage := uistate.GetAvatar(0, u)
	playerIconX := (u.WindowSize.X - u.PlayerIconDim.X) / 2
	playerIconY := u.WindowSize.Y - u.TableCardDim.Y - u.BottomPadding - u.Padding - u.PlayerIconDim.Y
	playerIconPos := coords.MakeVec(playerIconX, playerIconY)
	if u.Debug {
		u.Buttons["player0"] = texture.MakeImgWithoutAlt(playerIconImage, playerIconPos, u.PlayerIconDim, u)
	} else {
		u.BackgroundImgs = append(u.BackgroundImgs,
			texture.MakeImgWithoutAlt(playerIconImage, playerIconPos, u.PlayerIconDim, u))
	}
	// player 0's name
	center := coords.MakeVec(playerIconX+u.PlayerIconDim.X/2, playerIconY-15)
	name := uistate.GetName(0, u)
	textImgs := texture.MakeStringImgCenterAlign(name, "", "", true, center, scaler, maxWidth, u)
	for _, img := range textImgs {
		u.BackgroundImgs = append(u.BackgroundImgs, img)
	}
	// player 0's device icon
	deviceIconImage := uistate.GetDevice(0, u)
	deviceIconDim := u.PlayerIconDim.DividedBy(2)
	deviceIconPos := coords.MakeVec(playerIconPos.X+u.PlayerIconDim.X, playerIconPos.Y)
	u.BackgroundImgs = append(u.BackgroundImgs,
		texture.MakeImgWithoutAlt(deviceIconImage, deviceIconPos, deviceIconDim, u))
	// player 1's icon
	playerIconImage = uistate.GetAvatar(1, u)
	playerIconX = u.BottomPadding
	playerIconY = (u.WindowSize.Y+2*u.BottomPadding+u.PlayerIconDim.Y-
		(float32(len(u.CurTable.GetPlayers()[1].GetHand()))*
			(u.TableCardDim.Y-u.Overlap.Y)+u.TableCardDim.Y))/2 -
		u.PlayerIconDim.Y - u.Padding
	playerIconPos = coords.MakeVec(playerIconX, playerIconY)
	if u.Debug {
		u.Buttons["player1"] = texture.MakeImgWithoutAlt(playerIconImage, playerIconPos, u.PlayerIconDim, u)
	} else {
		u.BackgroundImgs = append(u.BackgroundImgs,
			texture.MakeImgWithoutAlt(playerIconImage, playerIconPos, u.PlayerIconDim, u))
	}
	// player 1's name
	start := coords.MakeVec(playerIconX, playerIconY-15)
	name = uistate.GetName(1, u)
	textImgs = texture.MakeStringImgLeftAlign(name, "", "", true, start, scaler, maxWidth, u)
	for _, img := range textImgs {
		u.BackgroundImgs = append(u.BackgroundImgs, img)
	}
	// player 1's device icon
	deviceIconImage = uistate.GetDevice(1, u)
	deviceIconPos = coords.MakeVec(playerIconPos.X+u.PlayerIconDim.X, playerIconPos.Y+u.PlayerIconDim.Y-deviceIconDim.Y)
	u.BackgroundImgs = append(u.BackgroundImgs,
		texture.MakeImgWithoutAlt(deviceIconImage, deviceIconPos, deviceIconDim, u))
	// player 2's icon
	playerIconImage = uistate.GetAvatar(2, u)
	playerIconX = (u.WindowSize.X - u.PlayerIconDim.X) / 2
	playerIconY = u.TopPadding + u.TableCardDim.Y + u.Padding
	playerIconPos = coords.MakeVec(playerIconX, playerIconY)
	if u.Debug {
		u.Buttons["player2"] = texture.MakeImgWithoutAlt(playerIconImage, playerIconPos, u.PlayerIconDim, u)
	} else {
		u.BackgroundImgs = append(u.BackgroundImgs,
			texture.MakeImgWithoutAlt(playerIconImage, playerIconPos, u.PlayerIconDim, u))
	}
	// player 2's name
	center = coords.MakeVec(playerIconX+u.PlayerIconDim.X/2, playerIconY+u.PlayerIconDim.Y)
	name = uistate.GetName(2, u)
	textImgs = texture.MakeStringImgCenterAlign(name, "", "", true, center, scaler, maxWidth, u)
	for _, img := range textImgs {
		u.BackgroundImgs = append(u.BackgroundImgs, img)
	}
	// player 2's device icon
	deviceIconImage = uistate.GetDevice(2, u)
	deviceIconPos = coords.MakeVec(playerIconPos.X+u.PlayerIconDim.X, playerIconPos.Y+u.PlayerIconDim.Y-deviceIconDim.Y)
	u.BackgroundImgs = append(u.BackgroundImgs,
		texture.MakeImgWithoutAlt(deviceIconImage, deviceIconPos, deviceIconDim, u))
	// player 3's icon
	playerIconImage = uistate.GetAvatar(3, u)
	playerIconX = u.WindowSize.X - u.BottomPadding - u.PlayerIconDim.X
	playerIconY = (u.WindowSize.Y+2*u.BottomPadding+u.PlayerIconDim.Y-
		(float32(len(u.CurTable.GetPlayers()[3].GetHand()))*
			(u.TableCardDim.Y-u.Overlap.Y)+u.TableCardDim.Y))/2 -
		u.PlayerIconDim.Y - u.Padding
	playerIconPos = coords.MakeVec(playerIconX, playerIconY)
	if u.Debug {
		u.Buttons["player3"] = texture.MakeImgWithoutAlt(playerIconImage, playerIconPos, u.PlayerIconDim, u)
	} else {
		u.BackgroundImgs = append(u.BackgroundImgs,
			texture.MakeImgWithoutAlt(playerIconImage, playerIconPos, u.PlayerIconDim, u))
	}
	// player 3's name
	end := coords.MakeVec(playerIconX+u.PlayerIconDim.X, playerIconY-15)
	name = uistate.GetName(3, u)
	textImgs = texture.MakeStringImgRightAlign(name, "", "", true, end, scaler, maxWidth, u)
	for _, img := range textImgs {
		u.BackgroundImgs = append(u.BackgroundImgs, img)
	}
	// player 3's device icon
	deviceIconImage = uistate.GetDevice(3, u)
	deviceIconPos = coords.MakeVec(playerIconPos.X-deviceIconDim.X, playerIconPos.Y+u.PlayerIconDim.Y-deviceIconDim.Y)
	u.BackgroundImgs = append(u.BackgroundImgs,
		texture.MakeImgWithoutAlt(deviceIconImage, deviceIconPos, deviceIconDim, u))
	// adding cards
	for _, p := range u.CurTable.GetPlayers() {
		// cards in hand
		hand := p.GetHand()
		for i, c := range hand {
			texture.PopulateCardImage(c, u)
			cardIndex := coords.MakeVec(float32(len(hand)), float32(i))
			reposition.SetCardPositionTable(c, p.GetPlayerIndex(), cardIndex, u)
			u.Eng.SetSubTex(c.GetNode(), c.GetBack())
			u.TableCards = append(u.TableCards, c)
		}
		// cards that have been passed
		passed := p.GetPassedTo()
		for i, c := range passed {
			var passer int
			switch u.CurTable.GetDir() {
			case direction.Right:
				passer = (p.GetPlayerIndex() + 1) % u.NumPlayers
			case direction.Across:
				passer = (p.GetPlayerIndex() + 2) % u.NumPlayers
			case direction.Left:
				passer = (p.GetPlayerIndex() + 3) % u.NumPlayers
			}
			cardIndexVec := coords.MakeVec(float32(len(hand)+len(passed)), float32(len(hand)+i))
			initial := reposition.CardPositionTable(passer, cardIndexVec, u)
			c.SetInitial(initial)
			if !p.GetDoneTaking() {
				texture.PopulateCardImage(c, u)
				c.SetBackDisplay(u.Eng)
				pos := reposition.DetermineTablePassPosition(c, i, p.GetPlayerIndex(), u)
				c.Move(pos, u.TableCardDim, u.Eng)
				u.TableCards = append(u.TableCards, c)
			}
		}
	}
	if u.Debug {
		addDebugBar(u)
	}
	reposition.SetTableDropColors(u)
	u.M.Unlock()
	fmt.Println("UNLOCKED")
}

// Decides which view of the player's hand to load based on what steps of the round they have completed
func LoadPassOrTakeOrPlay(u *uistate.UIState) {
	p := u.CurTable.GetPlayers()[u.CurPlayerIndex]
	if p.GetDoneTaking() || u.CurTable.GetDir() == direction.None {
		LoadPlayView(u)
	} else if p.GetDonePassing() {
		LoadTakeView(u)
	} else {
		LoadPassView(u)
	}
}

// Score View: Shows current player standings at the end of every round, including the end of the game
func LoadScoreView(roundScores, winners []int, u *uistate.UIState) {
	u.M.Lock()
	fmt.Println("SCORE LOCKED")
	reposition.ResetAnims(u)
	resetImgs(u)
	resetScene(u)
	u.CurView = uistate.Score
	addHeader(u)
	addScoreViewHeaderText(u)
	addPlayerScores(roundScores, u)
	addScoreButton(len(winners) > 0, u)
	u.M.Unlock()
	fmt.Println("UNLOCKED")
}

// Pass View: Shows player's hand and allows them to pass cards
func LoadPassView(u *uistate.UIState) {
	u.M.Lock()
	fmt.Println("PASS LOCKED")
	reposition.ResetAnims(u)
	resetImgs(u)
	resetScene(u)
	u.CurView = uistate.Pass
	addHeader(u)
	addGrayPassBar(u)
	//addPassDrops(u)
	addHand(u)
	if u.Debug {
		addDebugBar(u)
	}
	reposition.AnimateInPass(u)
	u.M.Unlock()
	fmt.Println("UNLOCKED")
}

// Take View: Shows player's hand and allows them to take the cards that have been passed to them
func LoadTakeView(u *uistate.UIState) {
	u.M.Lock()
	fmt.Println("TAKE LOCKED")
	reposition.ResetAnims(u)
	resetImgs(u)
	resetScene(u)
	u.CurView = uistate.Take
	addHeader(u)
	addGrayTakeBar(u)
	addHand(u)
	moveTakeCards(u)
	if u.Debug {
		addDebugBar(u)
	}
	// animate in take bar
	reposition.AnimateInTake(u)
	u.M.Unlock()
	fmt.Println("UNLOCKED")
}

// Play View: Shows player's hand and allows them to play cards
func LoadPlayView(u *uistate.UIState) {
	u.M.Lock()
	fmt.Println("PLAY LOCKED")
	reposition.ResetAnims(u)
	resetImgs(u)
	resetScene(u)
	u.CurView = uistate.Play
	addPlaySlot(u)
	addHand(u)
	addPlayHeader(getTurnText(u), false, u)
	SetNumTricksHand(u)
	if u.Debug {
		addDebugBar(u)
	}
	// animate in play slot if relevant
	if u.CurTable.WhoseTurn() == u.CurPlayerIndex {
		if u.SequentialPhases {
			if u.CurTable.AllDoneTaking() {
				reposition.AnimateInPlay(u)
			}
		} else if u.CurTable.AllDonePassing() {
			reposition.AnimateInPlay(u)
		}
	} else if u.CurTable.GetTrickRecipient() == u.CurPlayerIndex {
		reposition.AnimateInPlay(u)
	}
	u.M.Unlock()
	fmt.Println("UNLOCKED")
}

func LoadSplitView(reloading bool, u *uistate.UIState) {
	u.M.Lock()
	fmt.Println("SPLIT LOCKED")
	reposition.ResetAnims(u)
	resetImgs(u)
	resetScene(u)
	u.CurView = uistate.Split
	addPlayHeader(getTurnText(u), !reloading, u)
	addSplitViewPlayerIcons(!reloading, u)
	SetNumTricksHand(u)
	addHand(u)
	if u.Debug {
		addDebugBar(u)
	}
	reposition.SetSplitDropColors(u)
	if !reloading {
		ch := make(chan bool)
		quit := make(chan bool)
		u.AnimChans = append(u.AnimChans, quit)
		u.SwitchingViews = true
		reposition.AnimateInSplit(ch, u)
		go func() {
			onDone := func() { u.SwitchingViews = false }
			reposition.SwitchOnChan(ch, quit, onDone, u)
		}()
	}
	u.M.Unlock()
	fmt.Println("UNLOCKED")
}

func ChangePlayMessage(message string, u *uistate.UIState) {
	// remove text and replace with message
	for _, img := range u.Other {
		if img.GetNode().Parent == u.Scene {
			u.Scene.RemoveChild(img.GetNode())
		}
	}
	if u.Buttons["toggleSplit"].GetNode().Parent == u.Scene {
		u.Scene.RemoveChild(u.Buttons["toggleSplit"].GetNode())
	}
	u.Other = make([]*staticimg.StaticImg, 0)
	u.Buttons = make(map[string]*staticimg.StaticImg)
	addPlayHeader(message, false, u)
	for _, img := range u.Other {
		reposition.BringNodeToFront(img.GetNode(), u)
	}
	for _, img := range u.Buttons {
		reposition.BringNodeToFront(img.GetNode(), u)
	}
	for _, img := range u.ModText {
		reposition.BringNodeToFront(img.GetNode(), u)
	}
}

func addArrangePlayer(player int, arrangeDim *coords.Vec, arrangeBlockLength float32, u *uistate.UIState) {
	sitImg := u.Texs["SitSpotUnpressed.png"]
	sitAlt := u.Texs["SitSpotPressed.png"]
	var sitPos *coords.Vec
	switch player {
	case 0:
		sitPos = coords.MakeVec((u.WindowSize.X-arrangeDim.X)/2, (u.WindowSize.Y+arrangeBlockLength)/2-arrangeDim.Y-2*u.Padding)
	case 1:
		sitPos = coords.MakeVec((u.WindowSize.X-arrangeDim.X)/2-arrangeDim.X-2*u.Padding, (u.WindowSize.Y+arrangeBlockLength)/2-2*arrangeDim.Y-4*u.Padding)
	case 2:
		sitPos = coords.MakeVec((u.WindowSize.X-arrangeDim.X)/2, (u.WindowSize.Y+arrangeBlockLength)/2-3*arrangeDim.Y-6*u.Padding)
	case 3:
		sitPos = coords.MakeVec((u.WindowSize.X-arrangeDim.X)/2+arrangeDim.X+2*u.Padding, (u.WindowSize.Y+arrangeBlockLength)/2-2*arrangeDim.Y-4*u.Padding)
	}
	if u.PlayerData[player] == 0 {
		u.Buttons[fmt.Sprintf("joinPlayer-%d", player)] = texture.MakeImgWithAlt(sitImg, sitAlt, sitPos, arrangeDim, true, u)
	} else {
		avatar := uistate.GetAvatar(player, u)
		u.BackgroundImgs = append(u.BackgroundImgs, texture.MakeImgWithoutAlt(avatar, sitPos, arrangeDim, u))
		name := uistate.GetName(player, u)
		var center *coords.Vec
		if player == 2 {
			center = coords.MakeVec(sitPos.X+arrangeDim.X/2, sitPos.Y-u.Padding-10)
		} else {
			center = coords.MakeVec(sitPos.X+arrangeDim.X/2, sitPos.Y+arrangeDim.Y)
		}
		scaler := float32(6)
		maxWidth := arrangeDim.X
		textImgs := texture.MakeStringImgCenterAlign(name, "", "", true, center, scaler, maxWidth, u)
		for _, text := range textImgs {
			u.BackgroundImgs = append(u.BackgroundImgs, text)
		}
	}
}

func addSplitViewPlayerIcons(beforeSplitAnimation bool, u *uistate.UIState) {
	topOfBanner := u.WindowSize.Y - 4*u.CardDim.Y - 5*u.Padding - u.BottomPadding - 40
	splitWindowSize := coords.MakeVec(u.WindowSize.X, topOfBanner+u.TopPadding)
	dropTargetImage := u.Texs["trickDrop.png"]
	dropTargetAlt := u.Texs["trickDropBlue.png"]
	dropTargetDimensions := u.CardDim
	playerIconDimensions := u.CardDim.Minus(4)
	// first drop target
	dropTargetX := (splitWindowSize.X - u.CardDim.X) / 2
	dropTargetY := splitWindowSize.Y/2 + u.Padding
	if beforeSplitAnimation {
		dropTargetY -= topOfBanner
	}
	dropTargetPos := coords.MakeVec(dropTargetX, dropTargetY)
	d := texture.MakeImgWithAlt(dropTargetImage, dropTargetAlt, dropTargetPos, dropTargetDimensions, true, u)
	u.DropTargets = append(u.DropTargets, d)
	// first player icon
	playerIconImage := uistate.GetAvatar(u.CurPlayerIndex, u)
	u.BackgroundImgs = append(u.BackgroundImgs,
		texture.MakeImgWithoutAlt(playerIconImage, dropTargetPos.Plus(2), playerIconDimensions, u))
	// card on top of first drop target
	dropCard := u.CurTable.GetTrick()[u.CurPlayerIndex]
	if dropCard != nil {
		texture.PopulateCardImage(dropCard, u)
		dropCard.SetInitial(dropTargetPos)
		dropCard.Move(dropTargetPos, dropTargetDimensions, u.Eng)
		d.SetCardHere(dropCard)
		u.TableCards = append(u.TableCards, dropCard)
	}
	// second drop target
	dropTargetY = (splitWindowSize.Y - u.CardDim.Y) / 2
	if beforeSplitAnimation {
		dropTargetY -= topOfBanner
	}
	dropTargetX = splitWindowSize.X/2 - 3*u.CardDim.X/2 - u.Padding
	dropTargetPos = coords.MakeVec(dropTargetX, dropTargetY)
	d = texture.MakeImgWithAlt(dropTargetImage, dropTargetAlt, dropTargetPos, dropTargetDimensions, true, u)
	u.DropTargets = append(u.DropTargets, d)
	// second player icon
	playerIconImage = uistate.GetAvatar((u.CurPlayerIndex+1)%u.NumPlayers, u)
	u.BackgroundImgs = append(u.BackgroundImgs,
		texture.MakeImgWithoutAlt(playerIconImage, dropTargetPos.Plus(2), playerIconDimensions, u))
	// card on top of second drop target
	dropCard = u.CurTable.GetTrick()[(u.CurPlayerIndex+1)%len(u.CurTable.GetPlayers())]
	if dropCard != nil {
		texture.PopulateCardImage(dropCard, u)
		dropCard.SetInitial(dropTargetPos)
		dropCard.Move(dropTargetPos, dropTargetDimensions, u.Eng)
		d.SetCardHere(dropCard)
		u.TableCards = append(u.TableCards, dropCard)
	}
	// third drop target
	dropTargetX = (splitWindowSize.X - u.CardDim.X) / 2
	dropTargetY = splitWindowSize.Y/2 - u.Padding - u.CardDim.Y
	if beforeSplitAnimation {
		dropTargetY -= topOfBanner
	}
	dropTargetPos = coords.MakeVec(dropTargetX, dropTargetY)
	d = texture.MakeImgWithAlt(dropTargetImage, dropTargetAlt, dropTargetPos, dropTargetDimensions, true, u)
	u.DropTargets = append(u.DropTargets, d)
	// third player icon
	playerIconImage = uistate.GetAvatar((u.CurPlayerIndex+2)%u.NumPlayers, u)
	u.BackgroundImgs = append(u.BackgroundImgs,
		texture.MakeImgWithoutAlt(playerIconImage, dropTargetPos.Plus(2), playerIconDimensions, u))
	// card on top of third drop target
	dropCard = u.CurTable.GetTrick()[(u.CurPlayerIndex+2)%len(u.CurTable.GetPlayers())]
	if dropCard != nil {
		texture.PopulateCardImage(dropCard, u)
		dropCard.SetInitial(dropTargetPos)
		dropCard.Move(dropTargetPos, dropTargetDimensions, u.Eng)
		d.SetCardHere(dropCard)
		u.TableCards = append(u.TableCards, dropCard)
	}
	// fourth drop target
	dropTargetY = (splitWindowSize.Y - u.CardDim.Y) / 2
	if beforeSplitAnimation {
		dropTargetY -= topOfBanner
	}
	dropTargetX = splitWindowSize.X/2 + u.CardDim.X/2 + u.Padding
	dropTargetPos = coords.MakeVec(dropTargetX, dropTargetY)
	d = texture.MakeImgWithAlt(dropTargetImage, dropTargetAlt, dropTargetPos, dropTargetDimensions, true, u)
	u.DropTargets = append(u.DropTargets, d)
	// fourth player icon
	playerIconImage = uistate.GetAvatar((u.CurPlayerIndex+3)%u.NumPlayers, u)
	u.BackgroundImgs = append(u.BackgroundImgs,
		texture.MakeImgWithoutAlt(playerIconImage, dropTargetPos.Plus(2), playerIconDimensions, u))
	// card on top of fourth drop target
	dropCard = u.CurTable.GetTrick()[(u.CurPlayerIndex+3)%len(u.CurTable.GetPlayers())]
	if dropCard != nil {
		texture.PopulateCardImage(dropCard, u)
		dropCard.SetInitial(dropTargetPos)
		dropCard.Move(dropTargetPos, dropTargetDimensions, u.Eng)
		d.SetCardHere(dropCard)
		u.TableCards = append(u.TableCards, dropCard)
	}
}

// returns a string which says whose turn it is
func getTurnText(u *uistate.UIState) string {
	var turnText string
	playerTurnNum := u.CurTable.WhoseTurn()
	if playerTurnNum == -1 || !u.CurTable.AllDonePassing() || (u.SequentialPhases && !u.CurTable.AllDoneTaking()) {
		if u.CurTable.TrickOver() {
			recipient := u.CurTable.GetTrickRecipient()
			if recipient == u.CurPlayerIndex {
				turnText = "Please take your trick"
			} else {
				turnText = fmt.Sprintf("Waiting for %s to take the trick", uistate.GetName(recipient, u))
			}
		} else {
			turnText = "Waiting for other players"
		}
	} else if playerTurnNum == u.CurPlayerIndex {
		turnText = "Your turn"
	} else {
		name := uistate.GetName(playerTurnNum, u)
		turnText = name + "'s turn"
	}
	return turnText
}

func addHeader(u *uistate.UIState) {
	// adding blue banner
	headerImage := u.Texs["RoundedRectangle-DBlue.png"]
	headerPos := coords.MakeVec(0, -10)
	headerDimensions := coords.MakeVec(u.WindowSize.X, u.TopPadding+float32(20))
	u.BackgroundImgs = append(u.BackgroundImgs,
		texture.MakeImgWithoutAlt(headerImage, headerPos, headerDimensions, u))
}

func addPlayHeader(message string, beforeSplitAnimation bool, u *uistate.UIState) {
	// adding blue banner
	headerImage := u.Texs["Rectangle-DBlue.png"]
	var headerDimensions *coords.Vec
	var headerPos *coords.Vec
	if u.CurView == uistate.Play || beforeSplitAnimation {
		headerDimensions = coords.MakeVec(u.WindowSize.X, float32(50))
		headerPos = coords.MakeVec(0, 0)
	} else {
		headerDimensions = coords.MakeVec(u.WindowSize.X, float32(40))
		topOfHand := u.WindowSize.Y - 4*(u.CardDim.Y+u.Padding) - u.BottomPadding
		headerPos = coords.MakeVec(0, topOfHand-headerDimensions.Y-u.Padding)
	}
	u.Other = append(u.Other,
		texture.MakeImgWithoutAlt(headerImage, headerPos, headerDimensions, u))
	// adding pull tab
	pullTabImage := u.Texs["Visibility.png"]
	pullTabAlt := u.Texs["VisibilityOff.png"]
	pullTabDim := u.CardDim.DividedBy(2)
	pullTabPos := headerPos.PlusVec(headerDimensions).MinusVec(pullTabDim).Minus(u.Padding)
	u.Buttons["toggleSplit"] = texture.MakeImgWithAlt(pullTabImage, pullTabAlt, pullTabPos, pullTabDim, !beforeSplitAnimation, u)
	// adding text
	color := "DBlue"
	scaler := float32(4)
	center := coords.MakeVec(u.WindowSize.X/2, headerPos.Y+headerDimensions.Y-30)
	maxWidth := u.WindowSize.X - pullTabDim.X*2 - u.Padding*4
	u.Other = append(u.Other,
		texture.MakeStringImgCenterAlign(message, color, color, true, center, scaler, maxWidth, u)...)
	takeTrickImage := u.Texs["TakeTrickHandUnpressed.png"]
	takeTrickAlt := u.Texs["TakeTrickHandPressed.png"]
	takeTrickDim := coords.MakeVec(u.CardDim.X, u.CardDim.Y/2)
	takeTrickPos := coords.MakeVec(u.Padding, headerPos.Y-takeTrickDim.Y-u.Padding)
	display := (u.CurTable.TrickOver() && u.CurTable.GetTrickRecipient() == u.CurPlayerIndex)
	u.Buttons["takeTrick"] = texture.MakeImgWithAlt(takeTrickImage, takeTrickAlt, takeTrickPos, takeTrickDim, true, u)
	if !display {
		var emptyTex sprite.SubTex
		u.Eng.SetSubTex(u.Buttons["takeTrick"].GetNode(), emptyTex)
	}
}

func addPlaySlot(u *uistate.UIState) {
	topOfHand := u.WindowSize.Y - 5*(u.CardDim.Y+u.Padding) - (2 * u.Padding / 5) - u.BottomPadding
	// adding blue rectangle
	blueRectImg := u.Texs["RoundedRectangle-LBlue.png"]
	blueRectDim := coords.MakeVec(u.WindowSize.X-4*u.BottomPadding, topOfHand+u.CardDim.Y)
	blueRectPos := coords.MakeVec(2*u.BottomPadding, -blueRectDim.Y)
	u.BackgroundImgs = append(u.BackgroundImgs,
		texture.MakeImgWithoutAlt(blueRectImg, blueRectPos, blueRectDim, u))
	// adding drop target
	if u.CurTable.GetTrickRecipient() == u.CurPlayerIndex {
		var emptyTex sprite.SubTex
		dropTargetImg := emptyTex
		blockStartX := (u.WindowSize.X - float32(u.NumPlayers)*(u.CardDim.X+u.Padding) + u.Padding) / 2
		for i, c := range u.CurTable.GetTrick() {
			dropTargetPos := coords.MakeVec(blockStartX+float32(i)*(u.CardDim.X+u.Padding), -u.CardDim.Y-3*u.Padding)
			d := texture.MakeImgWithoutAlt(dropTargetImg, dropTargetPos, u.CardDim, u)
			texture.PopulateCardImage(c, u)
			c.Move(dropTargetPos, u.CardDim, u.Eng)
			d.SetCardHere(c)
			u.TableCards = append(u.TableCards, c)
			u.DropTargets = append(u.DropTargets, d)
		}
	} else {
		dropTargetImg := u.Texs["trickDrop.png"]
		dropTargetPos := coords.MakeVec(u.WindowSize.X/2-u.CardDim.X/2, -u.CardDim.Y-3*u.Padding)
		u.DropTargets = append(u.DropTargets,
			texture.MakeImgWithoutAlt(dropTargetImg, dropTargetPos, u.CardDim, u))
	}
}

func addGrayPassBar(u *uistate.UIState) {
	// adding gray bar
	grayBarImg := u.Texs["RoundedRectangle-Gray.png"]
	blueBarImg := u.Texs["RoundedRectangle-LBlue.png"]
	topOfHand := u.WindowSize.Y - 5*(u.CardDim.Y+u.Padding) - (2 * u.Padding / 5) - u.BottomPadding
	grayBarDim := coords.MakeVec(u.WindowSize.X-4*u.BottomPadding, topOfHand+u.CardDim.Y)
	grayBarPos := coords.MakeVec(2*u.BottomPadding, -u.WindowSize.Y-20)
	u.Other = append(u.Other,
		texture.MakeImgWithAlt(grayBarImg, blueBarImg, grayBarPos, grayBarDim, true, u))
	// adding name
	var receivingPlayer int
	var arrowImg sprite.SubTex
	var arrowAlt sprite.SubTex
	switch u.CurTable.GetDir() {
	case direction.Right:
		receivingPlayer = (u.CurPlayerIndex + 3) % u.NumPlayers
		arrowImg = u.Texs["RightArrowGray.png"]
		arrowAlt = u.Texs["RightArrowBlue.png"]
	case direction.Left:
		receivingPlayer = (u.CurPlayerIndex + 1) % u.NumPlayers
		arrowImg = u.Texs["LeftArrowGray.png"]
		arrowAlt = u.Texs["LeftArrowBlue.png"]
	case direction.Across:
		receivingPlayer = (u.CurPlayerIndex + 2) % u.NumPlayers
		arrowImg = u.Texs["AcrossArrowGray.png"]
		arrowAlt = u.Texs["AcrossArrowBlue.png"]
	}
	arrowDim := u.CardDim
	name := uistate.GetName(receivingPlayer, u)
	color := "Gray"
	altColor := "LBlue"
	center := coords.MakeVec(u.WindowSize.X/2-arrowDim.X/2, 20-u.WindowSize.Y)
	scaler := float32(3)
	maxWidth := grayBarDim.X - 3*u.Padding - arrowDim.X
	nameImgs := texture.MakeStringImgCenterAlign(fmt.Sprintf("Pass to %s", name), color, altColor, true, center, scaler, maxWidth, u)
	u.Other = append(u.Other, nameImgs...)
	imgBeforeArrow := u.Other[len(u.Other)-1]
	ibaDim := imgBeforeArrow.GetDimensions()
	ibaPos := imgBeforeArrow.GetCurrent()
	arrowPos := coords.MakeVec(ibaPos.X+ibaDim.X+u.Padding, ibaPos.Y+ibaDim.Y/2-arrowDim.Y/2)
	u.Other = append(u.Other,
		texture.MakeImgWithAlt(arrowImg, arrowAlt, arrowPos, arrowDim, true, u))
	numDrops := 3
	dropXStart := (u.WindowSize.X - (float32(numDrops)*u.CardDim.X + (float32(numDrops)-1)*u.Padding)) / 2
	dropImg := u.Texs["trickDrop.png"]
	for i := 0; i < numDrops; i++ {
		dropX := dropXStart + float32(i)*(u.Padding+u.CardDim.X)
		dropPos := coords.MakeVec(dropX, topOfHand-u.Padding-u.WindowSize.Y-20)
		d := texture.MakeImgWithoutAlt(dropImg, dropPos, u.CardDim, u)
		u.DropTargets = append(u.DropTargets, d)
	}
	passImg := u.Texs["PassUnpressed.png"]
	passAlt := u.Texs["PassPressed.png"]
	passDim := coords.MakeVec(2*u.CardDim.X, 2*u.CardDim.Y/3)
	passPos := coords.MakeVec((u.WindowSize.X-passDim.X)/2, topOfHand-2*u.Padding-u.WindowSize.Y-20-passDim.Y)
	b := texture.MakeImgWithAlt(passImg, passAlt, passPos, passDim, true, u)
	var emptyTex sprite.SubTex
	u.Eng.SetSubTex(b.GetNode(), emptyTex)
	u.Buttons["pass"] = b
}

func addGrayTakeBar(u *uistate.UIState) {
	passedCards := u.CurTable.GetPlayers()[u.CurPlayerIndex].GetPassedTo()
	var display bool
	if u.SequentialPhases {
		display = !u.CurTable.AllDonePassing()
	} else {
		display = len(passedCards) == 0
	}
	// adding gray bar
	grayBarImg := u.Texs["RoundedRectangle-Gray.png"]
	grayBarAlt := u.Texs["RoundedRectangle-LBlue.png"]
	topOfHand := u.WindowSize.Y - 5*(u.CardDim.Y+u.Padding) - (2 * u.Padding / 5) - u.BottomPadding
	var grayBarHeight float32
	if display {
		grayBarHeight = 105
	} else {
		grayBarHeight = topOfHand + u.CardDim.Y
	}
	grayBarDim := coords.MakeVec(u.WindowSize.X-4*u.BottomPadding, grayBarHeight)
	grayBarPos := coords.MakeVec(2*u.BottomPadding, -u.WindowSize.Y-20)
	u.Other = append(u.Other,
		texture.MakeImgWithAlt(grayBarImg, grayBarAlt, grayBarPos, grayBarDim, display, u))
	// adding name
	var passingPlayer int
	switch u.CurTable.GetDir() {
	case direction.Right:
		passingPlayer = (u.CurPlayerIndex + 1) % u.NumPlayers
	case direction.Left:
		passingPlayer = (u.CurPlayerIndex + 3) % u.NumPlayers
	case direction.Across:
		passingPlayer = (u.CurPlayerIndex + 2) % u.NumPlayers
	}
	name := uistate.GetName(passingPlayer, u)
	color := "Gray"
	nameAltColor := "LBlue"
	awaitingAltColor := "None"
	center := coords.MakeVec(u.WindowSize.X/2, 20-u.WindowSize.Y)
	scaler := float32(3)
	maxWidth := grayBarDim.X - 2*u.Padding
	u.Other = append(u.Other,
		texture.MakeStringImgCenterAlign(name, color, nameAltColor, display, center, scaler, maxWidth, u)...)
	center = coords.MakeVec(center.X, center.Y+30)
	scaler = float32(5)
	u.Other = append(u.Other,
		texture.MakeStringImgCenterAlign("Awaiting pass", color, awaitingAltColor, display, center, scaler, maxWidth, u)...)
	// adding cards to take, if cards have been passed
	if !display {
		u.Cards = append(u.Cards, passedCards...)
	}
}

func moveTakeCards(u *uistate.UIState) {
	passedCards := make([]*card.Card, 0)
	if u.SequentialPhases {
		if u.CurTable.AllDonePassing() {
			passedCards = append(passedCards, u.CurTable.GetPlayers()[u.CurPlayerIndex].GetPassedTo()...)
		}
	} else {
		passedCards = append(passedCards, u.CurTable.GetPlayers()[u.CurPlayerIndex].GetPassedTo()...)
	}
	if len(passedCards) > 0 {
		topOfHand := u.WindowSize.Y - 5*(u.CardDim.Y+u.Padding) - (2 * u.Padding / 5) - u.BottomPadding
		numCards := float32(3)
		cardXStart := (u.WindowSize.X - (numCards*u.CardDim.X + (numCards-1)*u.Padding)) / 2
		for i, c := range passedCards {
			cardX := cardXStart + float32(i)*(u.Padding+u.CardDim.X)
			cardPos := coords.MakeVec(cardX, topOfHand-u.Padding-u.WindowSize.Y-20)
			c.Move(cardPos, u.CardDim, u.Eng)
			reposition.RealignSuit(c.GetSuit(), c.GetInitial().Y, u)
			// invisible drop target holding card
			var emptyTex sprite.SubTex
			d := texture.MakeImgWithoutAlt(emptyTex, cardPos, u.CardDim, u)
			d.SetCardHere(c)
			u.DropTargets = append(u.DropTargets, d)
		}
	}
}

func SetNumTricksTable(u *uistate.UIState) {
	// remove old num tricks
	for _, img := range u.Other {
		if img.GetNode().Parent == u.Scene {
			u.Scene.RemoveChild(img.GetNode())
		}
	}
	u.Other = make([]*staticimg.StaticImg, 0)
	// set new num tricks
	scaler := float32(7)
	for i, d := range u.DropTargets {
		dropTargetDimensions := d.GetDimensions()
		dropTargetPos := d.GetCurrent()
		numTricks := u.CurTable.GetPlayers()[i].GetNumTricks()
		if numTricks > 0 {
			trickText := " tricks"
			if numTricks == 1 {
				trickText = " trick"
			}
			tMax := dropTargetDimensions.Y
			var textImgs []*staticimg.StaticImg
			switch i {
			case 0:
				tCenter := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X/2, dropTargetPos.Y+dropTargetDimensions.Y)
				textImgs = texture.MakeStringImgCenterAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tCenter, scaler, tMax, u)
			case 1:
				tRight := coords.MakeVec(dropTargetPos.X-2, dropTargetPos.Y+dropTargetDimensions.Y/2-5)
				textImgs = texture.MakeStringImgRightAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tRight, scaler, tMax, u)
			case 2:
				tCenter := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X/2, dropTargetPos.Y-12)
				textImgs = texture.MakeStringImgCenterAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tCenter, scaler, tMax, u)
			case 3:
				tLeft := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X+2, dropTargetPos.Y+dropTargetDimensions.Y/2-5)
				textImgs = texture.MakeStringImgLeftAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tLeft, scaler, tMax, u)
			}
			for _, text := range textImgs {
				u.Other = append(u.Other, text)
			}
		}
	}
}

func SetNumTricksHand(u *uistate.UIState) {
	// remove old num tricks
	for _, img := range u.ModText {
		if img.GetNode().Parent == u.Scene {
			u.Scene.RemoveChild(img.GetNode())
		}
	}
	u.ModText = make([]*staticimg.StaticImg, 0)
	// set new num tricks
	b := u.Buttons["toggleSplit"]
	center := coords.MakeVec(u.Padding+b.GetDimensions().X/2, b.GetCurrent().Y-3*u.Padding)
	scaler := float32(4)
	max := b.GetDimensions().Y
	numTricks := u.CurTable.GetPlayers()[u.CurPlayerIndex].GetNumTricks()
	if numTricks > 0 {
		trickText := "tricks"
		if numTricks == 1 {
			trickText = "trick"
		}
		numImgs := texture.MakeStringImgCenterAlign(strconv.Itoa(numTricks), "DBlue", "DBlue", true, center, scaler, max, u)
		for _, text := range numImgs {
			u.ModText = append(u.ModText, text)
		}
		center = coords.MakeVec(center.X, center.Y+15)
		textImgs := texture.MakeStringImgCenterAlign(trickText, "DBlue", "DBlue", true, center, scaler, max, u)
		for _, text := range textImgs {
			u.ModText = append(u.ModText, text)
		}
	}
	if u.CurView == uistate.Split {
		topOfHand := u.WindowSize.Y - 5*(u.CardDim.Y+u.Padding) - (2 * u.Padding / 5) - u.BottomPadding
		for i, d := range u.DropTargets {
			dropTargetDimensions := d.GetDimensions()
			dropTargetPos := d.GetCurrent()
			numTricks := u.CurTable.GetPlayers()[(u.CurPlayerIndex+i)%u.NumPlayers].GetNumTricks()
			if numTricks > 0 {
				trickText := " tricks"
				if numTricks == 1 {
					trickText = " trick"
				}
				tMax := dropTargetDimensions.Y - u.Padding
				var textImgs []*staticimg.StaticImg
				switch i {
				case 0:
					if topOfHand < u.TopPadding+4*u.CardDim.Y {
						tLeft := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X+2, dropTargetPos.Y+dropTargetDimensions.Y-15)
						textImgs = texture.MakeStringImgLeftAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tLeft, scaler, tMax, u)
					} else {
						tCenter := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X/2, dropTargetPos.Y+dropTargetDimensions.Y+u.Padding)
						textImgs = texture.MakeStringImgCenterAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tCenter, scaler, tMax, u)
					}
				case 1:
					tRight := coords.MakeVec(dropTargetPos.X-2, dropTargetPos.Y+dropTargetDimensions.Y/2-5)
					textImgs = texture.MakeStringImgRightAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tRight, scaler, tMax, u)
				case 2:
					if topOfHand < u.TopPadding+4*u.CardDim.Y {
						tLeft := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X+2, dropTargetPos.Y)
						textImgs = texture.MakeStringImgLeftAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tLeft, scaler, tMax, u)
					} else {
						tCenter := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X/2, dropTargetPos.Y-u.Padding-15)
						textImgs = texture.MakeStringImgCenterAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tCenter, scaler, tMax, u)
					}
				case 3:
					tLeft := coords.MakeVec(dropTargetPos.X+dropTargetDimensions.X+2, dropTargetPos.Y+dropTargetDimensions.Y/2-5)
					textImgs = texture.MakeStringImgLeftAlign(strconv.Itoa(numTricks)+trickText, "", "", true, tLeft, scaler, tMax, u)
				}
				for _, text := range textImgs {
					u.ModText = append(u.ModText, text)
				}
			}
		}
	}
}

func addPassDrops(u *uistate.UIState) {
	// adding blue background banner for drop targets
	topOfHand := u.WindowSize.Y - 5*(u.CardDim.Y+u.Padding) - (2 * u.Padding / 5) - u.BottomPadding
	passBannerImage := u.Texs["Rectangle-LBlue.png"]
	passBannerPos := coords.MakeVec(6*u.BottomPadding, topOfHand-(2*u.Padding))
	passBannerDim := coords.MakeVec(u.WindowSize.X-8*u.BottomPadding, u.CardDim.Y+2*u.Padding)
	u.BackgroundImgs = append(u.BackgroundImgs,
		texture.MakeImgWithoutAlt(passBannerImage, passBannerPos, passBannerDim, u))
	// adding undisplayed pull tab
	pullTabSpotImage := u.Texs["Rectangle-LBlue.png"]
	pullTabImage := u.Texs["VerticalPullTab.png"]
	pullTabSpotPos := coords.MakeVec(2*u.BottomPadding, passBannerPos.Y)
	pullTabSpotDim := coords.MakeVec(4*u.BottomPadding, u.CardDim.Y+2*u.Padding)
	u.Buttons["dragPass"] = texture.MakeImgWithAlt(pullTabImage, pullTabSpotImage, pullTabSpotPos, pullTabSpotDim, false, u)
	// adding text
	textLeft := coords.MakeVec(pullTabSpotPos.X+pullTabSpotDim.X/2, passBannerPos.Y-20)
	scaler := float32(5)
	maxWidth := passBannerDim.X
	text := texture.MakeStringImgLeftAlign("Pass:", "", "None", true, textLeft, scaler, maxWidth, u)
	u.BackgroundImgs = append(u.BackgroundImgs, text...)
	// adding drop targets
	dropTargetImage := u.Texs["trickDrop.png"]
	dropTargetY := passBannerPos.Y + u.Padding
	numDropTargets := float32(3)
	dropTargetXStart := (u.WindowSize.X - (numDropTargets*u.CardDim.X + (numDropTargets-1)*u.Padding)) / 2
	for i := 0; i < int(numDropTargets); i++ {
		dropTargetX := dropTargetXStart + float32(i)*(u.Padding+u.CardDim.X)
		dropTargetPos := coords.MakeVec(dropTargetX, dropTargetY)
		u.DropTargets = append(u.DropTargets,
			texture.MakeImgWithoutAlt(dropTargetImage, dropTargetPos, u.CardDim, u))
	}
}

func addHand(u *uistate.UIState) {
	p := u.CurTable.GetPlayers()[u.CurPlayerIndex]
	u.Cards = append(u.Cards, p.GetHand()...)
	sort.Sort(card.CardSorter(u.Cards))
	clubCount := 0
	diamondCount := 0
	spadeCount := 0
	heartCount := 0
	for i := 0; i < len(u.Cards); i++ {
		switch u.Cards[i].GetSuit() {
		case card.Club:
			clubCount++
		case card.Diamond:
			diamondCount++
		case card.Spade:
			spadeCount++
		case card.Heart:
			heartCount++
		}
	}
	suitCounts := []int{clubCount, diamondCount, spadeCount, heartCount}
	// adding gray background banners for each suit
	suitBannerImage := u.Texs["gray.jpeg"]
	suitBannerX := float32(0)
	suitBannerWidth := u.WindowSize.X
	suitBannerHeight := u.CardDim.Y + (4 * u.Padding / 5)
	suitBannerDim := coords.MakeVec(suitBannerWidth, suitBannerHeight)
	for i := 0; i < u.NumSuits; i++ {
		suitBannerY := u.WindowSize.Y - float32(i+1)*(u.CardDim.Y+u.Padding) - (2 * u.Padding / 5) - u.BottomPadding
		suitBannerPos := coords.MakeVec(suitBannerX, suitBannerY)
		u.BackgroundImgs = append(u.BackgroundImgs,
			texture.MakeImgWithoutAlt(suitBannerImage, suitBannerPos, suitBannerDim, u))
	}
	// adding suit image to any empty suit in hand
	for i, c := range suitCounts {
		var texKey string
		switch i {
		case 0:
			texKey = "Club.png"
		case 1:
			texKey = "Diamond.png"
		case 2:
			texKey = "Spade.png"
		case 3:
			texKey = "Heart.png"
		}
		suitIconImage := u.Texs[texKey]
		suitIconAlt := u.Texs["gray.png"]
		suitIconX := u.WindowSize.X/2 - u.CardDim.X/3
		suitIconY := u.WindowSize.Y - float32(4-i)*(u.CardDim.Y+u.Padding) + u.CardDim.Y/6 - u.BottomPadding
		display := c == 0
		suitIconPos := coords.MakeVec(suitIconX, suitIconY)
		suitIconDim := u.CardDim.Times(2).DividedBy(3)
		u.EmptySuitImgs = append(u.EmptySuitImgs,
			texture.MakeImgWithAlt(suitIconImage, suitIconAlt, suitIconPos, suitIconDim, display, u))
	}
	// adding clubs
	for i := 0; i < clubCount; i++ {
		numInSuit := i
		texture.PopulateCardImage(u.Cards[i], u)
		reposition.SetCardPositionHand(u.Cards[i], numInSuit, suitCounts, u)
	}
	// adding diamonds
	for i := clubCount; i < clubCount+diamondCount; i++ {
		numInSuit := i - clubCount
		texture.PopulateCardImage(u.Cards[i], u)
		reposition.SetCardPositionHand(u.Cards[i], numInSuit, suitCounts, u)
	}
	// adding spades
	for i := clubCount + diamondCount; i < clubCount+diamondCount+spadeCount; i++ {
		numInSuit := i - clubCount - diamondCount
		texture.PopulateCardImage(u.Cards[i], u)
		reposition.SetCardPositionHand(u.Cards[i], numInSuit, suitCounts, u)
	}
	// adding hearts
	for i := clubCount + diamondCount + spadeCount; i < clubCount+diamondCount+spadeCount+heartCount; i++ {
		numInSuit := i - clubCount - diamondCount - spadeCount
		texture.PopulateCardImage(u.Cards[i], u)
		reposition.SetCardPositionHand(u.Cards[i], numInSuit, suitCounts, u)
	}
}

func addScoreViewHeaderText(u *uistate.UIState) {
	top := u.CardDim.Y
	scaler := float32(4)
	maxWidth := u.WindowSize.X / 5
	// adding score text
	scoreCenter := coords.MakeVec(u.WindowSize.X/4, top)
	u.BackgroundImgs = append(u.BackgroundImgs,
		texture.MakeStringImgCenterAlign("Score:", "", "", true, scoreCenter, scaler, maxWidth, u)...)
	// adding game text
	gameCenter := coords.MakeVec(u.WindowSize.X/2, top)
	u.BackgroundImgs = append(u.BackgroundImgs,
		texture.MakeStringImgCenterAlign("Round", "", "", true, gameCenter, scaler, maxWidth, u)...)
	// adding total text
	totalCenter := coords.MakeVec(3*u.WindowSize.X/4, top)
	u.BackgroundImgs = append(u.BackgroundImgs,
		texture.MakeStringImgCenterAlign("Total", "", "", true, totalCenter, scaler, maxWidth, u)...)
}

func addPlayerScores(roundScores []int, u *uistate.UIState) {
	totalScores := make([]int, 0)
	for _, p := range u.CurTable.GetPlayers() {
		totalScores = append(totalScores, p.GetScore())
	}
	maxRoundScore := maxInt(roundScores)
	maxTotalScore := maxInt(totalScores)
	top := u.CardDim.Y
	scaler := float32(5)
	maxWidth := u.WindowSize.X / 4
	rowHeight := u.WindowSize.Y / 6
	for i, p := range u.CurTable.GetPlayers() {
		var color string
		// blue divider
		dividerImage := u.Texs["blue.png"]
		dividerDim := coords.MakeVec(u.WindowSize.X, u.Padding/2)
		dividerPos := coords.MakeVec(0, top+(float32(i)+.5)*rowHeight)
		u.BackgroundImgs = append(u.BackgroundImgs,
			texture.MakeImgWithoutAlt(dividerImage, dividerPos, dividerDim, u))
		// player icon
		playerIconImage := uistate.GetAvatar(i, u)
		playerIconDim := coords.MakeVec(rowHeight/2, rowHeight/2)
		playerIconPos := coords.MakeVec(u.WindowSize.X/4-playerIconDim.X/2, top+(float32(i)+.5)*rowHeight+rowHeight/7)
		u.BackgroundImgs = append(u.BackgroundImgs,
			texture.MakeImgWithoutAlt(playerIconImage, playerIconPos, playerIconDim, u))
		// player name
		name := uistate.GetName(i, u)
		nameCenter := coords.MakeVec(playerIconPos.X+playerIconDim.X/2, playerIconPos.Y+playerIconDim.Y)
		u.BackgroundImgs = append(u.BackgroundImgs,
			texture.MakeStringImgCenterAlign(name, "", "", true, nameCenter, scaler, maxWidth, u)...)
		// player round score
		roundScore := roundScores[i]
		if roundScore == maxRoundScore {
			color = "Red"
		} else {
			color = ""
		}
		roundCenter := coords.MakeVec(u.WindowSize.X/2, playerIconPos.Y+playerIconDim.Y/2)
		u.BackgroundImgs = append(u.BackgroundImgs,
			texture.MakeStringImgCenterAlign(strconv.Itoa(roundScore), color, color, true, roundCenter, scaler, maxWidth, u)...)
		// player total score
		totalScore := p.GetScore()
		if totalScore == maxTotalScore {
			color = "Red"
		} else {
			color = ""
		}
		totalCenter := coords.MakeVec(3*u.WindowSize.X/4, playerIconPos.Y+playerIconDim.Y/2)
		u.BackgroundImgs = append(u.BackgroundImgs,
			texture.MakeStringImgCenterAlign(strconv.Itoa(totalScore), color, color, true, totalCenter, scaler, maxWidth, u)...)
	}
	// final blue divider
	dividerImage := u.Texs["blue.png"]
	dividerDim := coords.MakeVec(u.WindowSize.X, u.Padding/2)
	dividerPos := coords.MakeVec(0, top+(float32(len(u.CurTable.GetPlayers()))+.5)*rowHeight)
	u.BackgroundImgs = append(u.BackgroundImgs,
		texture.MakeImgWithoutAlt(dividerImage, dividerPos, dividerDim, u))
}

func addScoreButton(gameOver bool, u *uistate.UIState) {
	var buttonImg sprite.SubTex
	var buttonAlt sprite.SubTex
	if gameOver {
		buttonImg = u.Texs["NewGameUnpressed.png"]
		buttonAlt = u.Texs["NewGamePressed.png"]
	} else {
		buttonImg = u.Texs["NewRoundUnpressed.png"]
		buttonAlt = u.Texs["NewRoundPressed.png"]
	}
	buttonDim := coords.MakeVec(2*u.CardDim.X, 3*u.CardDim.Y/4)
	buttonPos := coords.MakeVec((u.WindowSize.X-buttonDim.X)/2, u.WindowSize.Y-buttonDim.Y-u.BottomPadding)
	u.Buttons["ready"] = texture.MakeImgWithAlt(buttonImg, buttonAlt, buttonPos, buttonDim, true, u)
}

func resetImgs(u *uistate.UIState) {
	u.Cards = make([]*card.Card, 0)
	u.TableCards = make([]*card.Card, 0)
	u.BackgroundImgs = make([]*staticimg.StaticImg, 0)
	u.EmptySuitImgs = make([]*staticimg.StaticImg, 0)
	u.DropTargets = make([]*staticimg.StaticImg, 0)
	u.Buttons = make(map[string]*staticimg.StaticImg)
	u.Other = make([]*staticimg.StaticImg, 0)
	u.ModText = make([]*staticimg.StaticImg, 0)
}

func resetScene(u *uistate.UIState) {
	u.Scene = &sprite.Node{}
	u.Eng.Register(u.Scene)
	u.Eng.SetTransform(u.Scene, f32.Affine{
		{1, 0, 0},
		{0, 1, 0},
	})
}

func addDebugBar(u *uistate.UIState) {
	buttonDim := u.CardDim
	debugTableImage := u.Texs["BakuSquare.png"]
	debugTablePos := u.WindowSize.MinusVec(buttonDim)
	u.Buttons["table"] = texture.MakeImgWithoutAlt(debugTableImage, debugTablePos, buttonDim, u)
	debugPassImage := u.Texs["Clubs-2.png"]
	debugPassPos := coords.MakeVec(u.WindowSize.X-2*buttonDim.X, u.WindowSize.Y-buttonDim.Y)
	u.Buttons["hand"] = texture.MakeImgWithoutAlt(debugPassImage, debugPassPos, buttonDim, u)
}

// Helper function that returns the largest int in a non-negative int array (not index of largest int)
func maxInt(array []int) int {
	max := 0
	for _, num := range array {
		if num > max {
			max = num
		}
	}
	return max
}
