require "prefabutil"

---------------Config data
local name = "Mush Garden DS" --Change this variable to be the same as in modinfo.lua, if you change the mod name or move this file.
local folder = KnownModIndex:GetModActualName(name)

local MUSHPERDAY=GetModConfigData("MUSHPERDAY", folder)	--Determines growth rate
local MAXMUSH=GetModConfigData("MAXMUSH", folder)		--Determines flower density
local childtype1="mushtree_tall"
local childtype2="mushtree_medium"
local childtype3="mushtree_small"
---------------

local assets =
{
	Asset("ANIM", "anim/mushgarden_big.zip"),
}

local anim={}
anim.idle = "idle_mush"
anim.hit = anim.idle
anim.place ="idle"

local prefabs =
{
    childtype1,
    childtype2,
	childtype3,
	
	"collapse_small",
}



local function onhammered(inst, worker)
	if inst:HasTag("fire") and inst.components.burnable then
		inst.components.burnable:Extinguish()
	end
	inst.components.lootdropper:DropLoot()
	SpawnPrefab("collapse_small").Transform:SetPosition(inst.Transform:GetWorldPosition())
	inst.SoundEmitter:PlaySound("dontstarve/common/destroy_wood")
	inst:Remove()
end

local function onhit(inst, worker)
	if not inst:HasTag("burnt") then 
		inst.AnimState:PlayAnimation(inst.anims.hit)
		inst.AnimState:PushAnimation(inst.anims.idle, false)
	end
end

local function OnSave(inst, data)
	if inst:HasTag("burnt") or inst:HasTag("fire") then
		data.burnt = true
	end
end

local function OnLoad(inst, data)
	if data and data.burnt then
		inst.components.burnable.onburnt(inst)
	end
end

local function onbuilt(inst)
	inst.AnimState:PlayAnimation(anim.place)
	inst.AnimState:PushAnimation(anim.idle, false)
end

local function PlantMush(inst)
	local minrad=4
	local maxrad=6
	
	--inst exists
	if not inst then return end
	local pt = inst:GetPosition()
	
	--not too many children
	local ents = TheSim:FindEntities(pt.x, pt.y, pt.z, maxrad)
	local count=0
	for k,v in pairs(ents) do
		if v.prefab == childtype1 then
			count = count + 1
		end
	end
    if count>=MAXMUSH then return end
	
	--Find spot for new child and spawn
	local angle=math.random()*2*PI
	local radius=math.random()*(maxrad-minrad)+minrad
	local offset, check_angle, deflected=FindWalkableOffset(pt, angle, radius, 8, false, false)
	if(not check_angle) then return end
	angle=check_angle
	pt.x=pt.x+radius*math.cos(angle)
	pt.z=pt.z-radius*math.sin(angle)
	
	SpawnPrefab(childtype1).Transform:SetPosition(pt:Get())
	
	--not too many children
	local ents = TheSim:FindEntities(pt.x, pt.y, pt.z, maxrad)
	local count=0
	for k,v in pairs(ents) do
		if v.prefab == childtype2 then
			count = count + 1
		end
	end
	if count>=MAXMUSH then return end
	
	--Find spot for new child and spawn
	local angle=math.random()*2*PI
	local radius=math.random()*(maxrad-minrad)+minrad
	local offset, check_angle, deflected=FindWalkableOffset(pt, angle, radius, 9, false, false)
	if(not check_angle) then return end
	angle=check_angle
	pt.x=pt.x+radius*math.cos(angle)
	pt.z=pt.z-radius*math.sin(angle)
	
	SpawnPrefab(childtype2).Transform:SetPosition(pt:Get())
	
	--not too many children
	local ents = TheSim:FindEntities(pt.x, pt.y, pt.z, maxrad)
	local count=0
	for k,v in pairs(ents) do
		if v.prefab == childtype3 then
			count = count + 1
		end
	end
	if count>=MAXMUSH then return end
	
	
	--Find spot for new child and spawn
	local angle=math.random()*2*PI
	local radius=math.random()*(maxrad-minrad)+minrad
	local offset, check_angle, deflected=FindWalkableOffset(pt, angle, radius, 10, false, false)
	if(not check_angle) then return end
	angle=check_angle
	pt.x=pt.x+radius*math.cos(angle)
	pt.z=pt.z-radius*math.sin(angle)
	
	SpawnPrefab(childtype3).Transform:SetPosition(pt:Get())
end

local function saveanims(inst)
	if inst.anims==nil then
		inst.anims = {}
	end
	
	inst.anims.idle = anim.idle
	inst.anims.hit = anim.hit
	inst.anims.place = anim.place
end

local function fn()
	---------------Entity details
	
	local inst = CreateEntity()
	inst.entity:AddTransform()
	inst.entity:AddAnimState()
	inst.entity:AddSoundEmitter()
	---inst.MiniMapEntity:SetIcon("mushgarden_big.tex")

	local minimap = inst.entity:AddMiniMapEntity()
	minimap:SetIcon( "mushgarden_big.tex" )
	
	MakeObstaclePhysics(inst, 1.4)
	
	---------------Animation
	
	inst.AnimState:SetBank("mushgarden_big")
	inst.AnimState:SetBuild("mushgarden_big")
	inst.AnimState:PlayAnimation(anim.idle)
	
	---------------Tags
	inst:AddTag("structure")
	inst:AddTag("playerowned")
	
	---------------????	--DST only
	--MakeSnowCoveredPristine(inst)
	--inst.entity:SetPristine()
	--if not TheWorld.ismastersim then
	--	return inst
	--end 

	---------------Growing details
local growth_stages = {
		{name="only",
		time=function(inst) return TUNING.TOTAL_DAY_TIME/MUSHPERDAY end,
		fn=function(inst) PlantMush(inst) end},
	}
	
	inst:AddComponent("growable")
	inst.components.growable.stages = growth_stages
	inst.components.growable.stage = 1
	inst.components.growable.loopstages = true
	inst.components.growable:StartGrowing()
	
	---------------Components
	inst:AddComponent("inspectable")
	inst:AddComponent("lootdropper")
	inst:AddComponent("workable")
	inst.components.workable:SetWorkAction(ACTIONS.HAMMER)
	inst.components.workable:SetWorkLeft(4)
	inst.components.workable:SetOnFinishCallback(onhammered)
	inst.components.workable:SetOnWorkCallback(onhit)
	
	---------------Etcetera
	saveanims(inst)

	--MakeHauntableWork(inst)		--DST only
	MakeSnowCovered(inst)
	inst:ListenForEvent("onbuilt", onbuilt)
	
	MakeSmallBurnable(inst)
    MakeSmallPropagator(inst)
	
	inst.OnSave = OnSave
	inst.OnLoad = OnLoad
	
	return inst
end
	
 return  Prefab("common/objects/mushgarden_big", fn, assets, prefabs),
	MakePlacer("common/mushgarden_big_placer", "mushgarden_big", "mushgarden_big", "idle")