#ifndef QRK_SCRIPTED_STATE_MACHINE_H
#define QRK_SCRIPTED_STATE_MACHINE_H

/*!
  \file
  \brief スクリプト駆動の状態遷移用テンプレート

  「ゲーム AI プログラミング」より

  \author Satofumi KAMIMURA

  $Id: ScriptedStateMachine.h 1414 2009-10-14 23:14:02Z satofumi $
*/

#include <luabind/luabind.hpp>
#include <stack>


namespace qrk
{
  template <class T>
  class ScriptedStateMachine
  {
  public:
    ScriptedStateMachine(T* owner) : owner_(owner)
    {
    }


    void setCurrentState(const luabind::object& state)
    {
      current_state_ = state;
    }


    void update()
    {
      if (current_state_.is_valid()) {
        current_state_["Execute"](owner_);
      }
    }


    void changeState(const luabind::object& next_state)
    {
      if (current_state_) {
        current_state_["Exit"](owner_);
      }

      state_stack_.push(current_state_);
      current_state_ = next_state;
      current_state_["Enter"](owner_);
    }


    void changePreviousState(void)
    {
      if (state_stack_.empty()) {
        return;
      }

      changeState(state_stack_.top());

      // 元からあった状態と changeState() で追加した状態の２つを取り除く
      state_stack_.pop();
      state_stack_.pop();
    }


    const luabind::object& currentState(void) const
    {
      return current_state_;
    }

  private:
    T* owner_;
    luabind::object current_state_;
    std::stack<luabind::object> state_stack_;
  };
}

#endif /* !QRK_SCRIPTED_STATE_MACHINE_H */
