package main

import (
	"image"
	"log"
	"math"
	"time"

	_ "image/png"

	"golang.org/x/mobile/app"
	"golang.org/x/mobile/asset"
	"golang.org/x/mobile/event/paint"
	"golang.org/x/mobile/event/size"
	"golang.org/x/mobile/event/touch"
	"golang.org/x/mobile/exp/f32"
	"golang.org/x/mobile/exp/sprite"
	"golang.org/x/mobile/exp/sprite/clock"
	"golang.org/x/mobile/exp/sprite/glsprite"
	"golang.org/x/mobile/gl"
)

var (
	startTime          = time.Now()
	eng                = glsprite.Engine()
	scene              *sprite.Node
	cards              []*sprite.Node
	cardsXY            [][]float32
	initialCardsXY     [][]float32
	curCardIndex       = -1
	lastMouseXY        = []float32{-1, -1}
	cardWidth          = float32(100)
	cardHeight         = float32(100)
	windowSize         = []float32{-1, -1}
	swipeMoveThreshold = 70
	swipeTimeThreshold = .5
	swipeStart         time.Time
	animSpeedScaler    = .1
	animRotationScaler = .15
)

func main() {
	app.Main(func(a app.App) {
		var sz size.Event
		for e := range a.Events() {
			switch e := app.Filter(e).(type) {
			case size.Event:
				sz = e
				windowSize[0] = float32(sz.WidthPx)
				windowSize[1] = float32(sz.HeightPx)
			case touch.Event:
				onTouch(e)
			case paint.Event:
				onPaint(sz)
				a.EndPaint(e)
			}
		}
	})
}

func onTouch(t touch.Event) {
	switch t.Type.String() {
	case "begin":
		for i := len(cards) - 1; i >= 0; i-- {
			if t.X >= getCardX(i) &&
				t.Y >= getCardY(i) &&
				t.X <= cardWidth+getCardX(i) &&
				t.Y <= cardHeight+getCardY(i) {
				swipeStart = time.Now()
				curCardIndex = i
				node := getCardNode(i)
				node.Arranger = nil
				lastMouseXY[0] = t.X
				lastMouseXY[1] = t.Y
				return
			}
		}
	case "move":
		if curCardIndex > -1 {
			eng.SetTransform(cards[curCardIndex], f32.Affine{
				{cardWidth, 0, getCardX(curCardIndex) + t.X - lastMouseXY[0]},
				{0, cardHeight, getCardY(curCardIndex) + t.Y - lastMouseXY[1]},
			})
			setCardX(curCardIndex, getCardX(curCardIndex)+t.X-lastMouseXY[0])
			setCardY(curCardIndex, getCardY(curCardIndex)+t.Y-lastMouseXY[1])
			lastMouseXY[0] = t.X
			lastMouseXY[1] = t.Y
		}
	case "end":
		if curCardIndex > -1 {
			xDiff := getCardX(curCardIndex) - getInitialX(curCardIndex)
			yDiff := getCardY(curCardIndex) - getInitialY(curCardIndex)
			timeDiff := time.Since(swipeStart).Seconds()
			if (math.Abs(float64(xDiff))+math.Abs(float64(yDiff))) >= float64(swipeMoveThreshold) && timeDiff <= float64(swipeTimeThreshold) {
				animate(xDiff, yDiff, t)
			} else {
				eng.SetTransform(cards[curCardIndex], f32.Affine{
					{cardWidth, 0, getInitialX(curCardIndex)},
					{0, cardHeight, getInitialY(curCardIndex)},
				})
				setCardX(curCardIndex, getInitialX(curCardIndex))
				setCardY(curCardIndex, getInitialY(curCardIndex))
			}
		}
		curCardIndex = -1
	}
}

func animate(xDiff float32, yDiff float32, touch touch.Event) {
	index := curCardIndex
	curCardIndex = -1
	node := getCardNode(index)
	startTime := -1
	node.Arranger = arrangerFunc(func(eng sprite.Engine, node *sprite.Node, t clock.Time) {
		if startTime == -1 {
			startTime = int(t)
		}
		moveSpeed := float32(int(t)-startTime) * float32(animSpeedScaler)
		x := getCardX(index)
		y := getCardY(index)
		if math.Abs(float64(xDiff)) > math.Abs(float64(yDiff)) {
			if xDiff > 0 {
				x = x + moveSpeed
			} else {
				x = x - moveSpeed
			}
		} else {
			if yDiff > 0 {
				y = y + moveSpeed
			} else {
				y = y - moveSpeed
			}
		}
		setCardX(index, x)
		setCardY(index, y)
		position := f32.Affine{
			{cardWidth, 0, x + cardWidth/2},
			{0, cardHeight, y + cardHeight/2},
		}
		position.Rotate(&position, float32(t)*float32(animRotationScaler))
		position.Translate(&position, -.5, -.5)
		eng.SetTransform(node, position)
	})
}

func onPaint(sz size.Event) {
	if scene == nil {
		loadScene()
	}
	gl.ClearColor(1, 1, 1, 1)
	gl.Clear(gl.COLOR_BUFFER_BIT)
	now := clock.Time(time.Since(startTime) * 60 / time.Second)
	eng.Render(scene, now, sz)
}

func newNode() *sprite.Node {
	n := &sprite.Node{}
	eng.Register(n)
	scene.AppendChild(n)
	return n
}

func addCard(x float32, y float32, spriteTex sprite.SubTex) {
	n := newNode()
	eng.SetSubTex(n, spriteTex)
	eng.SetTransform(n, f32.Affine{
		{cardWidth, 0, x},
		{0, cardHeight, y},
	})
	cards = append(cards, n)
	cardsXY = append(cardsXY, []float32{x, y})
	initialCardsXY = append(initialCardsXY, []float32{x, y})
}

func getCardX(cardIndex int) float32 {
	return cardsXY[cardIndex][0]
}

func setCardX(cardIndex int, newX float32) {
	cardsXY[cardIndex][0] = newX
}

func getCardY(cardIndex int) float32 {
	return cardsXY[cardIndex][1]
}

func setCardY(cardIndex int, newY float32) {
	cardsXY[cardIndex][1] = newY
}

func getCardNode(cardIndex int) *sprite.Node {
	return cards[cardIndex]
}

func getInitialX(cardIndex int) float32 {
	return initialCardsXY[cardIndex][0]
}

func getInitialY(cardIndex int) float32 {
	return initialCardsXY[cardIndex][1]
}

func loadScene() {
	cards = make([]*sprite.Node, 0)
	cardsXY = make([][]float32, 0)
	initialCardsXY = make([][]float32, 0)
	texs := loadTextures()
	scene = &sprite.Node{}
	eng.Register(scene)
	eng.SetTransform(scene, f32.Affine{
		{1, 0, 0},
		{0, 1, 0},
	})
	for _, v := range texs {
		x := windowSize[0]/2 - cardWidth/2
		y := windowSize[1]/2 - cardHeight/2
		addCard(x, y, v)
	}
}

func loadTextures() map[string]sprite.SubTex {
	allTexs := make(map[string]sprite.SubTex)
	files := []string{"Clubs-2.png", "Clubs-3.png", "Clubs-4.png", "Clubs-5.png", "Clubs-6.png", "Clubs-7.png", "Clubs-8.png",
		"Clubs-9.png", "Clubs-10.png", "Clubs-Jack.png", "Clubs-Queen.png", "Clubs-King.png", "Clubs-Ace.png",
		"Diamonds-2.png", "Diamonds-3.png", "Diamonds-4.png", "Diamonds-5.png", "Diamonds-6.png", "Diamonds-7.png", "Diamonds-8.png",
		"Diamonds-9.png", "Diamonds-10.png", "Diamonds-Jack.png", "Diamonds-Queen.png", "Diamonds-King.png", "Diamonds-Ace.png",
		"Spades-2.png", "Spades-3.png", "Spades-4.png", "Spades-5.png", "Spades-6.png", "Spades-7.png", "Spades-8.png",
		"Spades-9.png", "Spades-10.png", "Spades-Jack.png", "Spades-Queen.png", "Spades-King.png", "Spades-Ace.png",
		"Hearts-2.png", "Hearts-3.png", "Hearts-4.png", "Hearts-5.png", "Hearts-6.png", "Hearts-7.png", "Hearts-8.png",
		"Hearts-9.png", "Hearts-10.png", "Hearts-Jack.png", "Hearts-Queen.png", "Hearts-King.png", "Hearts-Ace.png"}
	for _, f := range files {
		a, err := asset.Open(f)
		if err != nil {
			log.Fatal(err)
		}
		defer a.Close()

		img, _, err := image.Decode(a)
		if err != nil {
			log.Fatal(err)
		}
		t, err := eng.LoadTexture(img)
		if err != nil {
			log.Fatal(err)
		}
		allTexs[f] = sprite.SubTex{t, image.Rect(0, 0, 100, 100)}
	}
	return allTexs
}

type arrangerFunc func(e sprite.Engine, n *sprite.Node, t clock.Time)

func (a arrangerFunc) Arrange(e sprite.Engine, n *sprite.Node, t clock.Time) { a(e, n, t) }
