#include "doomlib.hpp"
#include "dp_doom/linuxdoom-1.10/doomdef.h"

// Taken from ib_video_sdl.c
static int xlatekey(SDL_Keycode keysym)
{
    int rc;

    switch(rc = keysym)
    {
      case SDLK_LEFT:	rc = KEY_LEFTARROW;	break;
      case SDLK_RIGHT:	rc = KEY_RIGHTARROW;	break;
      case SDLK_DOWN:	rc = KEY_DOWNARROW;	break;
      case SDLK_UP:	rc = KEY_UPARROW;	break;
      case SDLK_ESCAPE:	rc = KEY_ESCAPE;	break;
      case SDLK_RETURN:	rc = KEY_ENTER;		break;
      case SDLK_TAB:	rc = KEY_TAB;		break;
      case SDLK_F1:	rc = KEY_F1;		break;
      case SDLK_F2:	rc = KEY_F2;		break;
      case SDLK_F3:	rc = KEY_F3;		break;
      case SDLK_F4:	rc = KEY_F4;		break;
      case SDLK_F5:	rc = KEY_F5;		break;
      case SDLK_F6:	rc = KEY_F6;		break;
      case SDLK_F7:	rc = KEY_F7;		break;
      case SDLK_F8:	rc = KEY_F8;		break;
      case SDLK_F9:	rc = KEY_F9;		break;
      case SDLK_F10:	rc = KEY_F10;		break;
      case SDLK_F11:	rc = KEY_F11;		break;
      case SDLK_F12:	rc = KEY_F12;		break;

      case SDLK_BACKSPACE:
      case SDLK_DELETE:	rc = KEY_BACKSPACE;	break;

      case SDLK_PAUSE:	rc = KEY_PAUSE;		break;

      case SDLK_KP_EQUALS:
      case SDLK_EQUALS:	rc = KEY_EQUALS;	break;

      case SDLK_KP_MINUS:
      case SDLK_MINUS:	rc = KEY_MINUS;		break;

      case SDLK_LSHIFT:
      case SDLK_RSHIFT:
	rc = KEY_RSHIFT;
	break;

      case SDLK_LCTRL:
      case SDLK_RCTRL:
	rc = KEY_RCTRL;
	break;

      case SDLK_LALT:
      case SDLK_RALT:
#if SDL_MAJOR_VERSION >= 2
      case SDLK_LGUI:
      case SDLK_RGUI:
#else
      case SDLK_LMETA:
      case SDLK_RMETA:
#endif
	rc = KEY_RALT;
	break;

      default:
	if (rc >= SDLK_SPACE && rc <= SDLK_BACKQUOTE)
	    rc = rc - SDLK_SPACE + ' ';
	else if (rc >= 'A' && rc <= 'Z')
	    rc = rc - 'A' + 'a';
	break;
    }

    return rc;
}

// Similar to IB_StartTic from ib_video_sdl.c
std::optional<dp_doom_event_t> doomevent_from_sdlevent(const SDL_Event &sdl_event)
{
    dp_doom_event_t event;
    static int button_state;

    switch (sdl_event.type)
    {
    case SDL_KEYDOWN:
        event.type = DP_ev_keydown;
        event.data1 = xlatekey(sdl_event.key.keysym.sym);
        return event;

    case SDL_KEYUP:
        event.type = DP_ev_keyup;
        event.data1 = xlatekey(sdl_event.key.keysym.sym);
        return event;

    case SDL_MOUSEBUTTONDOWN:
        switch (sdl_event.button.button)
        {
        case SDL_BUTTON_LEFT:
            button_state |= 1;
            break;
        case SDL_BUTTON_MIDDLE:
            button_state |= 2;
            break;
        case SDL_BUTTON_RIGHT:
            button_state |= 4;
            break;
        }
        event.type = DP_ev_mouse;
        event.data1 = button_state;
        event.data2 = event.data3 = 0;
        return event;

    case SDL_MOUSEBUTTONUP:
        switch (sdl_event.button.button)
        {
        case SDL_BUTTON_LEFT:
            button_state &= ~1;
            break;
        case SDL_BUTTON_MIDDLE:
            button_state &= ~2;
            break;
        case SDL_BUTTON_RIGHT:
            button_state &= ~4;
            break;
        }
        event.type = DP_ev_mouse;
        event.data1 = button_state;
        event.data2 = event.data3 = 0;
        return event;

    case SDL_MOUSEMOTION:
        event.type = DP_ev_mouse;
        event.data1 = button_state;
        event.data2 = sdl_event.motion.xrel * (1 << 5);
        event.data3 = -sdl_event.motion.yrel * (1 << 5);

        if (event.data2 || event.data3)
            return event;
    }

    return {};
}
