/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_BAPP_H
#define SDL_BAPP_H

#include <InterfaceKit.h>
#include <OpenGLKit.h>

#include "../../video/haiku/SDL_bkeyboard.h"


#ifdef __cplusplus
extern "C" {
#endif

#include "../../SDL_internal.h"

#include "SDL_video.h"

/* Local includes */
#include "../../events/SDL_events_c.h"
#include "../../video/haiku/SDL_bkeyboard.h"
#include "../../video/haiku/SDL_bframebuffer.h"

#ifdef __cplusplus
}
#endif

#include <vector>




/* Forward declarations */
class SDL_BWin;

/* Message constants */
enum ToSDL {
    /* Intercepted by BWindow on its way to BView */
    BAPP_MOUSE_MOVED,
    BAPP_MOUSE_BUTTON,
    BAPP_MOUSE_WHEEL,
    BAPP_KEY,
    BAPP_REPAINT,           /* from _UPDATE_ */
    /* From BWindow */
    BAPP_MAXIMIZE,          /* from B_ZOOM */
    BAPP_MINIMIZE,
    BAPP_RESTORE,           /* TODO: IMPLEMENT! */
    BAPP_SHOW,
    BAPP_HIDE,
    BAPP_MOUSE_FOCUS,       /* caused by MOUSE_MOVE */
    BAPP_KEYBOARD_FOCUS,    /* from WINDOW_ACTIVATED */
    BAPP_WINDOW_CLOSE_REQUESTED,
    BAPP_WINDOW_MOVED,
    BAPP_WINDOW_RESIZED,
    BAPP_SCREEN_CHANGED
};



/* Create a descendant of BApplication */
class SDL_BApp : public BApplication {
public:
    SDL_BApp(const char* signature) :
        BApplication(signature) {
        _current_context = NULL;
    }


    virtual ~SDL_BApp() {
    }



        /* Event-handling functions */
    virtual void MessageReceived(BMessage* message) {
        /* Sort out SDL-related messages */
        switch ( message->what ) {
        case BAPP_MOUSE_MOVED:
            _HandleMouseMove(message);
            break;

        case BAPP_MOUSE_BUTTON:
            _HandleMouseButton(message);
            break;

        case BAPP_MOUSE_WHEEL:
            _HandleMouseWheel(message);
            break;

        case BAPP_KEY:
            _HandleKey(message);
            break;

        case BAPP_REPAINT:
            _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_EXPOSED);
            break;

        case BAPP_MAXIMIZE:
            _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_MAXIMIZED);
            break;

        case BAPP_MINIMIZE:
            _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_MINIMIZED);
            break;

        case BAPP_SHOW:
            _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_SHOWN);
            break;

        case BAPP_HIDE:
            _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_HIDDEN);
            break;

        case BAPP_MOUSE_FOCUS:
            _HandleMouseFocus(message);
            break;

        case BAPP_KEYBOARD_FOCUS:
            _HandleKeyboardFocus(message);
            break;

        case BAPP_WINDOW_CLOSE_REQUESTED:
            _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_CLOSE);
            break;

        case BAPP_WINDOW_MOVED:
            _HandleWindowMoved(message);
            break;

        case BAPP_WINDOW_RESIZED:
            _HandleWindowResized(message);
            break;

        case BAPP_SCREEN_CHANGED:
            /* TODO: Handle screen resize or workspace change */
            break;

        default:
           BApplication::MessageReceived(message);
           break;
        }
    }

    /* Window creation/destruction methods */
    int32 GetID(SDL_Window *win) {
        int32 i;
        for(i = 0; i < _GetNumWindowSlots(); ++i) {
            if( GetSDLWindow(i) == NULL ) {
                _SetSDLWindow(win, i);
                return i;
            }
        }

        /* Expand the vector if all slots are full */
        if( i == _GetNumWindowSlots() ) {
            _PushBackWindow(win);
            return i;
        }

        /* TODO: error handling */
        return 0;
    }

    /* FIXME: Bad coding practice, but I can't include SDL_BWin.h here.  Is
       there another way to do this? */
    void ClearID(SDL_BWin *bwin); /* Defined in SDL_BeApp.cc */


    SDL_Window *GetSDLWindow(int32 winID) {
        return _window_map[winID];
    }

    void SetCurrentContext(BGLView *newContext) {
        if(_current_context)
            _current_context->UnlockGL();
        _current_context = newContext;
        _current_context->LockGL();
    }
private:
    /* Event management */
    void _HandleBasicWindowEvent(BMessage *msg, int32 sdlEventType) {
        SDL_Window *win;
        int32 winID;
        if(
            !_GetWinID(msg, &winID)
        ) {
            return;
        }
        win = GetSDLWindow(winID);
        SDL_SendWindowEvent(win, sdlEventType, 0, 0);
    }

    void _HandleMouseMove(BMessage *msg) {
        SDL_Window *win;
        int32 winID;
        int32 x = 0, y = 0;
        if(
            !_GetWinID(msg, &winID) ||
            msg->FindInt32("x", &x) != B_OK || /* x movement */
            msg->FindInt32("y", &y) != B_OK    /* y movement */
        ) {
            return;
        }
        win = GetSDLWindow(winID);
        SDL_SendMouseMotion(win, 0, 0, x, y);

        /* Tell the application that the mouse passed over, redraw needed */
        BE_UpdateWindowFramebuffer(NULL,win,NULL,-1);
    }

    void _HandleMouseButton(BMessage *msg) {
        SDL_Window *win;
        int32 winID;
        int32 button, state;    /* left/middle/right, pressed/released */
        if(
            !_GetWinID(msg, &winID) ||
            msg->FindInt32("button-id", &button) != B_OK ||
            msg->FindInt32("button-state", &state) != B_OK
        ) {
            return;
        }
        win = GetSDLWindow(winID);
        SDL_SendMouseButton(win, 0, state, button);
    }

    void _HandleMouseWheel(BMessage *msg) {
        SDL_Window *win;
        int32 winID;
        int32 xTicks, yTicks;
        if(
            !_GetWinID(msg, &winID) ||
            msg->FindInt32("xticks", &xTicks) != B_OK ||
            msg->FindInt32("yticks", &yTicks) != B_OK
        ) {
            return;
        }
        win = GetSDLWindow(winID);
        SDL_SendMouseWheel(win, 0, xTicks, yTicks, SDL_MOUSEWHEEL_NORMAL);
    }

    void _HandleKey(BMessage *msg) {
        int32 scancode, state;  /* scancode, pressed/released */
        if(
            msg->FindInt32("key-state", &state) != B_OK ||
            msg->FindInt32("key-scancode", &scancode) != B_OK
        ) {
            return;
        }

        /* Make sure this isn't a repeated event (key pressed and held) */
        if(state == SDL_PRESSED && BE_GetKeyState(scancode) == SDL_PRESSED) {
            return;
        }
        BE_SetKeyState(scancode, state);
        SDL_SendKeyboardKey(state, BE_GetScancodeFromBeKey(scancode));
    }

    void _HandleMouseFocus(BMessage *msg) {
        SDL_Window *win;
        int32 winID;
        bool bSetFocus; /* If false, lose focus */
        if(
            !_GetWinID(msg, &winID) ||
            msg->FindBool("focusGained", &bSetFocus) != B_OK
        ) {
            return;
        }
        win = GetSDLWindow(winID);
        if(bSetFocus) {
            SDL_SetMouseFocus(win);
        } else if(SDL_GetMouseFocus() == win) {
            /* Only lose all focus if this window was the current focus */
            SDL_SetMouseFocus(NULL);
        }
    }

    void _HandleKeyboardFocus(BMessage *msg) {
        SDL_Window *win;
        int32 winID;
        bool bSetFocus; /* If false, lose focus */
        if(
            !_GetWinID(msg, &winID) ||
            msg->FindBool("focusGained", &bSetFocus) != B_OK
        ) {
            return;
        }
        win = GetSDLWindow(winID);
        if(bSetFocus) {
            SDL_SetKeyboardFocus(win);
        } else if(SDL_GetKeyboardFocus() == win) {
            /* Only lose all focus if this window was the current focus */
            SDL_SetKeyboardFocus(NULL);
        }
    }

    void _HandleWindowMoved(BMessage *msg) {
        SDL_Window *win;
        int32 winID;
        int32 xPos, yPos;
        /* Get the window id and new x/y position of the window */
        if(
            !_GetWinID(msg, &winID) ||
            msg->FindInt32("window-x", &xPos) != B_OK ||
            msg->FindInt32("window-y", &yPos) != B_OK
        ) {
            return;
        }
        win = GetSDLWindow(winID);
        SDL_SendWindowEvent(win, SDL_WINDOWEVENT_MOVED, xPos, yPos);
    }

    void _HandleWindowResized(BMessage *msg) {
        SDL_Window *win;
        int32 winID;
        int32 w, h;
        /* Get the window id ]and new x/y position of the window */
        if(
            !_GetWinID(msg, &winID) ||
            msg->FindInt32("window-w", &w) != B_OK ||
            msg->FindInt32("window-h", &h) != B_OK
        ) {
            return;
        }
        win = GetSDLWindow(winID);
        SDL_SendWindowEvent(win, SDL_WINDOWEVENT_RESIZED, w, h);
    }

    bool _GetWinID(BMessage *msg, int32 *winID) {
        return msg->FindInt32("window-id", winID) == B_OK;
    }



    /* Vector functions: Wraps vector stuff in case we need to change
       implementation */
    void _SetSDLWindow(SDL_Window *win, int32 winID) {
        _window_map[winID] = win;
    }

    int32 _GetNumWindowSlots() {
        return _window_map.size();
    }


    void _PopBackWindow() {
        _window_map.pop_back();
    }

    void _PushBackWindow(SDL_Window *win) {
        _window_map.push_back(win);
    }


    /* Members */
    std::vector<SDL_Window*> _window_map; /* Keeps track of SDL_Windows by index-id */

    display_mode *_saved_mode;
    BGLView      *_current_context;
};

#endif
