local assets =
{
    Asset("ANIM", "anim/idleshadowstuff.zip"),
	    Asset("ANIM", "anim/swap_shadowtorch.zip"),
    Asset("SOUND", "sound/common.fsb"),
	
		Asset("ATLAS", "images/inventoryimages/shadowtorch.xml"),
	Asset("IMAGE", "images/inventoryimages/shadowtorch.tex"),
}

local prefabs =
{
    "torchfire",
}

local function onequipfueldelta(inst)
    if inst.components.fueled.currentfuel < inst.components.fueled.maxfuel then
        inst.components.fueled:DoDelta(-.01 * inst.components.fueled.maxfuel)
    end
end

local function onequip(inst, owner)
 inst.Light:Enable(true)
    inst.Light:SetIntensity(.75)
    inst.Light:SetColour(253/255,179/255,179/255)
    inst.Light:SetFalloff(0.33)
    inst.Light:SetRadius(2)
    inst.components.burnable:Ignite()

      owner.AnimState:OverrideSymbol("swap_object", "swap_shadowtorch", "swap_shadowtorch")
    owner.AnimState:Show("ARM_carry")
    owner.AnimState:Hide("ARM_normal")

    inst.SoundEmitter:PlaySound("dontstarve/common/nightlight", "torch")
    inst.SoundEmitter:PlaySound("dontstarve/wilson/torch_swing")
    inst.SoundEmitter:SetParameter("torch", "intensity", 1)
    if inst.fires == nil then
        inst.fires = {}
	
	for i, fx_prefab in ipairs(inst:GetSkinName() == nil and { "torchfire" } or SKIN_FX_PREFAB[inst:GetSkinName()] or {}) do
            local fx = SpawnPrefab("shadowtorchfire")
            fx.entity:SetParent(owner.entity)
            fx.entity:AddFollower()
            fx.Follower:FollowSymbol(owner.GUID, "swap_object", 0, fx.fx_offset, 0)

			            table.insert(inst.fires, fx)
        end
    
	end		
    --take a percent of fuel next frame instead of this one, so we can remove the torch properly if it runs out at that point
    inst:DoTaskInTime(0, onequipfueldelta)
end

local function Unlight(inst)
 inst.Light:Enable(false)
end

local function onunequip(inst, owner)
 inst.Light:Enable(false)
    local skin_build = inst:GetSkinBuild()
    if skin_build ~= nil then
        owner:PushEvent("unequipskinneditem", inst:GetSkinName())
    end

    if inst.fires ~= nil then
        for i, fx in ipairs(inst.fires) do
            fx:Remove()
        end
        inst.fires = nil
        inst.SoundEmitter:PlaySound("dontstarve/common/fireOut")
    end

    inst.components.burnable:Extinguish()
    owner.AnimState:Hide("ARM_carry") 
    owner.AnimState:Show("ARM_normal")
    inst.SoundEmitter:KillSound("torch")
end

local function onpocket(inst, owner)
    inst.components.burnable:Extinguish()
	
 inst.Light:Enable(false)
end



local function Haunt(inst, data)

 local torchowner = inst.components.inventoryitem.owner
local target = data


  if target ~= nil and target.components.hauntable ~= nil then
  
 if target.components.hauntable.haunted == true then
 else
  torchowner.components.sanity:DoDelta(-10)
		 target.components.hauntable:DoHaunt(inst)
		    inst._fx2 = SpawnPrefab("shadowtorchfire")
    inst._fx2.entity:SetParent(target.entity)
    inst._fx2.Transform:SetPosition(0, 0.8, 0)	
		 inst._fx2.Transform:SetScale(3, 3, 3)
inst._fx2:DoTaskInTime(2, ErodeAway)
	end	  
end


 target.components.burnable:Extinguish(true, 0)
end

local function onattack(weapon, attacker, target)	
 if target ~= nil and target.components.hauntable ~= nil then
  
 if target.components.hauntable.haunted == true then
 else
 attacker.components.sanity:DoDelta(-10)
         weapon.components.fueled:DoDelta(-.02 * weapon.components.fueled.maxfuel)
		 target.components.hauntable:DoHaunt(attacker)
		    target._fx2 = SpawnPrefab("shadowtorchfire")
    target._fx2.entity:SetParent(target.entity)
    target._fx2.Transform:SetPosition(0, 1, 0)	
		 target._fx2.Transform:SetScale(3, 3, 3)
target._fx2:DoTaskInTime(2, ErodeAway)

	end	  
end


end

local function onupdatefueledraining(inst)
    local owner = inst.components.inventoryitem ~= nil and inst.components.inventoryitem.owner or nil
    inst.components.fueled.rate =
        owner ~= nil and
        owner.components.sheltered ~= nil and
        owner.components.sheltered.sheltered and
        1 or 1 + TUNING.TORCH_RAIN_RATE * TheWorld.state.precipitationrate
end

local function onisraining(inst, israining)
    if inst.components.fueled ~= nil then
        if israining then
            inst.components.fueled:SetUpdateFn(onupdatefueledraining)
        else
            inst.components.fueled:SetUpdateFn()
            inst.components.fueled.rate = 1
        end
    end
end

local function sectioncallback(newsection, oldsection, inst)
    if newsection == 0 then
        --when we burn out
        if inst.components.burnable ~= nil then
            inst.components.burnable:Extinguish()
        end
        local equippable = inst.components.equippable
        if equippable ~= nil and equippable:IsEquipped() then
            local owner = inst.components.inventoryitem ~= nil and inst.components.inventoryitem.owner or nil
            if owner ~= nil then
                local data =
                {
                    prefab = inst.prefab,
                    equipslot = equippable.equipslot,
                    announce = "ANNOUNCE_TORCH_OUT",
                }
                inst:Remove()

                owner:PushEvent("itemranout", data)
                return
            end
        end
        inst:Remove()

    end
end

local function fn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
    inst.entity:AddAnimState()
    inst.entity:AddSoundEmitter()
    inst.entity:AddNetwork()
	    inst.entity:AddLight()
 inst.Light:Enable(false)
    MakeInventoryPhysics(inst)

    inst.AnimState:SetBank("idleshadowstuff")
    inst.AnimState:SetBuild("idleshadowstuff")
    inst.AnimState:PlayAnimation("torch")

    inst:AddTag("wildfireprotected")

    --lighter (from lighter component) added to pristine state for optimization
    inst:AddTag("lighter")

    --waterproofer (from waterproofer component) added to pristine state for optimization
    inst:AddTag("waterproofer")


	
    inst.entity:SetPristine()

    if not TheWorld.ismastersim then
        return inst
    end

    inst:AddComponent("weapon")
    inst.components.weapon:SetDamage(TUNING.TORCH_DAMAGE)
    inst.components.weapon:SetOnAttack(onattack)

    -----------------------------------

    inst:AddTag("shadow")
    inst:AddComponent("lighter")
inst.components.lighter:SetOnLightFn(Haunt)
    -----------------------------------

    inst:AddComponent("inventoryitem")
	inst.components.inventoryitem:SetOnDroppedFn(Unlight)
		inst.components.inventoryitem.imagename = "shadowtorch"
    inst.components.inventoryitem.atlasname = "images/inventoryimages/shadowtorch.xml"
    -----------------------------------

    inst:AddComponent("equippable")
    inst.components.equippable:SetOnPocket(onpocket)
    inst.components.equippable:SetOnEquip(onequip)
    inst.components.equippable:SetOnUnequip(onunequip)
	    inst.components.equippable.dapperness = TUNING.CRAZINESS_SMALL

    -----------------------------------

    inst:AddComponent("waterproofer")
    inst.components.waterproofer:SetEffectiveness(0.01)


    -----------------------------------

    inst:AddComponent("inspectable")

    -----------------------------------

    inst:AddComponent("burnable")
    inst.components.burnable.canlight = false
    inst.components.burnable.fxprefab = nil


    -----------------------------------

    inst:AddComponent("fueled")
    inst.components.fueled:SetSectionCallback(sectioncallback)
    inst.components.fueled:InitializeFuelLevel(TUNING.TORCH_FUEL * 3)
    inst.components.fueled:SetDepletedFn(inst.Remove)

    inst:WatchWorldState("israining", onisraining)
    onisraining(inst, TheWorld.state.israining)

    MakeHauntableLaunch(inst)

    return inst
end

return Prefab("shadowtorch", fn, assets, prefabs)
