require("stategraphs/commonstates")

local actionhandlers =
{
    -- ActionHandler(ACTIONS.INVESTIGATE, "investigate"),
}

local events =
{
    EventHandler("attacked", function(inst)
        if not inst.components.health:IsDead() then
			if math.random() < 0.25 then
				inst.sg:GoToState("hit")
			end
        end
    end),
    EventHandler("doattack", function(inst, data) 
        if not (inst.sg:HasStateTag("busy") or inst.components.health:IsDead()) then
            --target CAN go invalid because SG events are buffered
            inst.sg:GoToState("attack", data.target)
        end
    end),
    EventHandler("death", function(inst) inst.sg:GoToState("death") end),
    -- CommonHandlers.OnSleep(),
    CommonHandlers.OnFreeze(),

    EventHandler("locomote", function(inst) 
        if not inst.sg:HasStateTag("busy") then
            local is_moving = inst.sg:HasStateTag("moving")
            local wants_to_move = inst.components.locomotor:WantsToMoveForward()
            if not inst.sg:HasStateTag("attack") and is_moving ~= wants_to_move then
                if wants_to_move and (inst.components.follower and inst.components.follower.leader == nil or not inst.components.follower) then
                    inst.sg:GoToState("moving")
				elseif wants_to_move and inst.components.follower and inst.components.follower.leader ~= nil then
					inst.sg:GoToState("run")
                else
                    inst.sg:GoToState("idle")
                end
            end
        end
    end),
}

local states =
{
    State{
        name = "death",
        tags = {"busy"},

        onenter = function(inst)
            inst.AnimState:PlayAnimation("death")
			inst.SoundEmitter:PlaySound("miningmachine/mobs/skeleton/death")
            inst.Physics:Stop()
            RemovePhysicsColliders(inst)
            inst.components.lootdropper:DropLoot(Vector3(inst.Transform:GetWorldPosition()))            
        end,
    },

    State{
        name = "moving",
        tags = {"moving", "canrotate"},

        onenter = function(inst)
            inst.components.locomotor:RunForward()
            inst.AnimState:PlayAnimation("walk")
			inst.SoundEmitter:PlaySound("miningmachine/mobs/skeleton/walk", "walk_rattle")
        end,

        events=
        {
            EventHandler("animover", function(inst) inst.sg:GoToState("moving") end),
        },
    },
	
	State{
        name = "run",
        tags = {"moving", "canrotate" , "run"},

        onenter = function(inst)
            inst.components.locomotor:RunForward()
            inst.AnimState:PlayAnimation("run")
			inst.SoundEmitter:PlaySound("miningmachine/mobs/skeleton/walk", "walk_rattle")
        end,

        events=
        {
            EventHandler("animover", function(inst) inst.sg:GoToState("run") end),
        },
    },

    State{
        name = "idle",
        tags = {"idle", "canrotate"},

        ontimeout = function(inst)
            inst.sg:GoToState("idle")
        end,

        onenter = function(inst, start_anim)
			inst.SoundEmitter:KillSound("walk_rattle")
            inst.Physics:Stop()
            local animname = "idle"
            if math.random() < .3 then
                inst.sg:SetTimeout(math.random()*2 + 2)
            end

            if start_anim then
                inst.AnimState:PlayAnimation(start_anim)
                inst.AnimState:PushAnimation("idle", true)
            else
                inst.AnimState:PlayAnimation("idle", true)
            end
        end,
    },

    -- State{
        -- name = "taunt",
        -- tags = {"busy"},

        -- onenter = function(inst)
            -- inst.Physics:Stop()
            -- inst.AnimState:PlayAnimation("taunt")
            -- inst.SoundEmitter:PlaySound(SoundPath(inst, "scream"))
        -- end,

        -- events=
        -- {
            -- EventHandler("animover", function(inst) inst.sg:GoToState("idle") end),
        -- },
    -- },    

    -- State{
        -- name = "investigate",
        -- tags = {"busy"},

        -- onenter = function(inst)
            -- inst.Physics:Stop()
            -- inst.AnimState:PlayAnimation("taunt")
            -- inst.SoundEmitter:PlaySound(SoundPath(inst, "scream"))
        -- end,

        -- events=
        -- {
            -- EventHandler("animover", function(inst)
                -- inst:PerformBufferedAction()
                -- inst.sg:GoToState("idle")
            -- end),
        -- },
    -- },

    State{
        name = "attack",
        tags = {"attack", "busy"},

        onenter = function(inst, target)
            inst.Physics:Stop()
            inst.components.combat:StartAttack()
            inst.AnimState:PlayAnimation("attack")
            inst.sg.statemem.target = target
        end,

        timeline=
        {
            TimeEvent(16*FRAMES, function(inst) 
									inst.components.combat:DoAttack(inst.sg.statemem.target) 
									if inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS) ~= nil then
										inst.SoundEmitter:PlaySound("miningmachine/mobs/skeleton/attack_range")
									else
										inst.SoundEmitter:PlaySound("miningmachine/mobs/skeleton/attack_melee")
									end
								end
			),
        },

        events=
        {
            EventHandler("animover", function(inst) 
										inst.sg:GoToState("idle") 
										inst.components.inventory:Unequip(EQUIPSLOTS.HANDS)
									end
			),
        },
    },

    State{
        name = "hit",

        onenter = function(inst)
            inst.AnimState:PlayAnimation("hit")
			inst.SoundEmitter:PlaySound("miningmachine/mobs/skeleton/hit")
            inst.Physics:Stop()            
        end,

        events=
        {
            EventHandler("animover", function(inst) inst.sg:GoToState("idle") end ),
        },
    },

    State{
        name = "hit_stunlock",
        tags = {"busy"},

        onenter = function(inst)
            inst.AnimState:PlayAnimation("hit")
			inst.SoundEmitter:PlaySound("miningmachine/mobs/skeleton/hit")
            inst.Physics:Stop()
        end,

        events=
        {
            EventHandler("animover", function(inst) inst.sg:GoToState("idle") end ),
        },
    },
}

-- CommonStates.AddSleepStates(states,
-- {
    -- starttimeline = {
        -- TimeEvent(0*FRAMES, function(inst) inst.SoundEmitter:PlaySound(SoundPath(inst, "fallAsleep")) end ),
    -- },
    -- sleeptimeline = 
    -- {
        -- TimeEvent(35*FRAMES, function(inst) inst.SoundEmitter:PlaySound(SoundPath(inst, "sleeping")) end ),
    -- },
    -- waketimeline = {
        -- TimeEvent(0*FRAMES, function(inst) inst.SoundEmitter:PlaySound(SoundPath(inst, "wakeUp")) end ),
    -- },
-- })

CommonStates.AddFrozenStates(states)

return StateGraph("wonkyskeleton", states, events, "idle", actionhandlers)
