/* Copyright 2022 Jaakko Keränen <jaakko.keranen@iki.fi>

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */

#pragma once

#include "SDL_keyboard.h"
#include "SDL_mouse.h"
#include <stdint.h>

enum {
    SDL_QUIT = 0x100,
    SDL_APP_LOWMEMORY,
    SDL_APP_WILLENTERFOREGROUND,
    SDL_APP_DIDENTERFOREGROUND,
    SDL_APP_WILLENTERBACKGROUND,
    SDL_APP_DIDENTERBACKGROUND,
    SDL_APP_TERMINATING,
    SDL_WINDOWEVENT,
    SDL_RENDER_TARGETS_RESET,
    SDL_RENDER_DEVICE_RESET,
    SDL_KEYDOWN,
    SDL_KEYUP,
    SDL_TEXTINPUT,
    SDL_MOUSEBUTTONDOWN,
    SDL_MOUSEBUTTONUP,
    SDL_MOUSEMOTION,
    SDL_MOUSEWHEEL,
    SDL_FINGERDOWN,
    SDL_FINGERMOTION,
    SDL_FINGERUP,
    SDL_DROPFILE,
    SDL_USEREVENT = 0x8000,
};

enum { SDL_RELEASED, SDL_PRESSED };

typedef int SDL_FingerID;
typedef int SDL_TouchID;

typedef struct SDL_KeyboardEvent_s {
    uint32_t   type;
    uint32_t   timestamp;
    uint32_t   windowID;
    uint8_t    state;
    uint8_t    repeat;
    SDL_KeySym keysym;
} SDL_KeyboardEvent;

typedef struct SDL_TextInputEvent_s {
    uint32_t    type;
    uint32_t    timestamp;
    uint32_t    windowID;
    char        text[32];
} SDL_TextInputEvent;

typedef struct SDL_MouseButtonEvent_s {
    uint32_t type;
    uint32_t timestamp;
    uint32_t windowID;
    uint32_t which;
    uint8_t  button;
    uint8_t  state;
    uint8_t  clicks;
    int      x;
    int      y;
} SDL_MouseButtonEvent;

typedef struct SDL_MouseMotionEvent_s {
    uint32_t type;
    uint32_t timestamp;
    uint32_t windowID;
    uint32_t which;
    uint8_t  state;
    int      x;
    int      y;
    int      xrel;
    int      yrel;
} SDL_MouseMotionEvent;

typedef struct SDL_MouseWheelEvent_s {
    uint32_t type;
    uint32_t timestamp;
    uint32_t windowID;
    uint32_t which;
    int      x;
    int      y;
    uint32_t direction;
    float    preciseX;
    float    preciseY;
} SDL_MouseWheelEvent;

typedef struct SDL_TouchFingerEvent_s {
    uint32_t type;
    uint32_t timestamp;
    SDL_TouchID touchId;
    SDL_FingerID fingerId;
    float x;
    float y;
    float dx;
    float dy;
    float pressure;
    uint32_t windowID;
} SDL_TouchFingerEvent;

typedef struct SDL_WindowEvent_s {
    uint32_t type;
    uint32_t timestamp;
    uint32_t windowID;
    uint8_t event;
    int data1;
    int data2;
} SDL_WindowEvent;

typedef struct SDL_DropEvent_s {
    uint32_t type;
    uint32_t timestamp;
    char *   file;
    uint32_t windowID;
} SDL_DropEvent;

typedef struct SDL_UserEvent_s {
    uint32_t type;
    uint32_t timestamp;
    uint32_t windowID;
    int code;
    void *data1;
    void *data2;
} SDL_UserEvent;

typedef union SDL_Event_s {
    uint32_t             type;
    SDL_WindowEvent      window;
    SDL_KeyboardEvent    key;
    SDL_MouseButtonEvent button;
    SDL_MouseMotionEvent motion;
    SDL_MouseWheelEvent  wheel;
    SDL_TouchFingerEvent tfinger;
    SDL_DropEvent        drop;
    SDL_TextInputEvent   text;
    SDL_UserEvent        user;
} SDL_Event;

void    SDL_EventState          (int event, int state);
void    SDL_AddEventWatch       (int (*filter)(void *, SDL_Event *), void *);
void    SDL_DelEventWatch       (int (*filter)(void *, SDL_Event *), void *);

int     SDL_PollEvent           (SDL_Event *event);
int     SDL_WaitEvent           (SDL_Event *event);
int     SDL_WaitEventTimeout    (SDL_Event *event, uint32_t timeout);
void    SDL_PushEvent           (const SDL_Event *);
