
local assets =
{
    Asset("ANIM", "anim/greent.zip"),
    Asset("ANIM", "anim/swap_greent.zip"),
    Asset("ATLAS", "inventoryimages/greent.xml"),
  	Asset("IMAGE", "inventoryimages/greent.tex"),
}

local prefabs =
{
    "torchfire",
}

local function ontakefuel(inst)
    inst.SoundEmitter:PlaySound("dontstarve/common/fireAddFuel")
end

local function onupdatefueled(inst)
    local fueled = inst.components.fueled

    fueled.rate = TheWorld.state.israining and 1 + TUNING.FIREPIT_RAIN_RATE * TheWorld.state.precipitationrate or 1

    if inst.components.burnable ~= nil then
        inst.components.burnable:SetFXLevel(fueled:GetCurrentSection(), fueled:GetSectionPercent())
    end
end

LightOn = function(inst)
	--p("LightOn")
	if not inst:IsValid() then
		return
	end
	local owner = inst.components.inventoryitem:GetGrandOwner()
	if owner then
		if not (inst._light and inst._light:IsValid()) then
			inst._light = SpawnPrefab("torchfire")
			if not (inst._light and inst._light:IsValid()) then
				return
			end
			inst._light.Light:Enable(true)
			inst._light.Light:SetRadius(3)
			inst._light.Light:SetFalloff(0.5)
			inst._light.Light:SetIntensity(.75)
			inst._light.Light:SetColour(237/255, 237/255, 209/255)
			--inst._light.entity:SetParent(owner.entity)
		end
		if owner ~= inst._light.parent then
			owner:AddChild(inst._light)
		end
	else
		--on the ground?
		inst.AnimState:SetBuild("greent")
		inst.Light:Enable(true)
	end
	inst.SoundEmitter:PlaySound("dontstarve/common/lightningrod")

	--[[if not(inst.components.fueled and (not inst.components.fueled:IsEmpty()) and (not inst.components.machine.ison)) then
		return
	end
	if pause then
		--p("Pause")
		inst.light_task = inst:DoTaskInTime(pause,LightOn)
		return
	end
	if inst._light then
		--p("No _light")
		return
	end
	local owner = inst.components.inventoryitem and inst.components.inventoryitem.owner
	if owner then
		inst._light = SpawnPrefab("torchfire")
	end
	if inst.components.fueled and not owner then
		--p("Light self")
		inst.Light:Enable(true)
	elseif inst._light and owner and owner:IsValid() and inst.components.fueled then
		--p("Light")
	else
		return
	end
	inst.components.fueled:StartConsuming()
	inst.AnimState:SetBuild("greent")
	inst.components.machine:TurnOn()--]]
end

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.components.burnable:Ignite()
        owner.AnimState:OverrideSymbol("swap_object", "swap_greent", "greent")
    owner.AnimState:Show("ARM_carry")
    owner.AnimState:Hide("ARM_normal")

    inst.SoundEmitter:PlaySound("dontstarve/wilson/torch_LP", "torch")
    inst.SoundEmitter:PlaySound("dontstarve/wilson/torch_swing")
    inst.SoundEmitter:SetParameter("torch", "intensity", 0.7)

    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(fx_prefab)
            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 onunequip(inst, owner)
    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()
end

local function onattack(weapon, attacker, target)
    if target ~= nil and target.components.burnable ~= nil and math.random() < TUNING.TORCH_ATTACK_IGNITE_PERCENT * target.components.burnable.flammability then
        target.components.burnable:Ignite(nil, attacker)
    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()

    MakeInventoryPhysics(inst)

    inst.AnimState:SetBank("greent")
    inst.AnimState:SetBuild("greent")
    inst.AnimState:PlayAnimation("idle")

    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:AddComponent("lighter")
    -----------------------------------

    inst:AddComponent("inventoryitem")
	inst.components.inventoryitem.imagename = "greent"
    inst.components.inventoryitem.atlasname = "inventoryimages/greent.xml"
    -----------------------------------

    inst:AddComponent("equippable")
    inst.components.equippable:SetOnPocket(onpocket)
    inst.components.equippable:SetOnEquip(onequip)
    inst.components.equippable:SetOnUnequip(onunequip)

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

    inst:AddComponent("waterproofer")
    inst.components.waterproofer:SetEffectiveness(TUNING.WATERPROOFNESS_SMALLMED)

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

    inst:AddComponent("inspectable")

    inst:AddComponent("fueled")
    inst.components.fueled.accepting = true
    inst.components.fueled.bonusmult = TUNING.FIREPIT_BONUS_MULT
	inst.components.fueled.fueltype = FUELTYPE.CAVE
    inst.components.fueled.ontakefuelfn = ontakefuel
    inst.components.fueled:SetUpdateFn(onupdatefueled)
	inst.components.fueled:SetSectionCallback(sectioncallback)
    inst.components.fueled:InitializeFuelLevel(TUNING.TORCH_FUEL * 3)
    inst.components.fueled:SetDepletedFn(inst.Remove)

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

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

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

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

    MakeHauntableLaunch(inst)

    return inst
end

return Prefab( "common/inventory/greent", fn, assets, prefabs)
