package tins2021

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

type ChasingMonster struct{}

func (m ChasingMonster) Type() MonsterType { return MonsterTypeChaser }
func (m *ChasingMonster) FindTarget(level *Level, src geom.Point) (geom.Point, bool) {
	path := level.Tiles.ShortestPath(src, level.Player, func(_ geom.Point, t *Tile) bool { return !t.Occupied() })
	if len(path) < 2 {
		return geom.Point{}, false
	}
	if level.CanMonsterMoveTo(path[1]) {
		return path[1], true
	}
	return geom.Point{}, false
}

type Monster interface {
	Type() MonsterType
	FindTarget(*Level, geom.Point) (geom.Point, bool)
}

type Monsters map[geom.Point]Monster

type MonsterType int

const (
	MonsterTypeStraight MonsterType = iota
	MonsterTypeRandom
	MonsterTypeChaser
)

type RandomWalkingMonster struct{}

func (m RandomWalkingMonster) Type() MonsterType { return MonsterTypeRandom }
func (m *RandomWalkingMonster) FindTarget(level *Level, src geom.Point) (geom.Point, bool) {
	for i := 0; i < 5; i++ {
		dir := RandomDirection()
		dst, ok := level.CanMonsterMove(src, dir)
		if ok {
			return dst, true
		}
	}
	return geom.Point{}, false
}

type StraightWalkingMonster struct {
	Direction Direction
}

func (m StraightWalkingMonster) Type() MonsterType { return MonsterTypeStraight }
func (m *StraightWalkingMonster) FindTarget(level *Level, src geom.Point) (geom.Point, bool) {
	dst, ok := level.CanMonsterMove(src, m.Direction)
	if ok {
		return dst, true
	}
	reverse := m.Direction.Reverse()
	dst, ok = level.CanMonsterMove(src, reverse)
	if ok {
		m.Direction = reverse
		return dst, true
	}
	return geom.Point{}, false
}