package items

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

type CarriedFace interface {
	Drop()
	Pickup()
}

type Carried struct {
	Mass int //масса в граммах
	Bulk int //внешний размер, см3
}

func (c Carried) Type() string {
	return ecs.CarriedComponent
}

func (c Carried) Pickup(who, what ecs.Entity) {
	// check if im lying on ground
	if !Controller.HasComponent(what, ecs.CoordsComponent) {
		return
	}
	// something inexistent on map trying to pickup an item?!
	if !Controller.HasComponent(who, ecs.CoordsComponent) {
		//todo log error - investigate this situation
		return
	}
	//check if who and what are on the same tile
	whoCoords := Controller.GetComponent(who, ecs.CoordsComponent).(types.Coords)
	whatCoords := Controller.GetComponent(what, ecs.CoordsComponent).(types.Coords)
	if whoCoords != whatCoords {
		//todo log error - something strange happened
		return
	}
	//does not have inventory?
	if !Controller.HasComponent(who, ecs.BackpackComponent) {
		//todo send message - you cant carry items
		return
	}
	bp := Controller.GetComponent(who, Backpack{}.Type()).(Backpack)
	if !bp.HasFreeSpace(c.Bulk, c.Mass) {
		//todo send message - does not fit to your inventory
		return
	}
	//do not remove appearance
	//remove coords instead (does not exist on map anymore)
	Controller.RemoveComponent(what, ecs.CoordsComponent)
	bp.items = append(bp.items, what)
}

func (c Carried) Drop(who, what ecs.Entity) {
	var coords types.Coords
	// something inexistent on map trying to drop an item?!
	if !Controller.HasComponent(who, ecs.CoordsComponent) {
		//todo log error - investigate this situation
		return
	} else {
		coords = Controller.GetComponent(who, types.Coords{}.Type()).(types.Coords)
	}
	//does not have inventory?
	if !Controller.HasComponent(who, ecs.BackpackComponent) {
		//todo send message - you cant carry items
		return
	}

	bp := Controller.GetComponent(who, Backpack{}.Type()).(Backpack)
	var dropped ecs.Entity
	bp.items, dropped = ecs.DeleteFromEntitySlice(bp.items, what)
	if dropped != what {
		//todo log error - something strange happened
		return
	}
	//Give dropped back coordinated
	Controller.AddComponent(dropped, coords)
	//Controller.UpdateComponent(what, coords.Type(), coords) //even we need that?
	Controller.UpdateComponent(who, bp.Type(), bp)
}

func (c Carried) GetMass(what ecs.Entity) int {
	return c.Mass
}
func (c *Carried) GetBulk(what ecs.Entity) int {
	return c.Bulk
}