/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2013 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/bwindow/SDL_bkeyboard.h"


#ifdef __cplusplus
extern "C" {
#endif

#include "SDL_config.h"

#include "SDL_video.h"

/* Local includes */
#include "../../events/SDL_events_c.h"
#include "../../video/bwindow/SDL_bkeyboard.h"
#include "../../video/bwindow/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);
    }

    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 */
    vector<SDL_Window*> _window_map; /* Keeps track of SDL_Windows by index-id*/

    display_mode *_saved_mode;
    BGLView      *_current_context;
};

#endif
