package gamemap

import (
	"lab.zaar.be/thefish/alchemyst-go/engine/ecs"
	"lab.zaar.be/thefish/alchemyst-go/engine/types"
	"lab.zaar.be/thefish/alchemyst-go/util"
)

//fixme move to config
var mapWidth = 150
var mapHeight = 90


type Level struct {
	*types.Rect
	ctx 		util.ClientCtx
	Name     string
	Branch   string
	Depth    int
	Objects  *[]ecs.Entity
	Tiles    []*Tile
}

func (l *Level) GetTile (coords types.Coords) *Tile {
	return l.Tiles[coords.Y*l.W+coords.X]
}

func (l *Level) GetTileNbs (coords types.Coords) []*Tile {
	result := make([]*Tile,0)
	for i := coords.X-1; i < coords.X+1; i++ {
		for j := coords.Y-1; j < coords.Y+1; j++ {
			nbc := types.Coords{i,j}
			if l.InBounds(nbc){
				if nbc == coords {
					continue
				}
				result = append(result, l.GetTileByXY(i,j))
			}
		}
	}
	return result
}

func (l *Level) GetTileByXY (x,y int) *Tile {
	return l.Tiles[y*l.W+x]
}

func (l *Level) SetTile (coords types.Coords, tile *Tile) {
	l.Tiles[coords.Y*l.W+coords.X] = tile
}

func (l *Level) SetTileByXY (x,y int, tile *Tile) {
	l.Tiles[y*l.W+x] = tile
}

func (l *Level) Put (x, y int, tileFunc interface{}) {
	tf := tileFunc.(func() *Tile)()
	if tf == nil {
		l.ctx.Logger().Fatal().Msgf("Got non-tile type to put into level: %v", tf)
	}
	if l.InBounds(types.Coords{x, y}) {
		l.Tiles[y*l.W+x] = tf
	}
}

func NewLevel(ctx util.ClientCtx, branch string, depth int) *Level {
	l := &Level{
		ctx: ctx,
		Name:     branch + string(depth),
		Depth:    depth,
		Rect: types.NewRect(0,0, mapWidth, mapHeight),
	}

	l.Tiles = make([]*Tile, l.W*l.H)
	ctx.Logger().Debug().Msgf("Generating level of branch %s depth %d", branch, depth)
	return l
}

func (l *Level) SetAllInvisible() {
	for idx, _ := range l.Tiles {
		l.Tiles[idx].Visible = false
	}
}

type Room struct {
	*types.Rect
	Center types.Coords
}