#ifndef MWLUA_PLAYERSCRIPTS_H
#define MWLUA_PLAYERSCRIPTS_H

#include <SDL_events.h>

#include <components/sdlutil/events.hpp>

#include "../mwbase/luamanager.hpp"

#include "localscripts.hpp"

namespace MWLua
{

    class PlayerScripts : public LocalScripts
    {
    public:
        PlayerScripts(LuaUtil::LuaState* lua, const LObject& obj)
            : LocalScripts(lua, obj)
        {
            registerEngineHandlers({ &mConsoleCommandHandlers, &mKeyPressHandlers, &mKeyReleaseHandlers,
                &mControllerButtonPressHandlers, &mControllerButtonReleaseHandlers, &mActionHandlers, &mOnFrameHandlers,
                &mTouchpadPressed, &mTouchpadReleased, &mTouchpadMoved });
        }

        void processInputEvent(const MWBase::LuaManager::InputEvent& event)
        {
            using InputEvent = MWBase::LuaManager::InputEvent;
            switch (event.mType)
            {
                case InputEvent::KeyPressed:
                    callEngineHandlers(mKeyPressHandlers, std::get<SDL_Keysym>(event.mValue));
                    break;
                case InputEvent::KeyReleased:
                    callEngineHandlers(mKeyReleaseHandlers, std::get<SDL_Keysym>(event.mValue));
                    break;
                case InputEvent::ControllerPressed:
                    callEngineHandlers(mControllerButtonPressHandlers, std::get<int>(event.mValue));
                    break;
                case InputEvent::ControllerReleased:
                    callEngineHandlers(mControllerButtonReleaseHandlers, std::get<int>(event.mValue));
                    break;
                case InputEvent::Action:
                    callEngineHandlers(mActionHandlers, std::get<int>(event.mValue));
                    break;
                case InputEvent::TouchPressed:
                    callEngineHandlers(mTouchpadPressed, std::get<SDLUtil::TouchEvent>(event.mValue));
                    break;
                case InputEvent::TouchReleased:
                    callEngineHandlers(mTouchpadReleased, std::get<SDLUtil::TouchEvent>(event.mValue));
                    break;
                case InputEvent::TouchMoved:
                    callEngineHandlers(mTouchpadMoved, std::get<SDLUtil::TouchEvent>(event.mValue));
                    break;
            }
        }

        void onFrame(float dt) { callEngineHandlers(mOnFrameHandlers, dt); }

        bool consoleCommand(
            const std::string& consoleMode, const std::string& command, const sol::object& selectedObject)
        {
            callEngineHandlers(mConsoleCommandHandlers, consoleMode, command, selectedObject);
            return !mConsoleCommandHandlers.mList.empty();
        }

    private:
        EngineHandlerList mConsoleCommandHandlers{ "onConsoleCommand" };
        EngineHandlerList mKeyPressHandlers{ "onKeyPress" };
        EngineHandlerList mKeyReleaseHandlers{ "onKeyRelease" };
        EngineHandlerList mControllerButtonPressHandlers{ "onControllerButtonPress" };
        EngineHandlerList mControllerButtonReleaseHandlers{ "onControllerButtonRelease" };
        EngineHandlerList mActionHandlers{ "onInputAction" };
        EngineHandlerList mOnFrameHandlers{ "onFrame" };
        EngineHandlerList mTouchpadPressed{ "onTouchPress" };
        EngineHandlerList mTouchpadReleased{ "onTouchRelease" };
        EngineHandlerList mTouchpadMoved{ "onTouchMove" };
    };

}

#endif // MWLUA_PLAYERSCRIPTS_H
