/*
 * Copyright (C) 2006 Zack Rusin <zack@kde.org>
 * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "ChromeClientQt.h"

#include "ApplicationCacheStorage.h"
#include "DatabaseTracker.h"
#include "FileChooser.h"
#include "Frame.h"
#include "FrameLoadRequest.h"
#include "FrameLoader.h"
#include "FrameLoaderClientQt.h"
#include "FrameView.h"
#include "Geolocation.h"
#if USE(ACCELERATED_COMPOSITING)
#include "GraphicsLayer.h"
#endif
#include "HitTestResult.h"
#include "Icon.h"
#include "NavigationAction.h"
#include "NetworkingContext.h"
#include "NotImplemented.h"
#include "NotificationPresenterClientQt.h"
#include "PageClientQt.h"
#include "PopupMenuQt.h"
#if defined(Q_WS_MAEMO_5)
#include "QtMaemoWebPopup.h"
#else
#include "QtFallbackWebPopup.h"
#endif
#include "QWebPageClient.h"
#include "ScrollbarTheme.h"
#include "SearchPopupMenuQt.h"
#include "SecurityOrigin.h"
#include "ViewportArguments.h"
#include "WindowFeatures.h"

#include "qgraphicswebview.h"
#include "qwebframe_p.h"
#include "qwebpage.h"
#include "qwebpage_p.h"
#include "qwebsecurityorigin.h"
#include "qwebsecurityorigin_p.h"
#include "qwebview.h"
#include <qdebug.h>
#include <qeventloop.h>
#include <qtextdocument.h>
#include <qtooltip.h>
#include <wtf/OwnPtr.h>

#if ENABLE(VIDEO) && (USE(GSTREAMER) || USE(QT_MULTIMEDIA))
#include "FullScreenVideoQt.h"
#include "HTMLMediaElement.h"
#include "HTMLNames.h"
#include "HTMLVideoElement.h"
#if USE(QT_MULTIMEDIA)
#include "MediaPlayerPrivateQt.h"
#endif
#endif

namespace WebCore {

bool ChromeClientQt::dumpVisitedLinksCallbacks = false;

ChromeClientQt::ChromeClientQt(QWebPage* webPage)
    : m_webPage(webPage)
    , m_eventLoop(0)
#if ENABLE(VIDEO) && (USE(GSTREAMER) || USE(QT_MULTIMEDIA))
    , m_fullScreenVideo(0)
#endif
{
    toolBarsVisible = statusBarVisible = menuBarVisible = true;
}

ChromeClientQt::~ChromeClientQt()
{
    if (m_eventLoop)
        m_eventLoop->exit();

#if ENABLE(VIDEO) && (USE(GSTREAMER) || USE(QT_MULTIMEDIA))
    delete m_fullScreenVideo;
#endif
}

void ChromeClientQt::setWindowRect(const FloatRect& rect)
{
    if (!m_webPage)
        return;
    emit m_webPage->geometryChangeRequested(QRect(qRound(rect.x()), qRound(rect.y()),
                            qRound(rect.width()), qRound(rect.height())));
}

/*!
    windowRect represents the rect of the Window, including all interface elements
    like toolbars/scrollbars etc. It is used by the viewport meta tag as well as
    by the DOM Window object: outerHeight(), outerWidth(), screenX(), screenY().
*/
FloatRect ChromeClientQt::windowRect()
{
    if (!platformPageClient())
        return FloatRect();
    return platformPageClient()->windowRect();
}

FloatRect ChromeClientQt::pageRect()
{
    if (!m_webPage)
        return FloatRect();
    return FloatRect(QRectF(QPointF(0, 0), m_webPage->viewportSize()));
}

float ChromeClientQt::scaleFactor()
{
    if (!m_webPage)
        return 1;
    return m_webPage->d->pixelRatio;
}

void ChromeClientQt::focus()
{
    if (!m_webPage)
        return;
    QWidget* view = m_webPage->view();
    if (!view)
        return;

    view->setFocus();
}


void ChromeClientQt::unfocus()
{
    if (!m_webPage)
        return;
    QWidget* view = m_webPage->view();
    if (!view)
        return;
    view->clearFocus();
}

bool ChromeClientQt::canTakeFocus(FocusDirection)
{
    // This is called when cycling through links/focusable objects and we
    // reach the last focusable object. Then we want to claim that we can
    // take the focus to avoid wrapping.
    return true;
}

void ChromeClientQt::takeFocus(FocusDirection)
{
    // don't do anything. This is only called when cycling to links/focusable objects,
    // which in turn is called from focusNextPrevChild. We let focusNextPrevChild
    // call QWidget::focusNextPrevChild accordingly, so there is no need to do anything
    // here.
}


void ChromeClientQt::focusedNodeChanged(Node*)
{
}

void ChromeClientQt::focusedFrameChanged(Frame*)
{
}

Page* ChromeClientQt::createWindow(Frame*, const FrameLoadRequest& request, const WindowFeatures& features, const NavigationAction&)
{
    QWebPage* newPage = m_webPage->createWindow(features.dialog ? QWebPage::WebModalDialog : QWebPage::WebBrowserWindow);
    if (!newPage)
        return 0;

    // A call to QWebPage::mainFrame() implicitly creates the main frame.
    // Make sure it exists, as WebCore expects it when returning from this call.
    newPage->mainFrame();
    return newPage->d->page;
}

void ChromeClientQt::show()
{
    if (!m_webPage)
        return;
    QWidget* view = m_webPage->view();
    if (!view)
        return;
    view->window()->show();
}


bool ChromeClientQt::canRunModal()
{
    return true;
}


void ChromeClientQt::runModal()
{
    m_eventLoop = new QEventLoop();
    QEventLoop* eventLoop = m_eventLoop;
    m_eventLoop->exec();
    delete eventLoop;
}


void ChromeClientQt::setToolbarsVisible(bool visible)
{
    toolBarsVisible = visible;
    emit m_webPage->toolBarVisibilityChangeRequested(visible);
}


bool ChromeClientQt::toolbarsVisible()
{
    return toolBarsVisible;
}


void ChromeClientQt::setStatusbarVisible(bool visible)
{
    emit m_webPage->statusBarVisibilityChangeRequested(visible);
    statusBarVisible = visible;
}


bool ChromeClientQt::statusbarVisible()
{
    return statusBarVisible;
}


void ChromeClientQt::setScrollbarsVisible(bool)
{
    notImplemented();
}


bool ChromeClientQt::scrollbarsVisible()
{
    notImplemented();
    return true;
}


void ChromeClientQt::setMenubarVisible(bool visible)
{
    menuBarVisible = visible;
    emit m_webPage->menuBarVisibilityChangeRequested(visible);
}

bool ChromeClientQt::menubarVisible()
{
    return menuBarVisible;
}

void ChromeClientQt::setResizable(bool)
{
    notImplemented();
}

void ChromeClientQt::addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message,
                                         unsigned int lineNumber, const String& sourceID)
{
    QString x = message;
    QString y = sourceID;
    m_webPage->javaScriptConsoleMessage(x, lineNumber, y);
}

void ChromeClientQt::chromeDestroyed()
{
    delete this;
}

bool ChromeClientQt::canRunBeforeUnloadConfirmPanel()
{
    return true;
}

bool ChromeClientQt::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
{
    return runJavaScriptConfirm(frame, message);
}

void ChromeClientQt::closeWindowSoon()
{
    m_webPage->d->page->setGroupName(String());
    m_webPage->mainFrame()->d->frame->loader()->stopAllLoaders();
    emit m_webPage->windowCloseRequested();
}

void ChromeClientQt::runJavaScriptAlert(Frame* f, const String& msg)
{
    QString x = msg;
    QWebFrame* webFrame = qobject_cast<QWebFrame*>(f->loader()->networkingContext()->originatingObject());
    m_webPage->javaScriptAlert(webFrame, x);
}

bool ChromeClientQt::runJavaScriptConfirm(Frame* f, const String& msg)
{
    QString x = msg;
    QWebFrame* webFrame = qobject_cast<QWebFrame*>(f->loader()->networkingContext()->originatingObject());
    return m_webPage->javaScriptConfirm(webFrame, x);
}

bool ChromeClientQt::runJavaScriptPrompt(Frame* f, const String& message, const String& defaultValue, String& result)
{
    QString x = result;
    QWebFrame* webFrame = qobject_cast<QWebFrame*>(f->loader()->networkingContext()->originatingObject());
    bool rc = m_webPage->javaScriptPrompt(webFrame, (QString)message, (QString)defaultValue, &x);

    // Fix up a quirk in the QInputDialog class. If no input happened the string should be empty
    // but it is null. See https://bugs.webkit.org/show_bug.cgi?id=30914.
    if (rc && x.isNull())
        result = String("");
    else
        result = x;

    return rc;
}

void ChromeClientQt::setStatusbarText(const String& msg)
{
    QString x = msg;
    emit m_webPage->statusBarMessage(x);
}

bool ChromeClientQt::shouldInterruptJavaScript()
{
    bool shouldInterrupt = false;
    QMetaObject::invokeMethod(m_webPage, "shouldInterruptJavaScript", Qt::DirectConnection, Q_RETURN_ARG(bool, shouldInterrupt));
    return shouldInterrupt;
}

KeyboardUIMode ChromeClientQt::keyboardUIMode()
{
    return m_webPage->settings()->testAttribute(QWebSettings::LinksIncludedInFocusChain)
        ? KeyboardAccessTabsToLinks : KeyboardAccessDefault;
}

IntRect ChromeClientQt::windowResizerRect() const
{
#if defined(Q_WS_MAC)
    if (!m_webPage)
        return IntRect();

    QWebPageClient* pageClient = platformPageClient();
    if (!pageClient)
        return IntRect();

    QWidget* ownerWidget = pageClient->ownerWidget();
    if (!ownerWidget)
        return IntRect();

    QWidget* topLevelWidget = ownerWidget->window();
    QRect topLevelGeometry(topLevelWidget->geometry());

    // There's no API in Qt to query for the size of the resizer, so we assume
    // it has the same width and height as the scrollbar thickness.
    int scollbarThickness = ScrollbarTheme::nativeTheme()->scrollbarThickness();

    // There's no API in Qt to query for the position of the resizer. Sometimes
    // it's drawn by the system, and sometimes it's a QSizeGrip. For RTL locales
    // it might even be on the lower left side of the window, but in WebKit we
    // always draw scrollbars on the right hand side, so we assume this to be the
    // location when computing the resize rect to reserve for WebKit.
    QPoint resizeCornerTopLeft = ownerWidget->mapFrom(topLevelWidget,
            QPoint(topLevelGeometry.width(), topLevelGeometry.height())
            - QPoint(scollbarThickness, scollbarThickness));

    QRect resizeCornerRect = QRect(resizeCornerTopLeft, QSize(scollbarThickness, scollbarThickness));
    return resizeCornerRect.intersected(pageClient->geometryRelativeToOwnerWidget());
#else
    return IntRect();
#endif
}

void ChromeClientQt::invalidateWindow(const IntRect& windowRect, bool)
{
#if ENABLE(TILED_BACKING_STORE)
    if (platformPageClient()) {
        WebCore::TiledBackingStore* backingStore = QWebFramePrivate::core(m_webPage->mainFrame())->tiledBackingStore();
        if (!backingStore)
            return;
        backingStore->invalidate(windowRect);
    }
#else
    Q_UNUSED(windowRect);
#endif
}

void ChromeClientQt::invalidateContentsAndWindow(const IntRect& windowRect, bool immediate)
{
    // No double buffer, so only update the QWidget if content changed.
    if (platformPageClient()) {
        QRect rect(windowRect);
        rect = rect.intersected(QRect(QPoint(0, 0), m_webPage->viewportSize()));
        if (!rect.isEmpty())
            platformPageClient()->update(rect);
    }
    QMetaObject::invokeMethod(m_webPage, "repaintRequested", Qt::QueuedConnection, Q_ARG(QRect, windowRect));

    // FIXME: There is no "immediate" support for window painting.  This should be done always whenever the flag
    // is set.
}

void ChromeClientQt::invalidateContentsForSlowScroll(const IntRect& windowRect, bool immediate)
{
    invalidateContentsAndWindow(windowRect, immediate);
}

void ChromeClientQt::scroll(const IntSize& delta, const IntRect& scrollViewRect, const IntRect&)
{
    if (platformPageClient())
        platformPageClient()->scroll(delta.width(), delta.height(), scrollViewRect);
    emit m_webPage->scrollRequested(delta.width(), delta.height(), scrollViewRect);
}

#if ENABLE(TILED_BACKING_STORE)
void ChromeClientQt::delegatedScrollRequested(const IntPoint& point)
{
    QPoint currentPosition(m_webPage->mainFrame()->scrollPosition());
    emit m_webPage->scrollRequested(point.x() - currentPosition.x(), point.y() - currentPosition.y(), QRect(QPoint(0, 0), m_webPage->viewportSize()));
}
#endif

IntRect ChromeClientQt::windowToScreen(const IntRect& rect) const
{
    QWebPageClient* pageClient = platformPageClient();
    if (!pageClient)
        return rect;

    QWidget* ownerWidget = pageClient->ownerWidget();
    if (!ownerWidget)
       return rect;

    QRect screenRect(rect);
    screenRect.translate(ownerWidget->mapToGlobal(QPoint(0, 0)));

    return screenRect;
}

IntPoint ChromeClientQt::screenToWindow(const IntPoint& point) const
{
    QWebPageClient* pageClient = platformPageClient();
    if (!pageClient)
        return point;

    QWidget* ownerWidget = pageClient->ownerWidget();
    if (!ownerWidget)
        return point;

    return ownerWidget->mapFromGlobal(point);
}

PlatformPageClient ChromeClientQt::platformPageClient() const
{
    return m_webPage->d->client.get();
}

void ChromeClientQt::contentsSizeChanged(Frame* frame, const IntSize& size) const
{
    if (frame->loader()->networkingContext())
        QWebFramePrivate::kit(frame)->contentsSizeChanged(size);
}

void ChromeClientQt::mouseDidMoveOverElement(const HitTestResult& result, unsigned)
{
    TextDirection dir;
    if (result.absoluteLinkURL() != lastHoverURL
        || result.title(dir) != lastHoverTitle
        || result.textContent() != lastHoverContent) {
        lastHoverURL = result.absoluteLinkURL();
        lastHoverTitle = result.title(dir);
        lastHoverContent = result.textContent();
        emit m_webPage->linkHovered(lastHoverURL.string(),
                lastHoverTitle, lastHoverContent);
    }
}

void ChromeClientQt::setToolTip(const String &tip, TextDirection)
{
#ifndef QT_NO_TOOLTIP
    QWidget* view = m_webPage->view();
    if (!view)
        return;

    if (tip.isEmpty()) {
        view->setToolTip(QString());
        QToolTip::hideText();
    } else {
        QString dtip = QLatin1String("<p>") + Qt::escape(tip) + QLatin1String("</p>");
        view->setToolTip(dtip);
    }
#else
    Q_UNUSED(tip);
#endif
}

void ChromeClientQt::print(Frame* frame)
{
    emit m_webPage->printRequested(QWebFramePrivate::kit(frame));
}

#if ENABLE(DATABASE)
void ChromeClientQt::exceededDatabaseQuota(Frame* frame, const String& databaseName)
{
    quint64 quota = QWebSettings::offlineStorageDefaultQuota();

    if (!DatabaseTracker::tracker().hasEntryForOrigin(frame->document()->securityOrigin()))
        DatabaseTracker::tracker().setQuota(frame->document()->securityOrigin(), quota);

    emit m_webPage->databaseQuotaExceeded(QWebFramePrivate::kit(frame), databaseName);
}
#endif

#if ENABLE(OFFLINE_WEB_APPLICATIONS)
void ChromeClientQt::reachedMaxAppCacheSize(int64_t)
{
    // FIXME: Free some space.
    notImplemented();
}

void ChromeClientQt::reachedApplicationCacheOriginQuota(SecurityOrigin* origin)
{
    int64_t quota;
    quint64 defaultOriginQuota = WebCore::cacheStorage().defaultOriginQuota();

    QWebSecurityOriginPrivate* priv = new QWebSecurityOriginPrivate(origin);
    QWebSecurityOrigin* securityOrigin = new QWebSecurityOrigin(priv);

    if (!WebCore::cacheStorage().quotaForOrigin(origin, quota))
       WebCore::cacheStorage().storeUpdatedQuotaForOrigin(origin, defaultOriginQuota);

    emit m_webPage->applicationCacheQuotaExceeded(securityOrigin, defaultOriginQuota);
}
#endif

#if ENABLE(NOTIFICATIONS)
NotificationPresenter* ChromeClientQt::notificationPresenter() const
{
    return NotificationPresenterClientQt::notificationPresenter();
}
#endif

void ChromeClientQt::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> prpFileChooser)
{
    RefPtr<FileChooser> fileChooser = prpFileChooser;
    bool supportMulti = m_webPage->supportsExtension(QWebPage::ChooseMultipleFilesExtension);

    if (fileChooser->allowsMultipleFiles() && supportMulti) {
        QWebPage::ChooseMultipleFilesExtensionOption option;
        option.parentFrame = QWebFramePrivate::kit(frame);

        if (!fileChooser->filenames().isEmpty())
            for (unsigned i = 0; i < fileChooser->filenames().size(); ++i)
                option.suggestedFileNames += fileChooser->filenames()[i];

        QWebPage::ChooseMultipleFilesExtensionReturn output;
        m_webPage->extension(QWebPage::ChooseMultipleFilesExtension, &option, &output);

        if (!output.fileNames.isEmpty()) {
            Vector<String> names;
            for (int i = 0; i < output.fileNames.count(); ++i)
                names.append(output.fileNames.at(i));
            fileChooser->chooseFiles(names);
        }
    } else {
        QString suggestedFile;
        if (!fileChooser->filenames().isEmpty())
            suggestedFile = fileChooser->filenames()[0];
        QString file = m_webPage->chooseFile(QWebFramePrivate::kit(frame), suggestedFile);
        if (!file.isEmpty())
            fileChooser->chooseFile(file);
    }
}

void ChromeClientQt::chooseIconForFiles(const Vector<String>& filenames, FileChooser* chooser)
{
    chooser->iconLoaded(Icon::createIconForFiles(filenames));
}

void ChromeClientQt::setCursor(const Cursor& cursor)
{
#ifndef QT_NO_CURSOR
    QWebPageClient* pageClient = platformPageClient();
    if (!pageClient)
        return;
    pageClient->setCursor(*cursor.platformCursor());
#else
    UNUSED_PARAM(cursor);
#endif
}


#if USE(ACCELERATED_COMPOSITING)
void ChromeClientQt::attachRootGraphicsLayer(Frame* frame, GraphicsLayer* graphicsLayer)
{
    if (platformPageClient())
        platformPageClient()->setRootGraphicsLayer(graphicsLayer ? graphicsLayer->platformLayer() : 0);
}

void ChromeClientQt::setNeedsOneShotDrawingSynchronization()
{
    // we want the layers to synchronize next time we update the screen anyway
    if (platformPageClient())
        platformPageClient()->markForSync(false);
}

void ChromeClientQt::scheduleCompositingLayerSync()
{
    // we want the layers to synchronize ASAP
    if (platformPageClient())
        platformPageClient()->markForSync(true);
}

ChromeClient::CompositingTriggerFlags ChromeClientQt::allowedCompositingTriggers() const
{
    if (platformPageClient() && platformPageClient()->allowsAcceleratedCompositing())
        return AllTriggers;

    return 0;
}

#endif

#if ENABLE(TILED_BACKING_STORE)
IntRect ChromeClientQt::visibleRectForTiledBackingStore() const
{
    if (!platformPageClient() || !m_webPage)
        return IntRect();

    if (!platformPageClient()->viewResizesToContentsEnabled())
        return QRect(m_webPage->mainFrame()->scrollPosition(), m_webPage->mainFrame()->geometry().size());

    return enclosingIntRect(FloatRect(platformPageClient()->graphicsItemVisibleRect()));
}
#endif

#if ENABLE(VIDEO) && (USE(GSTREAMER) || USE(QT_MULTIMEDIA))
FullScreenVideoQt* ChromeClientQt::fullScreenVideo()
{
    if (!m_fullScreenVideo)
        m_fullScreenVideo = new FullScreenVideoQt(this);
    return m_fullScreenVideo;
}

bool ChromeClientQt::supportsFullscreenForNode(const Node* node)
{
    ASSERT(node);
    return node->hasTagName(HTMLNames::videoTag) && fullScreenVideo()->isValid();
}

bool ChromeClientQt::requiresFullscreenForVideoPlayback()
{
    return fullScreenVideo()->requiresFullScreenForVideoPlayback();
}

void ChromeClientQt::enterFullscreenForNode(Node* node)
{
    ASSERT(node && node->hasTagName(HTMLNames::videoTag));

    fullScreenVideo()->enterFullScreenForNode(node);
}

void ChromeClientQt::exitFullscreenForNode(Node* node)
{
    ASSERT(node && node->hasTagName(HTMLNames::videoTag));

    fullScreenVideo()->exitFullScreenForNode(node);
} 
#endif

QWebSelectMethod* ChromeClientQt::createSelectPopup() const
{
    QWebSelectMethod* result = m_platformPlugin.createSelectInputMethod();
    if (result)
        return result;

#if defined(Q_WS_MAEMO_5)
    return new QtMaemoWebPopup;
#elif !defined(QT_NO_COMBOBOX)
    return new QtFallbackWebPopup(this);
#else
    return 0;
#endif
}

void ChromeClientQt::dispatchViewportDataDidChange(const ViewportArguments&) const
{
    emit m_webPage->viewportChangeRequested();
}

bool ChromeClientQt::selectItemWritingDirectionIsNatural()
{
    return false;
}

bool ChromeClientQt::selectItemAlignmentFollowsMenuWritingDirection()
{
    return false;
}

PassRefPtr<PopupMenu> ChromeClientQt::createPopupMenu(PopupMenuClient* client) const
{
    return adoptRef(new PopupMenuQt(client, this));
}

PassRefPtr<SearchPopupMenu> ChromeClientQt::createSearchPopupMenu(PopupMenuClient* client) const
{
    return adoptRef(new SearchPopupMenuQt(createPopupMenu(client)));
}

void ChromeClientQt::populateVisitedLinks()
{
    // We don't need to do anything here because history is tied to QWebPage rather than stored
    // in a separate database
    if (dumpVisitedLinksCallbacks) {
        printf("Asked to populate visited links for WebView \"%s\"\n",
                qPrintable(m_webPage->mainFrame()->url().toString()));
    }
}

} // namespace WebCore
