/*
  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_BWin_h
#define _SDL_BWin_h

#ifdef __cplusplus
extern "C" {
#endif

#include "../../SDL_internal.h"
#include "SDL.h"
#include "SDL_syswm.h"
#include "SDL_bframebuffer.h"

#ifdef __cplusplus
}
#endif

#include <stdio.h>
#include <AppKit.h>
#include <InterfaceKit.h>
#include <be/game/DirectWindow.h>
#if SDL_VIDEO_OPENGL
#include <be/opengl/GLView.h>
#endif
#include "SDL_events.h"
#include "../../main/haiku/SDL_BApp.h"


enum WinCommands {
    BWIN_MOVE_WINDOW,
    BWIN_RESIZE_WINDOW,
    BWIN_SHOW_WINDOW,
    BWIN_HIDE_WINDOW,
    BWIN_MAXIMIZE_WINDOW,
    BWIN_MINIMIZE_WINDOW,
    BWIN_RESTORE_WINDOW,
    BWIN_SET_TITLE,
    BWIN_SET_BORDERED,
    BWIN_SET_RESIZABLE,
    BWIN_FULLSCREEN
};


class SDL_BWin:public BDirectWindow
{
  public:
    /* Constructor/Destructor */
    SDL_BWin(BRect bounds, window_look look, uint32 flags)
        : BDirectWindow(bounds, "Untitled", look, B_NORMAL_WINDOW_FEEL, flags)
    {
        _last_buttons = 0;

#if SDL_VIDEO_OPENGL
        _SDL_GLView = NULL;
#endif
        _shown = false;
        _inhibit_resize = false;
        _mouse_focused = false;
        _prev_frame = NULL;

        /* Handle framebuffer stuff */
        _connected = _connection_disabled = false;
        _buffer_created = _buffer_dirty = false;
        _trash_window_buffer = false;
        _buffer_locker = new BLocker();
        _bitmap = NULL;
        _clips = NULL;

#ifdef DRAWTHREAD
        _draw_thread_id = spawn_thread(BE_DrawThread, "drawing_thread",
                            B_NORMAL_PRIORITY, (void*) this);
        resume_thread(_draw_thread_id);
#endif
    }

    virtual ~ SDL_BWin()
    {
        Lock();
        _connection_disabled = true;
        int32 result;

#if SDL_VIDEO_OPENGL
        if (_SDL_GLView) {
            _SDL_GLView->UnlockGL();
            RemoveChild(_SDL_GLView);   /* Why was this outside the if
                                            statement before? */
        }

#endif
        Unlock();
#if SDL_VIDEO_OPENGL
        if (_SDL_GLView) {
            delete _SDL_GLView;
        }
#endif

        /* Clean up framebuffer stuff */
        _buffer_locker->Lock();
#ifdef DRAWTHREAD
        wait_for_thread(_draw_thread_id, &result);
#endif
        free(_clips);
        delete _buffer_locker;
    }


    /* * * * * OpenGL functionality * * * * */
#if SDL_VIDEO_OPENGL
    virtual BGLView *CreateGLView(Uint32 gl_flags) {
        Lock();
        if (_SDL_GLView == NULL) {
            _SDL_GLView = new BGLView(Bounds(), "SDL GLView",
                                     B_FOLLOW_ALL_SIDES,
                                     (B_WILL_DRAW | B_FRAME_EVENTS),
                                     gl_flags);
        }
        AddChild(_SDL_GLView);
        _SDL_GLView->EnableDirectMode(true);
        _SDL_GLView->LockGL();  /* "New" GLViews are created */
        Unlock();
        return (_SDL_GLView);
    }

    virtual void RemoveGLView() {
        Lock();
        if(_SDL_GLView) {
            _SDL_GLView->UnlockGL();
            RemoveChild(_SDL_GLView);
        }
        Unlock();
    }

    virtual void SwapBuffers(void) {
        _SDL_GLView->UnlockGL();
        _SDL_GLView->LockGL();
        _SDL_GLView->SwapBuffers();
    }
#endif

    /* * * * * Framebuffering* * * * */
    virtual void DirectConnected(direct_buffer_info *info) {
        if(!_connected && _connection_disabled) {
            return;
        }

        /* Determine if the pixel buffer is usable after this update */
        _trash_window_buffer =      _trash_window_buffer
                                || ((info->buffer_state & B_BUFFER_RESIZED)
                                || (info->buffer_state & B_BUFFER_RESET)
                                || (info->driver_state == B_MODE_CHANGED));
        LockBuffer();

        switch(info->buffer_state & B_DIRECT_MODE_MASK) {
        case B_DIRECT_START:
            _connected = true;

        case B_DIRECT_MODIFY:
            if(_clips) {
                free(_clips);
                _clips = NULL;
            }

            _num_clips = info->clip_list_count;
            _clips = (clipping_rect *)malloc(_num_clips*sizeof(clipping_rect));
            if(_clips) {
                memcpy(_clips, info->clip_list,
                    _num_clips*sizeof(clipping_rect));

                _bits = (uint8*) info->bits;
                _row_bytes = info->bytes_per_row;
                _bounds = info->window_bounds;
                _bytes_per_px = info->bits_per_pixel / 8;
                _buffer_dirty = true;
            }
            break;

        case B_DIRECT_STOP:
            _connected = false;
            break;
        }
#if SDL_VIDEO_OPENGL
        if(_SDL_GLView) {
            _SDL_GLView->DirectConnected(info);
        }
#endif


        /* Call the base object directconnected */
        BDirectWindow::DirectConnected(info);

        UnlockBuffer();

    }




    /* * * * * Event sending * * * * */
    /* Hook functions */
    virtual void FrameMoved(BPoint origin) {
        /* Post a message to the BApp so that it can handle the window event */
        BMessage msg(BAPP_WINDOW_MOVED);
        msg.AddInt32("window-x", (int)origin.x);
        msg.AddInt32("window-y", (int)origin.y);
        _PostWindowEvent(msg);

        /* Perform normal hook operations */
        BDirectWindow::FrameMoved(origin);
    }

    virtual void FrameResized(float width, float height) {
        /* Post a message to the BApp so that it can handle the window event */
        BMessage msg(BAPP_WINDOW_RESIZED);

        msg.AddInt32("window-w", (int)width + 1);
        msg.AddInt32("window-h", (int)height + 1);
        _PostWindowEvent(msg);

        /* Perform normal hook operations */
        BDirectWindow::FrameResized(width, height);
    }

    virtual bool QuitRequested() {
        BMessage msg(BAPP_WINDOW_CLOSE_REQUESTED);
        _PostWindowEvent(msg);

        /* We won't allow a quit unless asked by DestroyWindow() */
        return false;
    }

    virtual void WindowActivated(bool active) {
        BMessage msg(BAPP_KEYBOARD_FOCUS);  /* Mouse focus sold separately */
        _PostWindowEvent(msg);
    }

    virtual void Zoom(BPoint origin,
                float width,
                float height) {
        BMessage msg(BAPP_MAXIMIZE);    /* Closest thing to maximization Haiku has */
        _PostWindowEvent(msg);

        /* Before the window zooms, record its size */
        if( !_prev_frame )
            _prev_frame = new BRect(Frame());

        /* Perform normal hook operations */
        BDirectWindow::Zoom(origin, width, height);
    }

    /* Member functions */
    virtual void Show() {
        while(IsHidden()) {
            BDirectWindow::Show();
        }
        _shown = true;

        BMessage msg(BAPP_SHOW);
        _PostWindowEvent(msg);
    }

    virtual void Hide() {
        BDirectWindow::Hide();
        _shown = false;

        BMessage msg(BAPP_HIDE);
        _PostWindowEvent(msg);
    }

    virtual void Minimize(bool minimize) {
        BDirectWindow::Minimize(minimize);
        int32 minState = (minimize ? BAPP_MINIMIZE : BAPP_RESTORE);

        BMessage msg(minState);
        _PostWindowEvent(msg);
    }


    /* BView message interruption */
    virtual void DispatchMessage(BMessage * msg, BHandler * target)
    {
        BPoint where;   /* Used by mouse moved */
        int32 buttons;  /* Used for mouse button events */
        int32 key;      /* Used for key events */

        switch (msg->what) {
        case B_MOUSE_MOVED:
            int32 transit;
            if (msg->FindPoint("where", &where) == B_OK
                && msg->FindInt32("be:transit", &transit) == B_OK) {
                _MouseMotionEvent(where, transit);
            }

            /* FIXME: Apparently a button press/release event might be dropped
               if made before before a different button is released.  Does
               B_MOUSE_MOVED have the data needed to check if a mouse button
               state has changed? */
            if (msg->FindInt32("buttons", &buttons) == B_OK) {
                _MouseButtonEvent(buttons);
            }
            break;

        case B_MOUSE_DOWN:
        case B_MOUSE_UP:
            /* _MouseButtonEvent() detects any and all buttons that may have
               changed state, as well as that button's new state */
            if (msg->FindInt32("buttons", &buttons) == B_OK) {
                _MouseButtonEvent(buttons);
            }
            break;

        case B_MOUSE_WHEEL_CHANGED:
            float x, y;
            if (msg->FindFloat("be:wheel_delta_x", &x) == B_OK
                && msg->FindFloat("be:wheel_delta_y", &y) == B_OK) {
                    _MouseWheelEvent((int)x, (int)y);
            }
            break;

        case B_KEY_DOWN:
        case B_UNMAPPED_KEY_DOWN:      /* modifier keys are unmapped */
            if (msg->FindInt32("key", &key) == B_OK) {
                _KeyEvent((SDL_Scancode)key, SDL_PRESSED);
            }
            break;

        case B_KEY_UP:
        case B_UNMAPPED_KEY_UP:        /* modifier keys are unmapped */
            if (msg->FindInt32("key", &key) == B_OK) {
                _KeyEvent(key, SDL_RELEASED);
            }
            break;

        default:
            /* move it after switch{} so it's always handled
               that way we keep Haiku features like:
               - CTRL+Q to close window (and other shortcuts)
               - PrintScreen to make screenshot into /boot/home
               - etc.. */
            /* BDirectWindow::DispatchMessage(msg, target); */
            break;
        }

        BDirectWindow::DispatchMessage(msg, target);
    }

    /* Handle command messages */
    virtual void MessageReceived(BMessage* message) {
        switch (message->what) {
            /* Handle commands from SDL */
            case BWIN_SET_TITLE:
                _SetTitle(message);
                break;
            case BWIN_MOVE_WINDOW:
                _MoveTo(message);
                break;
            case BWIN_RESIZE_WINDOW:
                _ResizeTo(message);
                break;
            case BWIN_SET_BORDERED:
                _SetBordered(message);
                break;
            case BWIN_SET_RESIZABLE:
                _SetResizable(message);
                break;
            case BWIN_SHOW_WINDOW:
                Show();
                break;
            case BWIN_HIDE_WINDOW:
                Hide();
                break;
            case BWIN_MAXIMIZE_WINDOW:
                BWindow::Zoom();
                break;
            case BWIN_MINIMIZE_WINDOW:
                Minimize(true);
                break;
            case BWIN_RESTORE_WINDOW:
                _Restore();
                break;
            case BWIN_FULLSCREEN:
                _SetFullScreen(message);
                break;
            default:
                /* Perform normal message handling */
                BDirectWindow::MessageReceived(message);
                break;
        }

    }



    /* Accessor methods */
    bool IsShown() { return _shown; }
    int32 GetID() { return _id; }
    uint32 GetRowBytes() { return _row_bytes; }
    int32 GetFbX() { return _bounds.left; }
    int32 GetFbY() { return _bounds.top; }
    bool ConnectionEnabled() { return !_connection_disabled; }
    bool Connected() { return _connected; }
    clipping_rect *GetClips() { return _clips; }
    int32 GetNumClips() { return _num_clips; }
    uint8* GetBufferPx() { return _bits; }
    int32 GetBytesPerPx() { return _bytes_per_px; }
    bool CanTrashWindowBuffer() { return _trash_window_buffer; }
    bool BufferExists() { return _buffer_created; }
    bool BufferIsDirty() { return _buffer_dirty; }
    BBitmap *GetBitmap() { return _bitmap; }
#if SDL_VIDEO_OPENGL
    BGLView *GetGLView() { return _SDL_GLView; }
#endif

    /* Setter methods */
    void SetID(int32 id) { _id = id; }
    void SetBufferExists(bool bufferExists) { _buffer_created = bufferExists; }
    void LockBuffer() { _buffer_locker->Lock(); }
    void UnlockBuffer() { _buffer_locker->Unlock(); }
    void SetBufferDirty(bool bufferDirty) { _buffer_dirty = bufferDirty; }
    void SetTrashBuffer(bool trash) { _trash_window_buffer = trash;     }
    void SetBitmap(BBitmap *bitmap) { _bitmap = bitmap; }


private:
    /* Event redirection */
    void _MouseMotionEvent(BPoint &where, int32 transit) {
        if(transit == B_EXITED_VIEW) {
            /* Change mouse focus */
            if(_mouse_focused) {
                _MouseFocusEvent(false);
            }
        } else {
            /* Change mouse focus */
            if (!_mouse_focused) {
                _MouseFocusEvent(true);
            }
            BMessage msg(BAPP_MOUSE_MOVED);
            msg.AddInt32("x", (int)where.x);
            msg.AddInt32("y", (int)where.y);

            _PostWindowEvent(msg);
        }
    }

    void _MouseFocusEvent(bool focusGained) {
        _mouse_focused = focusGained;
        BMessage msg(BAPP_MOUSE_FOCUS);
        msg.AddBool("focusGained", focusGained);
        _PostWindowEvent(msg);

/* FIXME: Why were these here?
 if false: be_app->SetCursor(B_HAND_CURSOR);
 if true:  SDL_SetCursor(NULL); */
    }

    void _MouseButtonEvent(int32 buttons) {
        int32 buttonStateChange = buttons ^ _last_buttons;

        /* Make sure at least one button has changed state */
        if( !(buttonStateChange) ) {
            return;
        }

        /* Add any mouse button events */
        if(buttonStateChange & B_PRIMARY_MOUSE_BUTTON) {
            _SendMouseButton(SDL_BUTTON_LEFT, buttons &
                B_PRIMARY_MOUSE_BUTTON);
        }
        if(buttonStateChange & B_SECONDARY_MOUSE_BUTTON) {
            _SendMouseButton(SDL_BUTTON_RIGHT, buttons &
                B_PRIMARY_MOUSE_BUTTON);
        }
        if(buttonStateChange & B_TERTIARY_MOUSE_BUTTON) {
            _SendMouseButton(SDL_BUTTON_MIDDLE, buttons &
                B_PRIMARY_MOUSE_BUTTON);
        }

        _last_buttons = buttons;
    }

    void _SendMouseButton(int32 button, int32 state) {
        BMessage msg(BAPP_MOUSE_BUTTON);
        msg.AddInt32("button-id", button);
        msg.AddInt32("button-state", state);
        _PostWindowEvent(msg);
    }

    void _MouseWheelEvent(int32 x, int32 y) {
        /* Create a message to pass along to the BeApp thread */
        BMessage msg(BAPP_MOUSE_WHEEL);
        msg.AddInt32("xticks", x);
        msg.AddInt32("yticks", y);
        _PostWindowEvent(msg);
    }

    void _KeyEvent(int32 keyCode, int32 keyState) {
        /* Create a message to pass along to the BeApp thread */
        BMessage msg(BAPP_KEY);
        msg.AddInt32("key-state", keyState);
        msg.AddInt32("key-scancode", keyCode);
        be_app->PostMessage(&msg);
        /* Apparently SDL only uses the scancode */
    }

    void _RepaintEvent() {
        /* Force a repaint: Call the SDL exposed event */
        BMessage msg(BAPP_REPAINT);
        _PostWindowEvent(msg);
    }
    void _PostWindowEvent(BMessage &msg) {
        msg.AddInt32("window-id", _id);
        be_app->PostMessage(&msg);
    }

    /* Command methods (functions called upon by SDL) */
    void _SetTitle(BMessage *msg) {
        const char *title;
        if(
            msg->FindString("window-title", &title) != B_OK
        ) {
            return;
        }
        SetTitle(title);
    }

    void _MoveTo(BMessage *msg) {
        int32 x, y;
        if(
            msg->FindInt32("window-x", &x) != B_OK ||
            msg->FindInt32("window-y", &y) != B_OK
        ) {
            return;
        }
        MoveTo(x, y);
    }

    void _ResizeTo(BMessage *msg) {
        int32 w, h;
        if(
            msg->FindInt32("window-w", &w) != B_OK ||
            msg->FindInt32("window-h", &h) != B_OK
        ) {
            return;
        }
        ResizeTo(w, h);
    }

    void _SetBordered(BMessage *msg) {
        bool bEnabled;
        if(msg->FindBool("window-border", &bEnabled) != B_OK) {
            return;
        }
        SetLook(bEnabled ? B_BORDERED_WINDOW_LOOK : B_NO_BORDER_WINDOW_LOOK);
    }

    void _SetResizable(BMessage *msg) {
        bool bEnabled;
        if(msg->FindBool("window-resizable", &bEnabled) != B_OK) {
            return;
        }
        if (bEnabled) {
            SetFlags(GetFlags() & ~(B_NOT_RESIZABLE | B_NOT_ZOOMABLE));
        } else {
            SetFlags(GetFlags() | (B_NOT_RESIZABLE | B_NOT_ZOOMABLE));
        }
    }

    void _Restore() {
        if(IsMinimized()) {
            Minimize(false);
        } else if(IsHidden()) {
            Show();
        } else if(_prev_frame != NULL) {    /* Zoomed */
            MoveTo(_prev_frame->left, _prev_frame->top);
            ResizeTo(_prev_frame->Width(), _prev_frame->Height());
        }
    }

    void _SetFullScreen(BMessage *msg) {
        bool fullscreen;
        if(
            msg->FindBool("fullscreen", &fullscreen) != B_OK
        ) {
            return;
        }
        SetFullScreen(fullscreen);
    }

    /* Members */
#if SDL_VIDEO_OPENGL
    BGLView * _SDL_GLView;
#endif

    int32 _last_buttons;
    int32 _id;  /* Window id used by SDL_BApp */
    bool  _mouse_focused;       /* Does this window have mouse focus? */
    bool  _shown;
    bool  _inhibit_resize;

    BRect *_prev_frame; /* Previous position and size of the window */

    /* Framebuffer members */
    bool            _connected,
                    _connection_disabled,
                    _buffer_created,
                    _buffer_dirty,
                    _trash_window_buffer;
    uint8          *_bits;
    uint32          _row_bytes;
    clipping_rect   _bounds;
    BLocker        *_buffer_locker;
    clipping_rect  *_clips;
    int32           _num_clips;
    int32           _bytes_per_px;
    thread_id       _draw_thread_id;

    BBitmap        *_bitmap;
};


/* FIXME:
 * An explanation of framebuffer flags.
 *
 * _connected -           Original variable used to let the drawing thread know
 *                         when changes are being made to the other framebuffer
 *                         members.
 * _connection_disabled - Used to signal to the drawing thread that the window
 *                         is closing, and the thread should exit.
 * _buffer_created -      True if the current buffer is valid
 * _buffer_dirty -        True if the window should be redrawn.
 * _trash_window_buffer - True if the window buffer needs to be trashed partway
 *                         through a draw cycle.  Occurs when the previous
 *                         buffer provided by DirectConnected() is invalidated.
 */
#endif
