/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#include "tools/sk_app/unix/WindowContextFactory_unix.h"

#include "src/utils/SkUTF.h"
#include "tools/sk_app/WindowContext.h"
#include "tools/sk_app/unix/Window_unix.h"
#include "tools/skui/ModifierKey.h"
#include "tools/timer/Timer.h"

extern "C" {
    #include "tools/sk_app/unix/keysym2ucs.h"
}
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/XKBlib.h>

namespace sk_app {

SkTDynamicHash<Window_unix, XWindow> Window_unix::gWindowMap;

Window* Window::CreateNativeWindow(void* platformData) {
    Display* display = (Display*)platformData;
    SkASSERT(display);

    Window_unix* window = new Window_unix();
    if (!window->initWindow(display)) {
        delete window;
        return nullptr;
    }

    return window;
}

const long kEventMask = ExposureMask | StructureNotifyMask |
                        KeyPressMask | KeyReleaseMask |
                        PointerMotionMask | ButtonPressMask | ButtonReleaseMask;

bool Window_unix::initWindow(Display* display) {
    if (fRequestedDisplayParams.fMSAASampleCount != fMSAASampleCount) {
        this->closeWindow();
    }
    // we already have a window
    if (fDisplay) {
        return true;
    }
    fDisplay = display;

    constexpr int initialWidth = 1280;
    constexpr int initialHeight = 960;

#ifdef SK_GL
    // Attempt to create a window that supports GL

    // We prefer the more recent glXChooseFBConfig but fall back to glXChooseVisual. They have
    // slight differences in how attributes are specified.
    static int constexpr kChooseFBConfigAtt[] = {
        GLX_RENDER_TYPE, GLX_RGBA_BIT,
        GLX_DOUBLEBUFFER, True,
        GLX_STENCIL_SIZE, 8,
        None
    };
    // For some reason glXChooseVisual takes a non-const pointer to the attributes.
    int chooseVisualAtt[] = {
        GLX_RGBA,
        GLX_DOUBLEBUFFER,
        GLX_STENCIL_SIZE, 8,
        None
    };
    SkASSERT(nullptr == fVisualInfo);
    if (fRequestedDisplayParams.fMSAASampleCount > 1) {
        static const GLint kChooseFBConifgAttCnt = std::size(kChooseFBConfigAtt);
        GLint msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 4];
        memcpy(msaaChooseFBConfigAtt, kChooseFBConfigAtt, sizeof(kChooseFBConfigAtt));
        SkASSERT(None == msaaChooseFBConfigAtt[kChooseFBConifgAttCnt - 1]);
        msaaChooseFBConfigAtt[kChooseFBConifgAttCnt - 1] = GLX_SAMPLE_BUFFERS_ARB;
        msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 0] = 1;
        msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 1] = GLX_SAMPLES_ARB;
        msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 2] = fRequestedDisplayParams.fMSAASampleCount;
        msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 3] = None;
        int n;
        fFBConfig = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay), msaaChooseFBConfigAtt, &n);
        if (n > 0) {
            fVisualInfo = glXGetVisualFromFBConfig(fDisplay, *fFBConfig);
        } else {
            static const GLint kChooseVisualAttCnt = std::size(chooseVisualAtt);
            GLint msaaChooseVisualAtt[kChooseVisualAttCnt + 4];
            memcpy(msaaChooseVisualAtt, chooseVisualAtt, sizeof(chooseVisualAtt));
            SkASSERT(None == msaaChooseVisualAtt[kChooseVisualAttCnt - 1]);
            msaaChooseFBConfigAtt[kChooseVisualAttCnt - 1] = GLX_SAMPLE_BUFFERS_ARB;
            msaaChooseFBConfigAtt[kChooseVisualAttCnt + 0] = 1;
            msaaChooseFBConfigAtt[kChooseVisualAttCnt + 1] = GLX_SAMPLES_ARB;
            msaaChooseFBConfigAtt[kChooseVisualAttCnt + 2] =
                    fRequestedDisplayParams.fMSAASampleCount;
            msaaChooseFBConfigAtt[kChooseVisualAttCnt + 3] = None;
            fVisualInfo = glXChooseVisual(display, DefaultScreen(display), msaaChooseVisualAtt);
            fFBConfig = nullptr;
        }
    }
    if (nullptr == fVisualInfo) {
        int n;
        fFBConfig = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay), kChooseFBConfigAtt, &n);
        if (n > 0) {
            fVisualInfo = glXGetVisualFromFBConfig(fDisplay, *fFBConfig);
        } else {
            fVisualInfo = glXChooseVisual(display, DefaultScreen(display), chooseVisualAtt);
            fFBConfig = nullptr;
        }
    }

    if (fVisualInfo) {
        Colormap colorMap = XCreateColormap(display,
                                            RootWindow(display, fVisualInfo->screen),
                                            fVisualInfo->visual,
                                            AllocNone);
        XSetWindowAttributes swa;
        swa.colormap = colorMap;
        swa.event_mask = kEventMask;
        fWindow = XCreateWindow(display,
                                RootWindow(display, fVisualInfo->screen),
                                0, 0, // x, y
                                initialWidth, initialHeight,
                                0, // border width
                                fVisualInfo->depth,
                                InputOutput,
                                fVisualInfo->visual,
                                CWEventMask | CWColormap,
                                &swa);
    }
#endif
    if (!fWindow) {
        // Create a simple window instead.  We will not be able to show GL
        fWindow = XCreateSimpleWindow(display,
                                      DefaultRootWindow(display),
                                      0, 0,  // x, y
                                      initialWidth, initialHeight,
                                      0,     // border width
                                      0,     // border value
                                      0);    // background value
        XSelectInput(display, fWindow, kEventMask);
    }

    if (!fWindow) {
        return false;
    }

    fMSAASampleCount = fRequestedDisplayParams.fMSAASampleCount;

    // set up to catch window delete message
    fWmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", False);
    XSetWMProtocols(display, fWindow, &fWmDeleteMessage, 1);

    // add to hashtable of windows
    gWindowMap.add(this);

    // init event variables
    fPendingPaint = false;
    fPendingResize = false;

    return true;
}

void Window_unix::closeWindow() {
    if (fDisplay) {
        this->detach();
        if (fGC) {
            XFreeGC(fDisplay, fGC);
            fGC = nullptr;
        }
        gWindowMap.remove(fWindow);
        XDestroyWindow(fDisplay, fWindow);
        fWindow = 0;
        if (fFBConfig) {
            XFree(fFBConfig);
            fFBConfig = nullptr;
        }
        if (fVisualInfo) {
            XFree(fVisualInfo);
            fVisualInfo = nullptr;
        }
        fDisplay = nullptr;
    }
}

static skui::Key get_key(KeySym keysym) {
    static const struct {
        KeySym      fXK;
        skui::Key fKey;
    } gPair[] = {
        { XK_BackSpace, skui::Key::kBack     },
        { XK_Clear,     skui::Key::kBack     },
        { XK_Return,    skui::Key::kOK       },
        { XK_Up,        skui::Key::kUp       },
        { XK_Down,      skui::Key::kDown     },
        { XK_Left,      skui::Key::kLeft     },
        { XK_Right,     skui::Key::kRight    },
        { XK_Tab,       skui::Key::kTab      },
        { XK_Page_Up,   skui::Key::kPageUp   },
        { XK_Page_Down, skui::Key::kPageDown },
        { XK_Home,      skui::Key::kHome     },
        { XK_End,       skui::Key::kEnd      },
        { XK_Delete,    skui::Key::kDelete   },
        { XK_Escape,    skui::Key::kEscape   },
        { XK_Shift_L,   skui::Key::kShift    },
        { XK_Shift_R,   skui::Key::kShift    },
        { XK_Control_L, skui::Key::kCtrl     },
        { XK_Control_R, skui::Key::kCtrl     },
        { XK_Alt_L,     skui::Key::kOption   },
        { XK_Alt_R,     skui::Key::kOption   },
        { 'a',          skui::Key::kA        },
        { 'c',          skui::Key::kC        },
        { 'v',          skui::Key::kV        },
        { 'x',          skui::Key::kX        },
        { 'y',          skui::Key::kY        },
        { 'z',          skui::Key::kZ        },
    };
    for (size_t i = 0; i < std::size(gPair); i++) {
        if (gPair[i].fXK == keysym) {
            return gPair[i].fKey;
        }
    }
    return skui::Key::kNONE;
}

static skui::ModifierKey get_modifiers(const XEvent& event) {
    static const struct {
        unsigned    fXMask;
        skui::ModifierKey  fSkMask;
    } gModifiers[] = {
        { ShiftMask,   skui::ModifierKey::kShift },
        { ControlMask, skui::ModifierKey::kControl },
        { Mod1Mask,    skui::ModifierKey::kOption },
    };

    skui::ModifierKey modifiers = skui::ModifierKey::kNone;
    for (size_t i = 0; i < std::size(gModifiers); ++i) {
        if (event.xkey.state & gModifiers[i].fXMask) {
            modifiers |= gModifiers[i].fSkMask;
        }
    }
    return modifiers;
}

bool Window_unix::handleEvent(const XEvent& event) {
    switch (event.type) {
        case MapNotify:
            if (!fGC) {
                fGC = XCreateGC(fDisplay, fWindow, 0, nullptr);
            }
            break;

        case ClientMessage:
            if ((Atom)event.xclient.data.l[0] == fWmDeleteMessage &&
                gWindowMap.count() == 1) {
                return true;
            }
            break;

        case ButtonPress:
            switch (event.xbutton.button) {
                case Button1:
                    this->onMouse(event.xbutton.x, event.xbutton.y,
                                  skui::InputState::kDown, get_modifiers(event));
                    break;
                case Button4:
                    this->onMouseWheel(1.0f, get_modifiers(event));
                    break;
                case Button5:
                    this->onMouseWheel(-1.0f, get_modifiers(event));
                    break;
            }
            break;

        case ButtonRelease:
            if (event.xbutton.button == Button1) {
                this->onMouse(event.xbutton.x, event.xbutton.y,
                              skui::InputState::kUp, get_modifiers(event));
            }
            break;

        case MotionNotify:
            this->onMouse(event.xmotion.x, event.xmotion.y,
                          skui::InputState::kMove, get_modifiers(event));
            break;

        case KeyPress: {
            int shiftLevel = (event.xkey.state & ShiftMask) ? 1 : 0;
            KeySym keysym = XkbKeycodeToKeysym(fDisplay, event.xkey.keycode, 0, shiftLevel);
            skui::Key key = get_key(keysym);
            if (key != skui::Key::kNONE) {
                if (!this->onKey(key, skui::InputState::kDown, get_modifiers(event))) {
                    if (keysym == XK_Escape) {
                        return true;
                    }
                }
            }

            long uni = keysym2ucs(keysym);
            if (uni != -1) {
                (void) this->onChar((SkUnichar) uni, get_modifiers(event));
            }
        } break;

        case KeyRelease: {
            int shiftLevel = (event.xkey.state & ShiftMask) ? 1 : 0;
            KeySym keysym = XkbKeycodeToKeysym(fDisplay, event.xkey.keycode,
                                               0, shiftLevel);
            skui::Key key = get_key(keysym);
            (void) this->onKey(key, skui::InputState::kUp,
                               get_modifiers(event));
        } break;

        case SelectionClear: {
            // Lost selection ownership
            fClipboardText.clear();
        } break;

        case SelectionRequest: {
            Atom UTF8      = XInternAtom(fDisplay, "UTF8_STRING", 0),
                 CLIPBOARD = XInternAtom(fDisplay, "CLIPBOARD", 0);

            const XSelectionRequestEvent* xsr = &event.xselectionrequest;

            XSelectionEvent xsel = {};
            xsel.type      = SelectionNotify;
            xsel.requestor = xsr->requestor;
            xsel.selection = xsr->selection;
            xsel.target    = xsr->target;
            xsel.property  = xsr->property;
            xsel.time      = xsr->time;

            if (xsr->selection != CLIPBOARD) {
                // A request for a different kind of selection. This shouldn't happen.
                break;
            }

            if (fClipboardText.empty() || xsr->target != UTF8 || xsr->property == None) {
                // We can't fulfill this request. Deny it.
                xsel.property = None;
                XSendEvent(fDisplay, xsr->requestor, True, NoEventMask, (XEvent*)&xsel);
            } else {
                // We can fulfill this request! Update the contents of the CLIPBOARD property,
                // and let the requestor know.
                XChangeProperty(fDisplay, xsr->requestor, xsr->property, UTF8, /*format=*/8,
                                PropModeReplace, (unsigned char*)fClipboardText.data(),
                                fClipboardText.length());
                XSendEvent(fDisplay, xsr->requestor, True, NoEventMask, (XEvent*)&xsel);
            }
        } break;

        default:
            // these events should be handled in the main event loop
            SkASSERT(event.type != Expose && event.type != ConfigureNotify);
            break;
    }

    return false;
}

void Window_unix::setTitle(const char* title) {
    XTextProperty textproperty;
    if (!XStringListToTextProperty(const_cast<char**>(&title), 1, &textproperty)) {
        return;
    }
    XSetWMName(fDisplay, fWindow, &textproperty);
    XFree(textproperty.value);
}

void Window_unix::show() {
    XMapWindow(fDisplay, fWindow);
}

bool Window_unix::attach(BackendType attachType) {
    fBackend = attachType;

    this->initWindow(fDisplay);

    window_context_factory::XlibWindowInfo winInfo;
    winInfo.fDisplay = fDisplay;
    winInfo.fWindow = fWindow;
    winInfo.fFBConfig = fFBConfig;
    winInfo.fVisualInfo = fVisualInfo;

    XWindowAttributes attrs;
    if (XGetWindowAttributes(fDisplay, fWindow, &attrs)) {
        winInfo.fWidth = attrs.width;
        winInfo.fHeight = attrs.height;
    } else {
        winInfo.fWidth = winInfo.fHeight = 0;
    }

    switch (attachType) {
#ifdef SK_DAWN
        case kDawn_BackendType:
            fWindowContext =
                    window_context_factory::MakeDawnVulkanForXlib(winInfo, fRequestedDisplayParams);
            break;
#endif
#ifdef SK_VULKAN
        case kVulkan_BackendType:
            fWindowContext =
                    window_context_factory::MakeVulkanForXlib(winInfo, fRequestedDisplayParams);
            break;
#endif
#ifdef SK_GL
        case kNativeGL_BackendType:
            fWindowContext =
                    window_context_factory::MakeGLForXlib(winInfo, fRequestedDisplayParams);
            break;
#endif
        case kRaster_BackendType:
            fWindowContext =
                    window_context_factory::MakeRasterForXlib(winInfo, fRequestedDisplayParams);
            break;
    }
    this->onBackendCreated();

    return (SkToBool(fWindowContext));
}

void Window_unix::onInval() {
    XEvent event;
    event.type = Expose;
    event.xexpose.send_event = True;
    event.xexpose.display = fDisplay;
    event.xexpose.window = fWindow;
    event.xexpose.x = 0;
    event.xexpose.y = 0;
    event.xexpose.width = this->width();
    event.xexpose.height = this->height();
    event.xexpose.count = 0;

    XSendEvent(fDisplay, fWindow, False, 0, &event);
}

void Window_unix::setRequestedDisplayParams(const DisplayParams& params, bool allowReattach) {
#if defined(SK_VULKAN)
    // Vulkan on unix crashes if we try to reinitialize the vulkan context without remaking the
    // window.
    if (fBackend == kVulkan_BackendType && allowReattach) {
        // Need to change these early, so attach() creates the window context correctly
        fRequestedDisplayParams = params;

        this->detach();
        this->attach(fBackend);
        return;
    }
#endif

    INHERITED::setRequestedDisplayParams(params, allowReattach);
}

const char* Window_unix::getClipboardText() {
    Atom UTF8      = XInternAtom(fDisplay, "UTF8_STRING", 0),
         CLIPBOARD = XInternAtom(fDisplay, "CLIPBOARD", 0),
         XSEL_DATA = XInternAtom(fDisplay, "XSEL_DATA", 0);

    // Ask for a UTF8 copy of the CLIPBOARD...
    XEvent event;
    XConvertSelection(fDisplay, CLIPBOARD, UTF8, XSEL_DATA, fWindow, CurrentTime);
    XSync(fDisplay, 0);
    XNextEvent(fDisplay, &event);
    if (event.type == SelectionNotify &&
            event.xselection.selection == CLIPBOARD &&
            event.xselection.property != None) {

        // We got a response
        Atom type;
        int format;
        unsigned long nitems, bytes_after;
        char* data;

        // Fetch the CLIPBOARD property
        XSelectionEvent xsel = event.xselection;
        XGetWindowProperty(xsel.display, xsel.requestor, xsel.property, /*offset=*/0,
                           /*length=*/~0L, /*delete=*/False, AnyPropertyType, &type, &format,
                           &nitems, &bytes_after, (unsigned char**)&data);
        SkASSERT(bytes_after == 0);
        if (type == UTF8) {
            fClipboardText.assign(data, nitems);
        }
        XFree(data);
        XDeleteProperty(xsel.display, xsel.requestor, xsel.property);
    }
    return fClipboardText.c_str();
}

void Window_unix::setClipboardText(const char* text) {
    fClipboardText.assign(text);

    // Take ownership of the CLIPBOARD
    Atom CLIPBOARD = XInternAtom(fDisplay, "CLIPBOARD", 0);
    XSetSelectionOwner(fDisplay, CLIPBOARD, fWindow, CurrentTime);
}

}   // namespace sk_app
