package ui

import (
	"opslag.de/schobers/geom"
)

type Context interface {
	Animate()
	Fonts() *Fonts
	HasQuit() bool
	MousePosition() geom.PointF32
	Overlays() *Overlays
	Quit()
	Renderer() Renderer
	ShowTooltip(t string)
	Style() *Style
	Textures() *Textures
}

var _ Context = &context{}
var _ EventTarget = &context{}

type context struct {
	animate  bool
	quit     chan struct{}
	renderer Renderer
	view     Control
	mouse    geom.PointF32
	tooltip  *Tooltip
	overlays *Overlays
	fonts    *Fonts
	textures *Textures
	style    *Style
}

func newContext(r Renderer, s *Style, view Control) *context {
	ctx := &context{
		quit:     make(chan struct{}),
		renderer: r,
		style:    s,
		view:     view,
		tooltip:  &Tooltip{},
		overlays: NewOverlays(view),
		fonts:    NewFonts(r),
		textures: NewTextures(r)}
	ctx.overlays.AddOnTop(uiDefaultTooltipOverlay, ctx.tooltip, false)
	return ctx
}

func (c *context) Animate() { c.animate = true }

func (c *context) Destroy() {
	c.fonts.Destroy()
	c.textures.Destroy()
}

func (c *context) Fonts() *Fonts { return c.fonts }

func (c *context) HasQuit() bool {
	select {
	case <-c.quit:
		return true
	default:
		return false
	}
}

func (c *context) MousePosition() geom.PointF32 { return c.mouse }

func (c *context) Overlays() *Overlays { return c.overlays }

func (c *context) Renderer() Renderer { return c.renderer }

func (c *context) ShowTooltip(t string) {
	c.overlays.Show(uiDefaultTooltipOverlay)
	c.tooltip.Text = t
}

func (c *context) Style() *Style { return c.style }

func (c *context) Quit() {
	if !c.HasQuit() {
		close(c.quit)
	}
}

func (c *context) Textures() *Textures { return c.textures }

// Handle implement EventTarget

func (c *context) Handle(e Event) {
	switch e := e.(type) {
	case *DisplayCloseEvent:
		c.Quit()
		return
	case *MouseMoveEvent:
		c.mouse = e.Pos()
	}
	c.overlays.Handle(c, e)
}