// 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 (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"

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

	"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(true, u)
	case uistate.Split:
		LoadSplitView(true, u)
	}
}

// Arrange view: For seating players
func LoadArrangeView(u *uistate.UIState) {
	u.M.Lock()
	defer u.M.Unlock()
	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.Buttons["start"].SetHidden(true)
		}
	}
}

// Waiting view: Displays the word "Waiting". To be displayed when players are waiting for a new round to be dealt
func LoadWaitingView(u *uistate.UIState) {
	u.M.Lock()
	defer u.M.Unlock()
	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)
	}
	if u.Debug {
		addDebugBar(u)
	}
}

// Discovery view: Displays a menu of possible games to join
func LoadDiscoveryView(u *uistate.UIState) {
	u.M.Lock()
	defer u.M.Unlock()
	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
	file, err := os.OpenFile(util.AddrFile, os.O_RDONLY|os.O_CREATE, 0666)
	if err != nil {
		fmt.Println("err:", err)
	}
	scanner := bufio.NewScanner(file)
	var oldAddr string
	scanner.Scan()
	addr := scanner.Text()
	// Search through all the database's syncgroups to see if addr represents a current syncgroup
	app := u.Service.App(util.AppName)
	db := app.Database(util.DbName, nil)
	allAddrs, _ := db.GetSyncgroupNames(u.Ctx)
	fmt.Println(allAddrs)
	for _, a := range allAddrs {
		if a == addr {
			oldAddr = a
		}
	}
	file.Close()
	if oldAddr != "" {
		rejoinGameImg := u.Texs["RejoinUnpressed.png"]
		rejoinGameAlt := u.Texs["RejoinPressed.png"]
		rejoinGameDim := coords.MakeVec(4*u.CardDim.X, u.CardDim.Y)
		rejoinGamePos := coords.MakeVec((u.WindowSize.X-rejoinGameDim.X)/2, u.TopPadding+rejoinGameDim.Y+u.Padding)
		u.Buttons["rejoinGame"] = texture.MakeImgWithAlt(rejoinGameImg, rejoinGameAlt, rejoinGamePos, rejoinGameDim, true, u)
		scanner.Scan()
		creator := scanner.Text()
		bInfo := oldAddr + "|" + creator
		u.Buttons["rejoinGame"].SetInfo(bInfo)
		buttonNum = 2
	}
	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)
				creator := creatorName == util.UserName
				bInfo := d.LogAddr + "|" + strconv.FormatBool(creator)
				u.Buttons[fmt.Sprintf("joinGame-%d", buttonNum)].SetInfo(bInfo)
				buttonNum++
			}
		}
	}
}

// Table View: Displays the table. Intended for public devices
func LoadTableView(u *uistate.UIState) {
	u.M.Lock()
	defer u.M.Unlock()
	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)
		u.Buttons["takeTrick"].SetHidden(true)
	}
	// 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)
}

// 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) {
	if u.CurPlayerIndex >= 0 {
		p := u.CurTable.GetPlayers()[u.CurPlayerIndex]
		if u.CurTable.RoundOver() {
			LoadScoreView(u)
		} else if p.GetDoneTaking() || u.CurTable.GetDir() == direction.None {
			if u.CurView == uistate.Play {
				LoadPlayView(true, u)
			} else {
				LoadPlayView(false, 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(u *uistate.UIState) {
	u.M.Lock()
	defer u.M.Unlock()
	reposition.ResetAnims(u)
	resetImgs(u)
	resetScene(u)
	u.CurView = uistate.Score
	addHeader(u)
	addScoreViewHeaderText(u)
	addPlayerScores(u.RoundScores, u)
	addScoreButton(len(u.Winners) > 0, u)
}

// Pass View: Shows player's hand and allows them to pass cards
func LoadPassView(u *uistate.UIState) {
	u.M.Lock()
	defer u.M.Unlock()
	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)
}

// 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()
	defer u.M.Unlock()
	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)
}

// Play View: Shows player's hand and allows them to play cards
func LoadPlayView(reloading bool, u *uistate.UIState) {
	u.M.Lock()
	defer u.M.Unlock()
	reposition.ResetAnims(u)
	resetImgs(u)
	resetScene(u)
	u.CurView = uistate.Play
	display := u.CurTable.GetTrick()[u.CurPlayerIndex] == nil && !u.CurTable.TrickNew() && reloading
	addPlaySlot(display, u)
	addHand(u)
	addPlayHeader(getTurnText(u), false, u)
	SetNumTricksHand(u)
	if u.Debug {
		addDebugBar(u)
	}
	// animate in play slot if relevant
	if u.CurTable.TrickNew() || u.CurTable.GetTrickRecipient() == u.CurPlayerIndex || (!reloading && u.CurTable.GetTrick()[u.CurPlayerIndex] == nil) {
		reposition.AnimateInPlay(u)
	}
}

func LoadSplitView(reloading bool, u *uistate.UIState) {
	u.M.Lock()
	defer u.M.Unlock()
	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
				if u.CardToPlay != nil {
					reposition.AlternateImgs(u.BackgroundImgs[0], u)
				}
			}
			reposition.SwitchOnChan(ch, quit, onDone, u)
		}()
	} else {
		if u.CardToPlay != nil {
			reposition.AlternateImgs(u.BackgroundImgs[0], u)
		}
	}
}

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)
	// 'unplayed' border
	borderImage := u.Texs["UnplayedBorder1.png"]
	borderAlt := u.Texs["UnplayedBorder2.png"]
	borderDim := dropTargetDimensions.Plus(2)
	borderPos := dropTargetPos.Minus(1)
	b := texture.MakeImgWithAlt(borderImage, borderAlt, borderPos, borderDim, true, u)
	u.BackgroundImgs = append(u.BackgroundImgs, b)
	if u.CardToPlay == nil {
		var emptyTex sprite.SubTex
		u.Eng.SetSubTex(b.GetNode(), emptyTex)
		b.SetHidden(true)
	}
	// 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 = ""
			} else {
				turnText = fmt.Sprintf("%s's 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(3*u.CardDim.X/2, 3*u.CardDim.Y/4)
	takeTrickPos := headerDimensions.MinusVec(takeTrickDim).DividedBy(2)
	if u.CurView == uistate.Play || beforeSplitAnimation {
		takeTrickPos = coords.MakeVec(takeTrickPos.X, takeTrickPos.Y+u.TopPadding/2+headerPos.Y)
	} else {
		takeTrickPos = coords.MakeVec(takeTrickPos.X, takeTrickPos.Y+u.TopPadding/2+headerPos.Y-5)
	}
	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)
		u.Buttons["takeTrick"].SetHidden(true)
	}
}

func addPlaySlot(display bool, 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)
	if display {
		blueRectPos = coords.MakeVec(blueRectPos.X, blueRectPos.Y+u.WindowSize.Y/3+u.TopPadding)
	}
	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)
		if display {
			dropTargetPos = coords.MakeVec(dropTargetPos.X, dropTargetPos.Y+u.WindowSize.Y/3+u.TopPadding)
		}
		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"]
	passDim := coords.MakeVec(3*u.CardDim.X/2, 2*u.CardDim.Y/3)
	for i := 0; i < numDrops; i++ {
		dropX := dropXStart + float32(i)*(u.Padding+u.CardDim.X)
		dropPos := coords.MakeVec(dropX, topOfHand-2*u.Padding-u.WindowSize.Y-20-passDim.Y)
		d := texture.MakeImgWithoutAlt(dropImg, dropPos, u.CardDim, u)
		u.DropTargets = append(u.DropTargets, d)
	}
	passImg := u.Texs["PassUnpressed.png"]
	passAlt := u.Texs["PassPressed.png"]
	passPos := coords.MakeVec((u.WindowSize.X-passDim.X)/2, topOfHand-2*u.Padding-u.WindowSize.Y-20-passDim.Y+u.CardDim.Y+u.Padding)
	b := texture.MakeImgWithAlt(passImg, passAlt, passPos, passDim, true, u)
	var emptyTex sprite.SubTex
	u.Eng.SetSubTex(b.GetNode(), emptyTex)
	b.SetHidden(true)
	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, 50-u.WindowSize.Y)
	if !display {
		center = coords.MakeVec(center.X, center.Y-30)
		name = "Take from " + name
	}
	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 from", 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) {
	topOfHand := u.WindowSize.Y - 5*(u.CardDim.Y+u.Padding) - (2 * u.Padding / 5) - u.BottomPadding
	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 {
		takeImg := u.Texs["TakeUnpressed.png"]
		takeAlt := u.Texs["TakePressed.png"]
		takeDim := coords.MakeVec(3*u.CardDim.X/2, 2*u.CardDim.Y/3)
		takePos := coords.MakeVec((u.WindowSize.X-takeDim.X)/2, topOfHand-2*u.Padding-u.WindowSize.Y-20-takeDim.Y+u.CardDim.Y+u.Padding)
		b := texture.MakeImgWithAlt(takeImg, takeAlt, takePos, takeDim, true, u)
		u.Buttons["take"] = b
		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-2*u.Padding-u.WindowSize.Y-20-takeDim.Y)
			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)
	}
	if u.CardToPlay != nil && u.DropTargets[0].GetCardHere() == nil {
		u.CardToPlay.Move(u.DropTargets[0].GetCurrent(), u.DropTargets[0].GetDimensions(), u.Eng)
		u.DropTargets[0].SetCardHere(u.CardToPlay)
		reposition.RealignSuit(u.CardToPlay.GetSuit(), u.CardToPlay.GetInitial().Y, 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)
	debugRestartImage := u.Texs["Restart.png"]
	debugRestartPos := coords.MakeVec(u.WindowSize.X-3*buttonDim.X, u.WindowSize.Y-buttonDim.Y)
	u.Buttons["restart"] = texture.MakeImgWithoutAlt(debugRestartImage, debugRestartPos, 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
}
