require "prefabutil"

local assets =
{
		Asset("ANIM", "anim/wall.zip"),
		Asset("ANIM", "anim/wall_asia.zip"),
		Asset("ATLAS", "images/inventoryimages/wall_asia_item.xml")
}

local function onhammered(inst, worker)
	local num_loots = math.max(1, math.floor(2*inst.components.health:GetPercent()))
	for k = 1, num_loots do
	inst.components.lootdropper:SpawnLootPrefab("rocks")
	end

		
	SpawnPrefab("collapse_small").Transform:SetPosition(inst.Transform:GetWorldPosition())
		
	inst.SoundEmitter:PlaySound("dontstarve/common/destroy_stone")		

		
	inst:Remove()
end

local function test_wall(inst, pt)
	local tiletype = GetGroundTypeAtPosition(pt)
	local ground_OK = tiletype ~= GROUND.IMPASSABLE 
		
	if ground_OK then
	local ents = TheSim:FindEntities(pt.x,pt.y,pt.z, 2, nil, {"NOBLOCK", "player", "FX", "INLIMBO", "DECOR"}) -- or we could include a flag to the search?

	for k, v in pairs(ents) do
	if v ~= inst and v.entity:IsValid() and v.entity:IsVisible() and not v.components.placer and v.parent == nil then
	local dsq = distsq( Vector3(v.Transform:GetWorldPosition()), pt)
	if v:HasTag("wall") then
	if dsq < .1 then return false end
	else
	if  dsq< 1 then return false end
	end
	end
	end
			
	return true

	end
	return false
		
end

local function makeobstacle(inst)

	inst.Physics:SetCollisionGroup(COLLISION.OBSTACLES)	
	inst.Physics:ClearCollisionMask()
	inst.Physics:SetMass(0)
	inst.Physics:CollidesWith(COLLISION.ITEMS)
	inst.Physics:CollidesWith(COLLISION.CHARACTERS)
	inst.Physics:SetActive(true)
	local ground = GetWorld()
	if ground then
	local pt = Point(inst.Transform:GetWorldPosition())
	ground.Pathfinder:AddWall(pt.x, pt.y, pt.z)
	end
end

local function clearobstacle(inst)
	inst:DoTaskInTime(2*FRAMES, function() inst.Physics:SetActive(false) end)

	local ground = GetWorld()
	if ground then
	local pt = Point(inst.Transform:GetWorldPosition())
	ground.Pathfinder:RemoveWall(pt.x, pt.y, pt.z)
	end
end

local function resolveanimtoplay(percent)
	local anim_to_play = nil
	if percent <= 0 then
	anim_to_play = "0"
	elseif percent <= .4 then
	anim_to_play = "1_4"
	elseif percent <= .5 then
	anim_to_play = "1_2"
	elseif percent < 1 then
	anim_to_play = "3_4"
	else
	anim_to_play = "1"
	end
	return anim_to_play
end

local function onhealthchange(inst, old_percent, new_percent)
		
	if old_percent <= 0 and new_percent > 0 then makeobstacle(inst) end
	if old_percent > 0 and new_percent <= 0 then clearobstacle(inst) end

	local anim_to_play = resolveanimtoplay(new_percent)
	if new_percent > 0 and not inst.components.walldoors:IsOpen() then
		inst.AnimState:PlayAnimation("0")
	elseif new_percent > 0 and inst.components.walldoors:IsOpen() then
		inst.AnimState:PlayAnimation(anim_to_play.."_hit")
		inst.AnimState:PushAnimation(anim_to_play, false)
	else
		inst.AnimState:PlayAnimation(anim_to_play)
	end
end

local function openwallremote(inst)
	   if inst.components.health:GetPercent() <= 0 then
	   inst.SoundEmitter:PlaySound("dontstarve/common/destroy_stone")	
	   inst.components.walldoors.isopen = false
	   inst.AnimState:PushAnimation("0")
	   elseif inst.components.health:GetPercent() <= .4 then
	   inst.components.walldoors.isopen = true
	   inst.AnimState:PlayAnimation("1_4")
	   inst.SoundEmitter:PlaySound("dontstarve/common/place_structure_stone")
	   makeobstacle(inst)
	   elseif inst.components.health:GetPercent() <= .5 then
	   inst.components.walldoors.isopen = true
	   inst.AnimState:PlayAnimation("1_2")
	   inst.SoundEmitter:PlaySound("dontstarve/common/place_structure_stone")
	   makeobstacle(inst)
	   elseif inst.components.health:GetPercent() <= .9 then
	   inst.components.walldoors.isopen = true
	   inst.AnimState:PlayAnimation("3_4")
	   inst.SoundEmitter:PlaySound("dontstarve/common/place_structure_stone")
	   makeobstacle(inst)
	   else
	   inst.AnimState:PlayAnimation("1")
	   inst.SoundEmitter:PlaySound("dontstarve/common/place_structure_stone")
	   inst.components.walldoors.isopen = true
	   makeobstacle(inst)
	   end
end
	
local function openwall(inst)
	   if inst.components.health:GetPercent() <= 0 then
	   inst.SoundEmitter:PlaySound("dontstarve/common/destroy_stone")	
	   inst.components.walldoors.isopen = false
	   inst.AnimState:PushAnimation("0")
	   elseif inst.components.health:GetPercent() <= .4 then
	   inst.components.walldoors.isopen = true
	   inst.AnimState:PlayAnimation("1_4")
	   inst.SoundEmitter:PlaySound("dontstarve/common/place_structure_stone")
	   makeobstacle(inst)
	   elseif inst.components.health:GetPercent() <= .5 then
	   inst.components.walldoors.isopen = true
	   inst.AnimState:PlayAnimation("1_2")
	   inst.SoundEmitter:PlaySound("dontstarve/common/place_structure_stone")
	   makeobstacle(inst)
	   elseif inst.components.health:GetPercent() <= .9 then
	   inst.components.walldoors.isopen = true
	   inst.AnimState:PlayAnimation("3_4")
	   inst.SoundEmitter:PlaySound("dontstarve/common/place_structure_stone")
	   makeobstacle(inst)
	   else
	   inst.AnimState:PlayAnimation("1")
	   inst.SoundEmitter:PlaySound("dontstarve/common/place_structure_stone")
	   inst.components.walldoors.isopen = true
	   makeobstacle(inst)
	   end
end
	
local function closewallremote(inst, data)
	    inst.components.walldoors.isopen = false
	    inst.SoundEmitter:PlaySound("dontstarve/common/destroy_stone")		
	    inst.AnimState:PlayAnimation("0")
	    clearobstacle(inst)
end
	
local function closewall(inst, data)
	    inst.components.walldoors.isopen = false
	    inst.SoundEmitter:PlaySound("dontstarve/common/destroy_stone")		
	    inst.AnimState:PlayAnimation("0")
	    clearobstacle(inst)
end

local function ondeploywall(inst, pt, deployer)
	local wall = SpawnPrefab("wall_asia") 
	if wall then 
	pt = Vector3(math.floor(pt.x)+.5, 0, math.floor(pt.z)+.5)
	wall.Physics:SetCollides(false)
	wall.Physics:Teleport(pt.x, pt.y, pt.z) 
	wall.Physics:SetCollides(true)
	inst.components.stackable:Get():Remove()

	local ground = GetWorld()
	if ground then
	ground.Pathfinder:AddWall(pt.x, pt.y, pt.z)
	openwall(wall)
	end
	end 		
end

local function itemfn(Sim)

	local inst = CreateEntity()
	inst:AddTag("wallbuilder")
		
	inst.entity:AddTransform()
	inst.entity:AddAnimState()
	MakeInventoryPhysics(inst)
	    
	inst.AnimState:SetBank("wall")
	inst.AnimState:SetBuild("wall_asia")
	inst.AnimState:PlayAnimation("idle")
	
	inst:AddTag("asia")

	inst:AddComponent("stackable")
	inst.components.stackable.maxsize = TUNING.STACK_SIZE_MEDITEM

	inst:AddComponent("inspectable")
	inst:AddComponent("inventoryitem")
	inst.components.inventoryitem.atlasname = "images/inventoryimages/wall_asia_item.xml"
		
	inst:AddComponent("repairer")

	inst.components.repairer.repairmaterial = "wood"

	inst.components.repairer.healthrepairvalue = TUNING.RUINSWALL_HEALTH / 6
		
	inst:AddComponent("deployable")
	inst.components.deployable.ondeploy = ondeploywall
	inst.components.deployable.test = test_wall
	inst.components.deployable.min_spacing = 0
	inst.components.deployable.placer = "wall_asia_placer"
		
	return inst
end

local function onhit(inst)
	inst.SoundEmitter:PlaySound("dontstarve/common/destroy_stone")

	local healthpercent = inst.components.health:GetPercent()
	local anim_to_play = resolveanimtoplay(healthpercent)
	if healthpercent > 0 and not inst.components.walldoors:IsOpen() then
	inst.AnimState:PlayAnimation("0")
	elseif healthpercent > 0 then
	inst.AnimState:PlayAnimation(anim_to_play.."_hit")		
	inst.AnimState:PushAnimation(anim_to_play, false)	
	end	

end

local function onrepaired(inst)
		inst.SoundEmitter:PlaySound("dontstarve/common/place_structure_stone")
		makeobstacle(inst)
end
	    
local function onload(inst, data)
		--print("walls - onload")
		makeobstacle(inst)
		if inst.components.health:GetPercent() <= 0 then
			clearobstacle(inst)
		end
end

local function onremoveentity(inst)
		clearobstacle(inst)
end

local function fn(Sim)
	local inst = CreateEntity()
	local trans = inst.entity:AddTransform()
	local anim = inst.entity:AddAnimState()
	inst.entity:AddSoundEmitter()
	inst:AddTag("wall")
	inst:AddTag("stone")
	inst:AddTag("wood")
	inst:AddTag("asia")
	inst:AddTag("walldoor")
	inst:AddTag("noauradamage")
	MakeObstaclePhysics(inst, .5)    
	inst.entity:SetCanSleep(false)
	anim:SetBank("wall")
	anim:SetBuild("wall_asia")
	anim:PlayAnimation("1_2", false)
	    
	inst:AddComponent("inspectable")
	inst:AddComponent("lootdropper")
				
	inst:AddComponent("repairable")
	inst.components.repairable.repairmaterial = "wood"
	inst.components.repairable.onrepaired = onrepaired
		
	inst:AddComponent("combat")
	inst.components.combat.onhitfn = onhit
		
	inst:AddComponent("health")
	inst.components.health:SetMaxHealth(TUNING.RUINSWALL_HEALTH)
	inst.components.health.currenthealth = TUNING.RUINSWALL_HEALTH / 2
	inst.components.health.ondelta = onhealthchange
	inst.components.health.nofadeout = true
	inst.components.health.canheal = false
	inst:AddTag("noauradamage")
		
	inst.components.health.fire_damage_scale = 0
	
	inst:AddComponent("walldoors")
	inst.components.walldoors.openwallfn = openwall
	inst.components.walldoors.closewallfn = closewall
	inst.components.walldoors.caninteractfn = function() return not inst.components.health:IsDead() end

	inst.SoundEmitter:PlaySound("dontstarve/common/destroy_stone")
		
	inst:AddComponent("workable")
	inst.components.workable:SetWorkAction(ACTIONS.HAMMER)
	inst.components.workable:SetWorkLeft(3)
	inst.components.workable:SetOnFinishCallback(onhammered)
	inst.components.workable:SetOnWorkCallback(onhit) 
				
		
	inst.OnLoad = onload
	inst.OnRemoveEntity = onremoveentity
		
	MakeSnowCovered(inst)
		
	return inst
end

return Prefab( "common/wall_asia", fn, assets),
Prefab( "common/wall_asia_item", itemfn, assets, {"wall_asia", "wall_asia_placer"}),
MakePlacer("common/wall_asia_placer", "wall", "wall_asia", "1_2", false, false, true)