package main

import (
	"image/color"
	"machine"
	"time"

	"tinygo.org/x/drivers/lis3dh"
	"tinygo.org/x/drivers/ws2812"
	"tinygo.org/x/tinyfont"
	"tinygo.org/x/tinyfont/freemono"
	"tinygo.org/x/tinyfont/freesans"
	"tinygo.org/x/tinyfont/proggy"
)

var (
	colorRed         = color.RGBA{250, 0, 0, 255}
	colorMellonGreen = color.RGBA{0, 200, 0, 255}
	colorGreen       = color.RGBA{0, 255, 0, 255}
	colorCyan        = color.RGBA{0, 255, 255, 255}
	colorBlue        = color.RGBA{0, 0, 255, 255}
	colorPurple      = color.RGBA{153, 51, 255, 255}
	colorWhite       = color.RGBA{255, 255, 255, 255}
	colorBlack       = color.RGBA{0, 0, 0, 255}
	colorBlackLED    = color.RGBA{0, 0, 0, 0}
	colorText        = color.RGBA{160, 160, 160, 255}
	colorOrange      = color.RGBA{255, 153, 51, 255}
	colorYellow      = color.RGBA{255, 255, 0, 255}
)

const (
	buttonUp = iota
	buttonRight
	buttonDown
	buttonLeft
	buttonA
	buttonB
	buttonC
	buttonStart
	buttonSelect
)

const (
	modeBadge = iota
	modeInfo
	modeSchedule
	modeAdventure
	modeLEDs
	modeAccelerometer
	modeMusic
	modeGameSnake
	modeGameLife
	modeGameColors
	modeGameReflex
	modeGamePacman
)

var buttonsState []bool
var buttonsOldState []bool
var options = []string{
	"Badge",
	"Info",
	"GopherCon Schedule",
	"GopherCon Adventure",
	"Rainbow LEDs",
	"Accelerometer",
	"Music!",
	"Snake",
	"Game of Life",
	"Color Game",
	"Reflex",
	"Pac-Man",
}

var leds ws2812.Device
var bzrPin machine.Pin
var accel lis3dh.Device

var defaultFont tinyfont.Fonter

var snakeGame = NewSnakeGame()
var reflexGame = NewReflexGame()
var pacmanGame = NewPacmanGame()

func main() {

	buttonsState = make([]bool, 9)
	buttonsOldState = make([]bool, 9)
	defaultFont = &freemono.Regular12pt7b

	if displayWidth <= 180 || (displayWidth == 240 && displayHeight == 135) {
		defaultFont = &proggy.TinySZ8pt7b
	}

	initHardware()
	display.FillScreen(colorBlack)
	setCustomData()

	Info()

	for {
		selected := menu()
		runMenuOption(selected)
		time.Sleep(1 * time.Second)
	}
}

func writeLine(str string, c color.RGBA, x, y int16, maxWidth uint32, xCenter bool) bool {
	w32, _ := tinyfont.LineWidth(&freesans.Bold24pt7b, str)
	if w32 <= maxWidth {
		if xCenter {
			x = x - (int16(w32) / 2)
		}
		tinyfont.WriteLine(&display, &freesans.Bold24pt7b, x, y, str, c)
		return true
	}

	w32, _ = tinyfont.LineWidth(&freesans.Bold18pt7b, str)
	if w32 <= maxWidth {
		if xCenter {
			x = x - (int16(w32) / 2)
		}
		tinyfont.WriteLine(&display, &freesans.Bold18pt7b, x, y, str, c)
		return true
	}

	w32, _ = tinyfont.LineWidth(&freesans.Bold12pt7b, str)
	if w32 <= maxWidth {
		if xCenter {
			x = x - (int16(w32) / 2)
		}
		tinyfont.WriteLine(&display, &freesans.Bold12pt7b, x, y, str, c)
		return true
	}

	w32, _ = tinyfont.LineWidth(&freesans.Bold9pt7b, str)
	if xCenter {
		x = x - (int16(w32) / 2)
	}
	tinyfont.WriteLine(&display, &freesans.Bold9pt7b, x, y, str, c)
	if w32 <= maxWidth {
		return true
	}
	return false
}

func goBack() bool {
	return !buttonsOldState[buttonBack] && buttonsState[buttonBack]
}
