/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2020 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 <game/DirectWindow.h>
#if SDL_VIDEO_OPENGL
#include <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;
        _gl_type = 0;
#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;
        _num_clips = 0;

#ifdef DRAWTHREAD
        _draw_thread_id = spawn_thread(HAIKU_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

        delete _prev_frame;

        /* 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);
            _gl_type = gl_flags;
        }
        AddChild(_SDL_GLView);
        _SDL_GLView->SetEventMask(B_POINTER_EVENTS | B_KEYBOARD_EVENTS, B_NO_POINTER_HISTORY);
        _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 (info->clip_list_count > _num_clips)
            {
                if(_clips) {
                    free(_clips);
                    _clips = NULL;
                }
            }

            _num_clips = info->clip_list_count;
            if (_clips == NULL)
                _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 */
        msg.AddBool("focusGained", active);
        _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);
            }
            break;

        case B_MOUSE_DOWN:
            if (msg->FindInt32("buttons", &buttons) == B_OK) {
                _MouseButtonEvent(buttons, SDL_PRESSED);
            }
            break;

        case B_MOUSE_UP:
            if (msg->FindInt32("buttons", &buttons) == B_OK) {
                _MouseButtonEvent(buttons, SDL_RELEASED);
            }
            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:
            {
                int32 i = 0;
                int8 byte;
                int8 bytes[4] = { 0, 0, 0, 0 };
                while (i < 4 && msg->FindInt8("byte", i, &byte) == B_OK) {
                    bytes[i] = byte;
                    i++;
                }
                if (msg->FindInt32("key", &key) == B_OK) {
                    _KeyEvent((SDL_Scancode)key, &bytes[0], i, SDL_PRESSED);
                }
            }
            break;
            
        case B_UNMAPPED_KEY_DOWN:      /* modifier keys are unmapped */
            if (msg->FindInt32("key", &key) == B_OK) {
                _KeyEvent((SDL_Scancode)key, NULL, 0, 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, NULL, 0, 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; }
    Uint32 GetGLType() { return _gl_type; }
#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, Uint8 state) {
        int32 buttonStateChange = buttons ^ _last_buttons;

        if(buttonStateChange & B_PRIMARY_MOUSE_BUTTON) {
            _SendMouseButton(SDL_BUTTON_LEFT, state);
        }
        if(buttonStateChange & B_SECONDARY_MOUSE_BUTTON) {
            _SendMouseButton(SDL_BUTTON_RIGHT, state);
        }
        if(buttonStateChange & B_TERTIARY_MOUSE_BUTTON) {
            _SendMouseButton(SDL_BUTTON_MIDDLE, state);
        }

        _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, const int8 *keyUtf8, const ssize_t & len, 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);
        if (keyUtf8 != NULL) {
            msg.AddData("key-utf8", B_INT8_TYPE, (const void*)keyUtf8, len);
        }
        be_app->PostMessage(&msg);
    }

    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_TITLED_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(Flags() & ~(B_NOT_RESIZABLE | B_NOT_ZOOMABLE));
        } else {
            SetFlags(Flags() | (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;
    Uint32 _gl_type;
#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;
    uint32          _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 /* SDL_BWin_h_ */

/* vi: set ts=4 sw=4 expandtab: */
