local assets =
{
    Asset("ANIM", "anim/cherry_tree_white.zip"),
    
	Asset("ATLAS", "images/map_icons/cherry_tree_white.xml"),
    Asset("IMAGE", "images/map_icons/cherry_tree_white.tex"),
	
	Asset("ATLAS", "images/map_icons/cherry_tree_stump.xml"),
    Asset("IMAGE", "images/map_icons/cherry_tree_stump.tex"),
	
	Asset("ATLAS", "images/map_icons/cherry_tree_burnt.xml"),
    Asset("IMAGE", "images/map_icons/cherry_tree_burnt.tex"),
	
	Asset("SOUND", "sound/forest.fsb"),
}

local prefabs =
{
    "log",
    "petals",
    "charcoal",
	"fruitbat",
}

SetSharedLootTable( 'cherry2',
{
    {'log',  1.00},
    {'log',  1.00},
    {'log',  1.00},
    {'log',  0.50},
    {'log',  0.25},
    {'petals',  1},
    {'petals',  1},
	{'petals',  0.50},
	{'petals',  0.50},
	{'fruitbat',  0.50},
	{'fruitbat',  0.25},
	{'fruitbat',  0.25},
	
})

local leaves_assets =
{
    Asset("ANIM", "anim/cherry_leaves.zip"),
}

local NUM_LEAVES_TYPES = 3

local function makeleaves(leavestype)
    local function fn()
        local inst = CreateEntity()

        inst.entity:AddTransform()
        inst.entity:AddAnimState()
		inst.entity:AddSoundEmitter()
        inst.entity:AddNetwork()

        inst.AnimState:SetBank("cherry_leaves")
        inst.AnimState:SetBuild("cherry_leaves")
        inst.AnimState:PlayAnimation("f"..leavestype)
		inst.AnimState:SetOrientation(ANIM_ORIENTATION.OnGround)
		inst.AnimState:SetLayer(LAYER_BACKGROUND)
		inst.AnimState:SetSortOrder(3)

		inst:SetDeployExtraSpacing(2)

        if leavestype:len() > 0 then
            inst:SetPrefabNameOverride("cherry_leaves")
        end

        inst.entity:SetPristine()

        if not TheWorld.ismastersim then
            return inst
        end
		
		inst:AddTag("FX")

        return inst
    end
    return Prefab("cherry_leaves"..leavestype, fn, leaves_assets)
end

local function SpawnLeaves(inst)
    inst.task = nil
    if inst.leaves == nil then
        inst.leaves = {}
        for i = 0, math.random(3, 8) do
            local theta = math.random() * 5 * PI
            local leavestype = math.random(NUM_LEAVES_TYPES)
            table.insert(inst.leaves,
            {
                leavestype = leavestype > TUNING.CHERRYPETALS and tostring(leavestype) or "",
                offset =
                {
                    math.sin(theta) * 3.3 + math.random() * .5,
                    0,
                    math.cos(theta) * 3.3 + math.random() * .5,
                },
            })
        end
    end
    for i, v in ipairs(inst.leaves) do
        if type(v.leavestype) == "string" and type(v.offset) == "table" and #v.offset == 3 then
            local leaves = SpawnPrefab("cherry_leaves"..v.leavestype)
            if leaves ~= nil then
                leaves.entity:SetParent(inst.entity)
                leaves.Transform:SetPosition(unpack(v.offset))
                leaves.persists = false
            end
        end
    end
end

local function chop_tree(inst, chopper, chops)
    if not (chopper ~= nil and chopper:HasTag("playerghost")) then
        inst.SoundEmitter:PlaySound("dontstarve/wilson/use_axe_tree")
    end
    inst.AnimState:PlayAnimation("chop")
	inst.AnimState:PushAnimation("idle")
end

local function set_stump(inst)
    inst:RemoveComponent("workable")
    inst:RemoveComponent("burnable")
    inst:RemoveComponent("propagator")
    inst:RemoveComponent("hauntable")
    if not inst:HasTag("burnt") then
        MakeSmallBurnable(inst)
        MakeSmallPropagator(inst)
        MakeHauntableIgnite(inst)
    end
    RemovePhysicsColliders(inst)
    inst:AddTag("stump")
    inst.MiniMapEntity:SetIcon( "cherry_tree_stump.tex" )
end

local function dig_up_stump(inst, chopper)
    inst.components.lootdropper:SpawnLootPrefab("log")
    inst:Remove()
end

local function chop_down_tree(inst, chopper)
    inst.SoundEmitter:PlaySound("dontstarve/forest/treeCrumble")
    if not (chopper ~= nil and chopper:HasTag("playerghost")) then
        inst.SoundEmitter:PlaySound("dontstarve/wilson/use_axe_tree")
    end
    inst.AnimState:PlayAnimation("fall")
    inst.AnimState:PushAnimation("stump", false)
    set_stump(inst)
    inst.components.lootdropper:DropLoot()
	
	inst:AddTag("stump")

    inst:AddComponent("workable")
    inst.components.workable:SetWorkAction(ACTIONS.DIG)
    inst.components.workable:SetOnFinishCallback(dig_up_stump)
    inst.components.workable:SetWorkLeft(1)
end

local function chop_down_burnt_tree(inst, chopper)
    inst.SoundEmitter:PlaySound("dontstarve/forest/treeCrumble")
    if not (chopper ~= nil and chopper:HasTag("playerghost")) then
        inst.SoundEmitter:PlaySound("dontstarve/wilson/use_axe_tree")
    end
    inst.AnimState:PlayAnimation("burnt_chop")
    set_stump(inst)
    RemovePhysicsColliders(inst)
    inst:ListenForEvent("animover", inst.Remove)
	inst.components.lootdropper:SpawnLootPrefab("charcoal")
end

local function OnBurnt(inst)
    inst:RemoveComponent("burnable")
    inst:RemoveComponent("propagator")
    inst:RemoveComponent("hauntable")
    MakeHauntableWork(inst)

    inst.components.lootdropper:SetLoot({"charcoal"})

    inst.components.workable:SetWorkLeft(1)
    inst.components.workable:SetOnWorkCallback(nil)
    inst.components.workable:SetOnFinishCallback(chop_down_burnt_tree)
    inst.AnimState:PlayAnimation("burnt_idle", true)
    inst:AddTag("burnt")
    inst.MiniMapEntity:SetIcon( "cherry_tree_burnt.tex" )
end

local function inspect_tree(inst)
    return (inst:HasTag("burnt") and "BURNT")
        or (inst:HasTag("stump") and "CHOPPED")
        or (inst.components.burnable ~= nil and
            inst.components.burnable:IsBurning() and
            "BURNING")
        or nil
end

local function handler_growfromseed(inst)
    inst.SoundEmitter:PlaySound("dontstarve/forest/treeGrow")
end

local function onsave(inst, data)
    if inst:HasTag("burnt") or (inst.components.burnable ~= nil and inst.components.burnable:IsBurning()) then
        data.burnt = true
    end
    if inst:HasTag("stump") then
        data.stump = true
    end
end

local function onload(inst, data)
    if data ~= nil then
        if data.stump then
            set_stump(inst)
            inst.AnimState:PlayAnimation("stump", false)
            if data.burnt or inst:HasTag("burnt") then
                DefaultBurntFn(inst)
            else
                inst:AddComponent("workable")
                inst.components.workable:SetWorkAction(ACTIONS.DIG)
                inst.components.workable:SetOnFinishCallback(dig_up_stump)
                inst.components.workable:SetWorkLeft(1)
            end
        elseif data.burnt and not inst:HasTag("burnt") then
            OnBurnt(inst)
        end
    end
end

local function ReturnChildren(inst)
	for k,child in pairs(inst.components.childspawner.childrenoutside) do
		if child.components.homeseeker then
			child.components.homeseeker:GoHome()
		end
		child:PushEvent("gohome")
	end
end

local function onnear(inst)
    if inst.components.childspawner.childreninside >= inst.components.childspawner.maxchildren then
        local tries = 10
        while inst.components.childspawner:CanSpawn() and tries > 0 do
            local bat = inst.components.childspawner:SpawnChild()
            if bat ~= nil then
                bat:DoTaskInTime(0, function() bat:PushEvent("panic") end)
            end
            tries = tries - 1
        end
        inst.SoundEmitter:PlaySound("dontstarve/cave/bat_cave_explosion")
    end
end

local function onaddchild( inst, count )
    if inst.components.childspawner.childreninside == inst.components.childspawner.maxchildren then
        inst.SoundEmitter:PlaySound("dontstarve/cave/bat_cave_warning", "full")
    end
end

local function onspawnchild( inst, child )
    inst.SoundEmitter:KillSound("full")
end

local function OnEntityWake(inst)
    if inst.components.childspawner.childreninside == inst.components.childspawner.maxchildren then
        inst.AnimState:PlayAnimation("eyes",true)
        inst.SoundEmitter:PlaySound("dontstarve/cave/bat_cave_warning", "full")
    end
end

local function OnEntitySleep(inst)
    inst.SoundEmitter:KillSound("full")
end

local function onisday(inst, isday)
    if isday then
        inst.components.childspawner:StopSpawning()
    else
        inst.components.childspawner:StartSpawning()
    end
end

local function fn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
    inst.entity:AddAnimState()
    inst.entity:AddDynamicShadow()
    inst.entity:AddSoundEmitter()
    inst.entity:AddMiniMapEntity()
    inst.entity:AddNetwork()

    MakeObstaclePhysics(inst, .25)
	
	inst.Transform:SetScale(TUNING.CHERRYTREE_SIZE, TUNING.CHERRYTREE_SIZE, TUNING.CHERRYTREE_SIZE)

    inst.MiniMapEntity:SetIcon( "cherry_tree_white.tex" )

    inst:AddTag("tree")
	inst:AddTag("shelter")

    inst.AnimState:SetBuild("cherry_tree_white")
    inst.AnimState:SetBank("cherry_tree_white")
	inst.AnimState:PlayAnimation("idle", true)

    MakeSnowCoveredPristine(inst)

    inst.entity:SetPristine()

    if not TheWorld.ismastersim then
        return inst
    end

    MakeLargeBurnable(inst)
    inst.components.burnable:SetOnBurntFn(OnBurnt)
    MakeSmallPropagator(inst)

    inst:AddComponent("lootdropper") 
	inst.components.lootdropper:SetChanceLootTable('cherry2')

    inst:AddComponent("workable")
    inst.components.workable:SetWorkAction(ACTIONS.CHOP)
    inst.components.workable:SetWorkLeft(20)
    inst.components.workable:SetOnWorkCallback(chop_tree)
    inst.components.workable:SetOnFinishCallback(chop_down_tree)
	
	inst:AddComponent("childspawner")
	inst.components.childspawner:SetRegenPeriod(120)
	inst.components.childspawner:SetSpawnPeriod(120)
	inst.components.childspawner:SetMaxChildren(TUNING.CHERRYLING_CANSPAWN)
	inst.components.childspawner.childname = "fruitbat"
    inst.components.childspawner:StartSpawning()
    inst.components.childspawner:StartRegen()
    inst.components.childspawner:SetOnAddChildFn( onaddchild )
    inst.components.childspawner:SetSpawnedFn( onspawnchild )
    inst.components.childspawner.childreninside = 0

	inst.growfromseed = handler_growfromseed

    MakeHauntableWorkAndIgnite(inst)

    local color = 0.5 + math.random() * 0.5
    inst.AnimState:SetMultColour(color, color, color, 1)
    inst.AnimState:SetTime(math.random()*2)

    inst:AddComponent("inspectable")
    inst.components.inspectable.getstatus = inspect_tree
	
	onisday(inst, TheWorld.state.iscaveday)
    inst:WatchWorldState("iscaveday", onisday)

    inst.OnSave = onsave
    inst.OnLoad = onload
    MakeSnowCovered(inst)

    return inst
end

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