local StateMachine = class("StateMachine")

function StateMachine:ctor()
    self.stateMap = {}
    self.active = false
    self.curStateKey = nil
    self.curState = nil
end

---- 获取是否active
function StateMachine:getIsActive()
    return self.active
end

---- 获取当前state StateInterface
function StateMachine:getCurState()
    return self.curState
end

---- 获取当前state对应的key
function StateMachine:getCurStateKey()
    return self.curStateKey
end

---- 获取state
function StateMachine:getStateByKey(key)
    return self.stateMap[key]
end

---- 注册一个state
function StateMachine:registerState(stateKey, state)
    if self.stateMap[stateKey] then
        Logger.logWarning("StateMachine registerState: state machine already have state %s", stateKey)
        return
    end
    self.stateMap[stateKey] = state
end

---- 改变状态
function StateMachine:changeState(stateKey, params)
    if not self.active then
        Logger.logWarning("StateMachine changeState: state machine not active")
        return
    end
    local newState = self.stateMap[stateKey]
    if newState then
        self.curState:exit()
        self.curState = newState
        self.curStateKey = stateKey
        self.curState:enter(params)
    else
        Logger.logWarning("StateMachine changeState: state machine no such state %s", stateKey)
    end
end

---- start状态机
function StateMachine:start(stateKey, params)
    if self.active then
        return
    end
    local newState = self.stateMap[stateKey]
    if newState then
        self.curState = newState
        self.curState:enter(params)
        self.curStateKey = stateKey
        self.active = true
    else
        Logger.logWarning("StateMachine start: state machine no such state %s", stateKey)
    end
end

---- 重新开始状态机
function StateMachine:restart(stateKey, params)
    local newState = self.stateMap[stateKey]
    if newState then
        if self.active then
            self.curState:exit()
        end
        self.curState = newState
        self.curStateKey = stateKey
        self.curState:enter(params)
        self.active = true
    else
        Logger.logWarning("StateMachine restart: state machine no such state %s", stateKey)
    end
end

---- 停止状态机
function StateMachine:stop()
    if not self.active then
        return
    end
    self.curState:exit()
    self.curState = nil
    self.curStateKey = nil
    self.active = false
    for _, state in pairs(self.stateMap) do
        state:clear()
    end
end

---- 每帧tick当前状态
function StateMachine:tick()
    if self.active then
        self.curState:tick()
    end
end

return StateMachine