package main

import (
	"strconv"
	"time"

	"tinygo.org/x/tinydraw"
	"tinygo.org/x/tinyfont"
	"tinygo.org/x/tinyfont/freemono"
	"tinygo.org/x/tinyfont/freesans"
	"tinygo.org/x/tinyfont/proggy"

	qrcode "github.com/skip2/go-qrcode"
)

var (
	advOptY      = int16(24)
	advOptHeight = int16(10)
)

func adventure() {
	quit := false
	s := 0
	score := 0
	money := 0
	costume := 0
	pancake := false
	talk := false
	opinion := 0
	selected := int16(0)

	if displayWidth <= 240 {
		advOptY = 54
		advOptHeight = 20
	}

	for {
		scene(s)
		selected = 0
		score += s
		if s == 5 {
			costume = 1
		} else if s == 3 {
			talk = true
		} else if s == 6 {
			pancake = true
		} else if s == 8 {
			money += 689
			costume = 2
		} else if s == 17 {
			money += 5
		} else if s == 20 {
			opinion = 57
		} else if s == 21 {
			opinion = 37
		} else if s == 22 {
			opinion = 21
		} else if s == 25 {
			myNameIs(YourName)
		} else if s == 27 {
			if costume == 0 {
				s = 30
			} else if costume == 1 {
				s = 28
			} else {
				s = 29
			}
			continue
		} else if s == 32 {
			s = 34
			if talk {
				s = 33
			}
			continue
		} else if s == 41 {
			showGameStats(score, money, costume, opinion, pancake, talk)
		} else if s == 42 {
			showGameQR()
		} else if s == 44 {
			return
		}

		tinydraw.FilledCircle(&display, 10, displayHeight-advOptY-4+advOptHeight*selected, 3, colorWhite)
		for {
			getInput()

			if selected > 0 && ((!buttonsOldState[buttonLeft] && buttonsState[buttonLeft]) ||
				(!buttonsOldState[buttonUp] && buttonsState[buttonUp])) {
				tinydraw.FilledCircle(&display, 10, displayHeight-4-advOptY+advOptHeight*selected, 3, colorBlack)
				selected--
				tinydraw.FilledCircle(&display, 10, displayHeight-4-advOptY+advOptHeight*selected, 3, colorWhite)
			} else if selected < 2 && ((!buttonsOldState[buttonRight] && buttonsState[buttonRight]) ||
				(!buttonsOldState[buttonDown] && buttonsState[buttonDown])) {
				tinydraw.FilledCircle(&display, 10, displayHeight-4-advOptY+advOptHeight*selected, 3, colorBlack)
				selected++
				tinydraw.FilledCircle(&display, 10, displayHeight-4-advOptY+advOptHeight*selected, 3, colorWhite)
			} else if !buttonsOldState[buttonA] && buttonsState[buttonA] {
				if selected == 0 {
					s = sceneData[s].sceneA
					if s == 1 {
						money += 385
					} else if s == 2 {
						money += 335
					}
					break
				} else if selected == 1 {
					s = sceneData[s].sceneB
					if s == 1 {
						money += 600
					} else if s == 2 {
						money += 550
					}
					break
				} else {
					s = sceneData[s].sceneC
					if s == 1 {
						money += 1050
					} else if s == 2 {
						money += 970
					}
					break
				}
			} else if goBack() {
				quit = true
				break
			}

			time.Sleep(200 * time.Millisecond)
		}
		if quit {
			break
		}
	}
}

func scene(s int) {
	display.FillScreen(colorWhite)

	ss := splitBefore(sceneData[s].description, 0)
	for i := int16(0); i < int16(len(ss)); i++ {
		if displayWidth <= 240 {
			tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 6, 16+i*10, ss[i], colorBlack)
		} else {
			tinyfont.WriteLine(&display, &freemono.Regular9pt7b, 6, 16+i*16, ss[i], colorBlack)
		}
	}

	display.FillRectangle(0, displayHeight-advOptY-9, displayWidth, advOptY+9, colorBlack)

	// OPTION A
	ss = splitBefore(sceneData[s].optionA, 3)
	tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 20, displayHeight-advOptY, ss[0], colorWhite)
	if len(ss) > 1 {
		tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 20, displayHeight-advOptY+10, ss[1], colorWhite)
	}

	// OPTION B
	ss = splitBefore(sceneData[s].optionB, 3)
	tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 20, displayHeight-advOptY+advOptHeight, ss[0], colorWhite)
	if len(ss) > 1 {
		tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 20, displayHeight-advOptY+advOptHeight+10, ss[1], colorWhite)
	}

	// OPTION C
	ss = splitBefore(sceneData[s].optionC, 3)
	tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 20, displayHeight-advOptY+advOptHeight*2, ss[0], colorWhite)
	if len(ss) > 1 {
		tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 20, displayHeight-advOptY+advOptHeight*2+10, ss[1], colorWhite)
	}

	tinydraw.Circle(&display, 10, displayHeight-advOptY-4, 4, colorWhite)
	tinydraw.Circle(&display, 10, displayHeight-advOptY+advOptHeight-4, 4, colorWhite)
	tinydraw.Circle(&display, 10, displayHeight-advOptY+(advOptHeight)*2-4, 4, colorWhite)

	display.Display()
}

func splitBefore(str string, offset int) []string {
	l := len(str)
	a := 0
	s := make([]string, 0)
	lineW := 28 - offset
	if displayWidth <= 240 {
		lineW = 40 - offset
	}
	for {
		if l <= lineW {
			s = append(s, str[a:a+l])
			break
		} else {
			for i := lineW; i > 0; i-- {
				if string(str[a+i]) == " " {
					s = append(s, str[a:a+i])
					a = a + i + 1
					l = l - i - 1
					break
				}
			}
		}
	}
	return s
}

func showGameStats(score, money, costume, opinion int, pancake, talk bool) {

	c := "SCORE: " + strconv.Itoa(score)
	w32, _ := tinyfont.LineWidth(&freesans.Bold9pt7b, c)
	tinyfont.WriteLine(&display, &freesans.Bold9pt7b, (displayWidth-int16(w32))/2, 26, c, colorBlack)
	tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 10, 50, "Money spent: "+strconv.Itoa(money)+" EUR", colorBlack)

	c = "YOURSELF"
	if costume == 1 {
		c = "UNICORN PIJAMA"
	} else if costume == 2 {
		c = "DELUXE TUXEDO"
	}
	tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 10, 60, "You were dressed as: "+c, colorBlack)

	c = "NO pancakes"
	if pancake {
		c = "37 pancakes"
	}
	tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 10, 70, "Your breakfast: "+c, colorBlack)

	if talk {
		tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 10, 80, "You DID give a talk (and it was awesome)", colorBlack)
	} else {
		tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 10, 80, "You did NOT give a talk (sad noises)", colorBlack)
	}
	tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 10, 90, "Your opinion is "+strconv.Itoa(opinion)+"% popular", colorBlack)

	display.Display()
}

func showGameQR() {

	// https://tinyurl.com/gceuADV
	qr, err := qrcode.New("https://tinyurl.com/gceuADV", qrcode.Medium)
	if err != nil {
		println(err, 123)
	}

	qrbytes := qr.Bitmap()
	size := int16(len(qrbytes))

	factor := int16(displayHeight / len(qrbytes))

	bx := (displayWidth - size*factor)
	by := (displayHeight - size*factor) / 2
	display.FillScreen(colorWhite)
	for y := int16(0); y < size; y++ {
		for x := int16(0); x < size; x++ {
			if qrbytes[y][x] {
				display.FillRectangle(bx+x*factor, by+y*factor, factor, factor, colorBlack)
			} else {
				display.FillRectangle(bx+x*factor, by+y*factor, factor, factor, colorWhite)
			}
		}
	}

	tinyfont.WriteLine(&display, &freesans.Bold9pt7b, 10, 30, "SCAN &", colorBlack)
	tinyfont.WriteLine(&display, &freesans.Bold9pt7b, 10, 50, "SHARE", colorBlack)
	tinyfont.WriteLine(&display, &freesans.Bold9pt7b, 10, 70, "YOUR", colorBlack)
	tinyfont.WriteLine(&display, &freesans.Bold9pt7b, 10, 90, "SCORE", colorBlack)
	tinyfont.WriteLine(&display, &freesans.Bold9pt7b, 10, 110, "ONLINE", colorBlack)

	display.Display()
}
