package mainwindow

import (
	"errors"
	"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
	"lab.zaar.be/thefish/alchemyst-go/engine/types"
)

var NotInViewError = errors.New("not in ViewPort")
const FPS_LIMIT = 60

type ViewPort struct {
	*types.Rect
	level *gamemap.Level
	layer *Layer
}

func NewViewPort(x, y, w, h int, level *gamemap.Level, layer *Layer) *ViewPort {
	return &ViewPort{
		Rect:  &types.Rect{x, y, w, h},
		level: level,
		layer: layer,
	}
}

func (vp *ViewPort) Move(c *types.Coords) {
	x := c.X - vp.Rect.W/2
	y := c.Y - vp.Rect.H/2

	if x < 0 {
		x = 0
	}
	if y < 0 {
		y = 0
	}
	if x > vp.level.W-vp.W {
		x = vp.level.W - vp.W
	}
	if y > vp.level.H-vp.H {
		x = vp.level.H - vp.H
	}
	//if x != vp.X || y != vp.Y { State.FovRecompute <- struct{}{}}
	vp.X, vp.Y = x, y
}

func (vp *ViewPort) ToVPCoords(c *types.Coords) (newCoords *types.Coords, err error) {
	//coords on map to coords on vp
	x, y := c.X-vp.X, c.Y-vp.Y
	if x < 0 || y < 0 || x >= vp.W || y >= vp.H {
		return &types.Coords{-1, -1}, NotInViewError
	}
	return &types.Coords{x, y}, nil
}

//call only from main thread
//func (vp *ViewPort) Render() {
//	//fixme get these from state chan(s)
//	var fpsTicker int
//	var fovRecompute bool
//	redraw := false
//	//fixme get player instance
//
//	vp.Move(player.Coords)
//	//fixme detect fovRecompute
//	if fovRecompute {
//		vp.layer.Clear(vp.Rect)
//		fovRecompute = false
//		redraw = true
//		//fixme
//		vp.level.ComputeFov(FovMap, player.Coords, player.TorchRadius, FovLightWalls, FovAlgo)
//	}
//	//increase ticker
//	fpsTicker++
//
//	if redraw || fpsTicker % (FPS_LIMIT /  10) == 0 {
//		fpsTicker := 0
//
//		for y:=0; y < vp.H; y++ {
//			for x:=0; x<vp.W; x++ {
//				mapCoords := types.Coords{vp.X + x, vp.Y + y}
//				tile := vp.level.Tiles[mapCoords.X][mapCoords.Y]
//				visible := vp.IsInFov(mapCoords)
//				if !visible {
//					if tile.MustDraw {
//						//darkened version of landscape
//						vp.layer.WithRawColor(tile.ColorSet.DarkFg()).
//							PutWithRawBackground(mapCoords.X, mapCoords.Y, tile.Char, tile.ColorSet.DarkBg())
//					}
//				} else {
//					if redraw == true || tile.Colordance {
//						vp.layer.WithRawColor(tile.ColorSet.Fg()).
//							PutWithRawBackground(mapCoords.X, mapCoords.Y, tile.Char, tile.ColorSet.Bg())
//						tile.Explored = true
//						tile.MustDraw = true
//					}
//				}
//			}
//		}
//
//	}
//}