local WALK_SPEED = 4
local RUN_SPEED = 7

require("stategraphs/commonstates")

local actionhandlers = 
{
    ActionHandler(ACTIONS.PICK, "eat"),
    ActionHandler(ACTIONS.GOHOME, "action"),
}

local events=
{
    CommonHandlers.OnSleep(),
    CommonHandlers.OnFreeze(),
    EventHandler("attacked", function(inst) if inst.components.health:GetPercent() > 0 then inst.sg:GoToState("hit") end end),
    EventHandler("death", function(inst) inst.sg:GoToState("death") end),
    EventHandler("trapped", function(inst) inst.sg:GoToState("trapped") end),
    EventHandler("locomote", 
        function(inst) 
            if not inst.sg:HasStateTag("idle") and not inst.sg:HasStateTag("moving") then return end
            
            if not inst.components.locomotor:WantsToMoveForward() then
                if not inst.sg:HasStateTag("idle") then
                    if not inst.sg:HasStateTag("running") then
                        inst.sg:GoToState("idle")
                    end
                        inst.sg:GoToState("idle")
                end
            elseif inst.components.locomotor:WantsToRun() then
                if not inst.sg:HasStateTag("running") then
                    inst.sg:GoToState("run")
                end
            else
                if not inst.sg:HasStateTag("hopping") then
                    inst.sg:GoToState("hop")
                end
            end
        end),
}

local states=
{
 
    State{
        name = "look",
        tags = {"idle", "canrotate" },
        onenter = function(inst)
            
            if math.random() > .5 then
                inst.AnimState:PlayAnimation("lookup_pre")
                inst.AnimState:PushAnimation("lookup_loop", true)
                inst.AnimState:PushAnimation("lookup_pst", false)
            else
                inst.AnimState:PlayAnimation("lookdown_pre")
                inst.AnimState:PushAnimation("lookdown_loop", true)
                inst.AnimState:PushAnimation("lookdown_pst", false)
            end
        end,
        
        events=
        {
            EventHandler("animqueueover", function (inst)
                    inst.sg:GoToState("idle")
            end),
        }
    },

    State{
        name = "sing",
        onenter = function(inst)
                	inst.Physics:Stop()
            	inst:RemoveTag("dosong")
                inst.AnimState:PlayAnimation("lookdown_pre")
                inst.AnimState:PushAnimation("lookdown_pst", false)
                inst.AnimState:PushAnimation("lookdown_pre", false)
                inst.AnimState:PushAnimation("lookdown_pst", false)
		inst.SoundEmitter:PlaySound("dontstarve/creatures/bishop/voice")
                inst.SoundEmitter:PlaySound("dontstarve/wilson/flute_LP", "sing")
    inst.AnimState:Hide("eye")
		SpawnPrefab("warfarinheart").Transform:SetPosition(inst:GetPosition():Get())
			local pos = Vector3(inst.Transform:GetWorldPosition())
			pos.y = pos.y + 0.5 + math.random()*0.5
			pos.x = pos.x - 1 + math.random()*1.5
			local note = SpawnPrefab("warfarin_faithesong")
			note.Transform:SetPosition(pos:Get())
		if inst.components.follower.leader == GetPlayer() then
		GetPlayer().components.sanity:DoDelta(1)
		end
        end,
       
        onexit = function(inst)
                inst.SoundEmitter:KillSound("sing")
    inst.AnimState:Show("eye")
        end,
 
        events=
        {
            EventHandler("animqueueover", function(inst)
                if math.random() < .3 then
                    inst.sg:GoToState("sing")
                else
                    inst.sg:GoToState("idle")
                end
            end),
        },

        timeline=
        {
   
            TimeEvent(12*FRAMES, function(inst) 
			local pos = Vector3(inst.Transform:GetWorldPosition())
			pos.y = pos.y + 0.5 + math.random()*0.5
			pos.x = pos.x - 1 + math.random()*1.5
			local note = SpawnPrefab("warfarin_faithesong")
			note.Transform:SetPosition(pos:Get())
		if inst.components.follower.leader == GetPlayer() then
		GetPlayer().components.sanity:DoDelta(1)
		end
			end),
            TimeEvent(24*FRAMES, function(inst) 
			local pos = Vector3(inst.Transform:GetWorldPosition())
			pos.y = pos.y + 0.5 + math.random()*0.5
			pos.x = pos.x - 1 + math.random()*1.5
			local note = SpawnPrefab("warfarin_faithesong")
			note.Transform:SetPosition(pos:Get())
		if inst.components.follower.leader == GetPlayer() then
		GetPlayer().components.sanity:DoDelta(1)
		end
			end),
        }, 
    },

    State{
        
        name = "idle",
        tags = {"idle", "canrotate"},
        onenter = function(inst)
            inst.Physics:Stop()
                inst.AnimState:PlayAnimation("idle", true)                           
            inst.sg:SetTimeout(4 + math.random()*2)
        end,
        
        ontimeout= function(inst)
                if math.random() < .6 and inst:HasTag("dosong") then
                    inst.sg:GoToState("sing")
                else
                    inst.sg:GoToState("look")
                end
        end,
},
    
    State{
        
        name = "action",
        onenter = function(inst, playanim)
            inst.Physics:Stop()
            inst.AnimState:PlayAnimation("idle")
            inst:PerformBufferedAction()
        end,
        events=
        {
            EventHandler("animover", function (inst, data) inst.sg:GoToState("idle") end),
        }
    },    
    
    State{
        name = "open",
        tags = {"busy", "open"},
        
        onenter = function(inst)
            inst.Physics:Stop()
            inst.AnimState:PlayAnimation("sleep_pre")
		inst.AnimState:SetBuild("faithe_buildo")
		inst.SoundEmitter:PlaySound("dontstarve/wilson/backpack_open")
        end,

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

    State{
        name = "open_idle",
        tags = {"busy", "open"},
        
        onenter = function(inst)
            inst.AnimState:PlayAnimation("sleep_loop", true)
            
        end,

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

    State{
        name = "close",
        tags = {""},
        
        onenter = function(inst)
            inst.AnimState:PlayAnimation("sleep_pst")
		inst.SoundEmitter:PlaySound("dontstarve/wilson/backpack_close")
		inst.AnimState:SetBuild("faithe_build")
        end,

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

    State{
        name = "eat",
        
        onenter = function(inst)
            inst.Physics:Stop()
            inst.AnimState:PlayAnimation("rabbit_eat_pre", false)
            inst.AnimState:PushAnimation("rabbit_eat_loop", true)
            inst.sg:SetTimeout(2+math.random()*4)
        end,
        
        ontimeout= function(inst)
            inst:PerformBufferedAction()
            inst.sg:GoToState("open_idle", "rabbit_eat_pst")
        end,
    },    

    State{
        name = "hop",
        tags = {"moving", "canrotate", "hopping"},
        
        timeline=
        {
            TimeEvent(5*FRAMES, function(inst) 
                inst.Physics:Stop() 
                inst.SoundEmitter:PlaySound("dontstarve/rabbit/hop")
            end ),
        },
        
        onenter = function(inst) 
            inst.AnimState:PlayAnimation("walk")
            inst.components.locomotor:WalkForward()
            inst.sg:SetTimeout(2*math.random()+.5)
        end,
        
        onupdate= function(inst)
            if not inst.components.locomotor:WantsToMoveForward() then
                inst.sg:GoToState("idle")
            end
        end,        
        
        ontimeout= function(inst)
            inst.sg:GoToState("hop")
        end,
    },
    
    State{
        name = "run",
        tags = {"moving", "running", "canrotate"},
        
        onenter = function(inst) 
            inst.AnimState:PlayAnimation("run_pre")
            inst.AnimState:PushAnimation("run", true)
            inst.components.locomotor:RunForward()
        end,
        
        --[[onupdate= function(inst)
            if not inst.components.locomotor:WantsToMoveForward() then
                inst.sg:GoToState("idle")
            end
        end, --]]       
        
    },    
    
    State{
        name = "death",
        tags = {"busy"},
        
        onenter = function(inst)
            inst.components.container:Close()
            inst.components.container:DropEverything()
            inst.AnimState:PlayAnimation("death")
            inst.Physics:Stop()
            RemovePhysicsColliders(inst)
        inst.SoundEmitter:PlaySound("dontstarve/rabbit/beardscream")
		inst.SoundEmitter:PlaySound("dontstarve/creatures/bishop/voice")            
        end,
        events =
        {
            EventHandler("animover", function(inst)
                inst.sg:GoToState("transform_pst")
                inst:DoTaskInTime(1, function() 
        inst.SoundEmitter:PlaySound("dontstarve/maxwell/shadowmax_appear")
        inst.SoundEmitter:PlaySound("dontstarve/charlie/attack")   
	SpawnPrefab("statue_transition").Transform:SetPosition(inst:GetPosition():Get())
	SpawnPrefab("statue_transition_2").Transform:SetPosition(inst:GetPosition():Get())
                    inst:Remove()
                end)
            end ),
        },
    },   
    
    State{
        name = "stunned",
        tags = {"busy"},
        
        onenter = function(inst) 
            inst.Physics:Stop()
            inst.AnimState:PlayAnimation("stunned_loop", true)
            inst.sg:SetTimeout(GetRandomWithVariance(6, 2) )
            if inst.components.inventoryitem then
                inst.components.inventoryitem.canbepickedup = true
            end
        end,
        
        onexit = function(inst)
            if inst.components.inventoryitem then
                inst.components.inventoryitem.canbepickedup = false
            end
        end,
        
        ontimeout = function(inst) inst.sg:GoToState("idle") end,
    },
    
    State{
        name = "trapped",
        tags = {"busy", "trapped"},
        
        onenter = function(inst) 
            inst.Physics:Stop()
			inst:ClearBufferedAction()
            inst.AnimState:PlayAnimation("stunned_loop", true)
            inst.sg:SetTimeout(1)
        end,
        
        ontimeout = function(inst) inst.sg:GoToState("idle") end,
    },
    State{
        name = "hit",
        tags = {"busy"},
        
        onenter = function(inst)
            inst.AnimState:PlayAnimation("hit")
            inst.Physics:Stop()     
	inst.SoundEmitter:PlaySound("dontstarve/creatures/bishop/hurt")   
        inst.SoundEmitter:PlaySound("dontstarve/rabbit/beardscream_short")
		inst.SoundEmitter:PlaySound("dontstarve/creatures/bishop/voice")   
        end,
        
        events=
        {
            EventHandler("animover", function(inst) inst.sg:GoToState("idle") end ),
        },        
    },    

}
CommonStates.AddSleepStates(states)
CommonStates.AddFrozenStates(states)

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

