package gui

import (
	"image/color"

	"github.com/hajimehoshi/ebiten/v2"
	"github.com/hajimehoshi/ebiten/v2/ebitenutil"
	"github.com/hajimehoshi/ebiten/v2/examples/resources/fonts"

	_ "embed"
)

type App struct {
	Root       View
	Background color.Color

	defaultCtx *appCtx

	oldMouseEvent MouseEvent
}

func NewApp(root View) (*App, error) {
	fnt, err := LoadFontFromBytes(fonts.MPlus1pRegular_ttf)
	if err != nil {
		return nil, err
	}

	return &App{
		Root:       root,
		Background: color.White,

		defaultCtx: &appCtx{
			font:     fnt,
			fontSize: 16,
			fg:       color.Black,
			bg:       color.Transparent,
		},
	}, nil
}

func (a *App) Update() error {
	if a.Root == nil {
		return nil
	}

	winw, winh := ebiten.WindowSize()
	window := D(0, 0, winw, winh)

	// handle mouse events
	mouseEvent := makeMouseEvent()
	if mouseEvent.IsScrollEvent() {
		a.Root.OnMouseScroll(mouseEvent)
	}
	if mouseEvent.HasMouseMoved(a.oldMouseEvent) && mouseEvent.Position.In(window) {
		a.Root.OnMouseMove(mouseEvent)
	}
	if mouseEvent.Buttons.anyClicked() {
		a.Root.OnMouseClick(mouseEvent)
	}
	a.oldMouseEvent = mouseEvent

	return nil
}

func (a *App) Draw(screen *ebiten.Image) {
	if a.Root == nil {
		return
	}

	// layout phase
	a.Root.Layout(a.defaultCtx)

	// draw phase
	screen.Fill(a.Background)
	a.Root.Draw(newImage(screen), a.defaultCtx)

	// show fps
	ebitenutil.DebugPrint(screen, "") //fmt.Sprintf("fps: %g", ebiten.CurrentFPS()))
}

func (a *App) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
	return outsideWidth, outsideHeight
}

func (a *App) Start() error {
	ebiten.SetScreenTransparent(true)
	ebiten.SetWindowResizingMode(ebiten.WindowResizingModeEnabled)
	//ebiten.SetFPSMode(ebiten.FPSModeVsyncOffMinimum)
	ebiten.SetFPSMode(ebiten.FPSModeVsyncOffMaximum)
	ebiten.SetRunnableOnUnfocused(true)
	return ebiten.RunGame(a)
}
