// Copyright (C) 2016 The Android Open Source Project
//
// This software is licensed under the terms of the GNU General Public
// License version 2, as published by the Free Software Foundation, and
// may be copied, distributed, and modified under those terms.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

#include "android/skin/qt/emulator-container.h"

#include "android/skin/qt/emulator-qt-window.h"
#include "android/skin/qt/tool-window.h"

#include <QtCore>
#include <QApplication>
#include <QObject>
#include <QScrollBar>
#include <QStyle>
#include <QStyleFactory>

#if defined(__APPLE__)
#include "android/skin/qt/mac-native-window.h"
#endif

#if defined(_WIN32)
#include "android/skin/qt/windows-native-window.h"
#endif

EmulatorContainer::EmulatorContainer(EmulatorQtWindow* window)
    : QScrollArea(), mEmulatorWindow(window) {
    setFrameShape(QFrame::NoFrame);
    setWidget(window);

    // The following hints prevent the minimize/maximize/close buttons from
    // appearing.
    setWindowFlags(Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::Window);

#ifdef __APPLE__
    // Digging into the Qt source code reveals that if the above flags are set
    // on OSX, the created window will be given a style mask that removes the
    // resize handles from the window. The hint below is the specific
    // customization flag that ensures the window will have resize handles.
    // So, we add the button for now, then immediately disable it when the
    // window is first shown.
    setWindowFlags(this->windowFlags() | Qt::WindowMaximizeButtonHint);

    // On OS X the native scrollbars disappear when not in use which
    // makes the zoomed-in emulator window look unscrollable. Also, due
    // to the semi-transparent nature of the scrollbar, it will
    // interfere with the main GL window, causing all kinds of ugly
    // effects.
    QStyle* style = QStyleFactory::create("Fusion");
    if (style) {
        this->verticalScrollBar()->setStyle(style);
        this->horizontalScrollBar()->setStyle(style);
        QObject::connect(this, &QObject::destroyed, [style] { delete style; });
    }
#endif  // __APPLE__

    mResizeTimer.setSingleShot(true);
    QObject::connect(&mResizeTimer, SIGNAL(timeout()), this,
                     SLOT(slot_resizeDone()));
}

EmulatorContainer::~EmulatorContainer() {
    // This object is owned directly by |window|.  Avoid circular
    // destructor calls by explicitly unsetting the widget.
    takeWidget();
}

bool EmulatorContainer::event(QEvent* e) {
    // Ignore MetaCall and UpdateRequest events, and don't snap in zoom mode.
    if (mEmulatorWindow->isInZoomMode() || e->type() == QEvent::MetaCall ||
        e->type() == QEvent::UpdateRequest) {
        return QScrollArea::event(e);
    }

    // Add to the event buffer, but keep it a reasonable size - a few events,
    // such as repaint,
    // can occur in between resizes but before the release happens
    mEventBuffer.push_back(e->type());
    if (mEventBuffer.size() > 8) {
        mEventBuffer.removeFirst();
    }

    // Scan to see if a resize event happened recently
    bool foundResize = false;
    int i = 0;
    for (; i < mEventBuffer.size(); i++) {
        if (mEventBuffer[i] == QEvent::Resize) {
            foundResize = true;
            i++;
            break;
        }
    }

    // Determining resize-over is OS specific
    // Do so by scanning the remainder of the event buffer for specific
    // combinations
    if (foundResize) {
#ifdef _WIN32

        for (; i < mEventBuffer.size() - 1; i++) {
            if (mEventBuffer[i] == QEvent::NonClientAreaMouseButtonRelease) {
                mEventBuffer.clear();
                mEmulatorWindow->doResize(this->size());

                // Kill the resize timer to avoid double resizes.
                stopResizeTimer();
                break;
            }
        }

#elif __linux__

        for (; i < mEventBuffer.size() - 3; i++) {
            if (mEventBuffer[i] == QEvent::WindowActivate &&
                mEventBuffer[i + 1] == QEvent::ActivationChange &&
                mEventBuffer[i + 2] == QEvent::FocusIn &&
                mEventBuffer[i + 3] == QEvent::InputMethodQuery) {
                mEventBuffer.clear();
                mEmulatorWindow->doResize(this->size());

                // Kill the resize timer to avoid double resizes.
                stopResizeTimer();
                break;
            }
        }

#elif __APPLE__

        if (e->type() == QEvent::NonClientAreaMouseMove ||
            e->type() == QEvent::Enter || e->type() == QEvent::Leave) {
            mEventBuffer.clear();
            mEmulatorWindow->doResize(this->size());

            // Kill the resize timer to avoid double resizes.
            stopResizeTimer();
        }

#endif
    }

    return QScrollArea::event(e);
}

void EmulatorContainer::changeEvent(QEvent* event) {
    // Strictly preventing the maximizing (called "zooming" on OS X) of a
    // window is hard - it changes by host, and even by window manager on
    // Linux. Therefore, we counteract it by seeing if the window ever
    // enters a maximized state, and if it does, immediately undoing that
    // maximization.
    //
    // Note that we *do not* call event->ignore(). Maximizing happens in the
    // OS-level window, not Qt's representation of the window. This event
    // simply notifies the Qt representation (and us) that the OS-level window
    // has changed to a maximized state. We do not want to ignore this state
    // change, we just want to counteract the effects it had.
    if (event->type() == QEvent::WindowStateChange) {
        if (windowState() & Qt::WindowMaximized) {
            showNormal();
        } else if (windowState() & Qt::WindowMinimized) {
            // In case the window was minimized without pressing the toolbar's
            // minimize button (which is possible on some window managers),
            // remember to hide the toolbar (which will also hide the extended
            // window, if it exists).
            mEmulatorWindow->toolWindow()->hide();
        }
    }
}

void EmulatorContainer::closeEvent(QCloseEvent* event) {
    mEmulatorWindow->closeEvent(event);
}

void EmulatorContainer::focusInEvent(QFocusEvent* event) {
    mEmulatorWindow->toolWindow()->raise();
    if (mEmulatorWindow->isInZoomMode()) {
        mEmulatorWindow->showZoomIfNotUserHidden();
    }
}

void EmulatorContainer::keyPressEvent(QKeyEvent* event) {
    mEmulatorWindow->keyPressEvent(event);
}

void EmulatorContainer::keyReleaseEvent(QKeyEvent* event) {
    mEmulatorWindow->keyReleaseEvent(event);
}

void EmulatorContainer::moveEvent(QMoveEvent* event) {
    QScrollArea::moveEvent(event);
    mEmulatorWindow->simulateWindowMoved(event->pos());
    mEmulatorWindow->toolWindow()->dockMainWindow();
}

void EmulatorContainer::resizeEvent(QResizeEvent* event) {
    QScrollArea::resizeEvent(event);
    mEmulatorWindow->toolWindow()->dockMainWindow();
    mEmulatorWindow->simulateZoomedWindowResized(this->viewportSize());

    // To solve some resizing edge cases on OSX/Windows/KDE, start a short
    // timer that will attempt to trigger a resize in case the user's mouse has
    // not entered the window again. We use a longer timer on Linux because
    // the timer is not needed on non-KDE systems, so we want it to be less
    // noticeable.
#ifdef __linux__
    mResizeTimer.start(1000);
#else
    mResizeTimer.start(500);
#endif
}

void EmulatorContainer::showEvent(QShowEvent* event) {
// Disable to maximize button on OSX. See the comment in the constructor for an
// explanation of why this is necessary.
#ifdef __APPLE__
    WId wid = effectiveWinId();
    wid = (WId)getNSWindow((void*)wid);
    nsWindowHideWindowButtons((void*)wid);
#endif // __APPLE__

    // showEvent() gets called when the emulator is minimized because we are
    // calling showMinimized(), which *technically* is a show event. We only
    // want to re-show the toolbar when we are transitioning to a not-minimized
    // state. However, we must do it after changing flags on Linux.
    if (!(windowState() & Qt::WindowMinimized)) {
// As seen below in showMinimized(), we need to remove the minimize button on
// Linux when the window is re-shown. We know this show event is from being
// un-minimized because the minimized button flag is present.
#ifdef __linux__
        Qt::WindowFlags flags = windowFlags();
        if (flags & Qt::WindowMinimizeButtonHint) {
            setWindowFlags(flags & ~Qt::WindowMinimizeButtonHint);

            // Changing window flags requires re-showing this window to ensure
            // the flags are appropriately changed.
            showNormal();

            // The subwindow won't redraw until the guest screen changes, which
            // may not happen for a minute (when the clock changes), so force a
            // redraw after re-showing the window.
            SkinEvent* event = new SkinEvent();
            event->type = kEventForceRedraw;
            mEmulatorWindow->queueSkinEvent(event);
        }
#endif // __linux__
        mEmulatorWindow->toolWindow()->show();
        mEmulatorWindow->toolWindow()->dockMainWindow();
    }
}

void EmulatorContainer::showMinimized() {
// Some Linux window managers (specifically, Compiz, which is the default
// Ubuntu window manager) will not allow minimizing unless the minimize
// button is actually there! So, we re-add the button, minimize the window,
// and then remove the button when it gets reshown.
#ifdef __linux__
    setWindowFlags(windowFlags() | Qt::WindowMinimizeButtonHint);
#endif // __linux__
    QScrollArea::showMinimized();
}

void EmulatorContainer::stopResizeTimer() {
    mResizeTimer.stop();
}

QSize EmulatorContainer::viewportSize() const {
    QSize output = this->size();

    QScrollBar* vertical = this->verticalScrollBar();
    output.setWidth(output.width() -
                    (vertical->isVisible() ? vertical->width() : 0));

    QScrollBar* horizontal = this->horizontalScrollBar();
    output.setHeight(output.height() -
                     (horizontal->isVisible() ? horizontal->height() : 0));

    return output;
}

void EmulatorContainer::slot_resizeDone() {
    if (mEmulatorWindow->isInZoomMode()) {
        return;
    }

// Windows and Apple have convenient ways of checking global mouse state, so
// we'll only do a resize if no mouse buttons are held down.
#if defined(__APPLE__) || defined(_WIN32)
    // A hacky way of determining if the user is still holding down for a
    // resize.
    // This queries the global event state to see if any mouse buttons are held
    // down.
    // If there are, then the user must not be done resizing yet.
    if (numHeldMouseButtons() == 0) {
        mEmulatorWindow->doResize(this->size());
    } else {
        mResizeTimer.start(500);
    }
#endif

// X11 doesn't. Hope that the user isn't still holding down a mouse button, and
// if they are, oh well.
#ifdef __linux__
    mEmulatorWindow->doResize(this->size());
#endif
}
