/*
 * Copyright (C) 2010 Apple Inc. 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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 "WebView.h"

#include "DrawingAreaProxyImpl.h"
#include "FindIndicator.h"
#include "Logging.h"
#include "NativeWebKeyboardEvent.h"
#include "NativeWebMouseEvent.h"
#include "NativeWebWheelEvent.h"
#include "WKAPICast.h"
#include "WebContext.h"
#include "WebContextMenuProxyWin.h"
#include "WebEditCommandProxy.h"
#include "WebEventFactory.h"
#include "WebPageProxy.h"
#include "WebPopupMenuProxyWin.h"
#include <Commctrl.h>
#include <WebCore/BitmapInfo.h>
#include <WebCore/Cursor.h>
#include <WebCore/DragSession.h>
#include <WebCore/Editor.h>
#include <WebCore/FileSystem.h>
#include <WebCore/FloatRect.h>
#include <WebCore/HWndDC.h>
#include <WebCore/IntRect.h>
#include <WebCore/NotImplemented.h>
#include <WebCore/Region.h>
#include <WebCore/RunLoop.h>
#include <WebCore/SoftLinking.h>
#include <WebCore/WebCoreInstanceHandle.h>
#include <WebCore/WindowMessageBroadcaster.h>
#include <WebCore/WindowsTouch.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/text/WTFString.h>

#if USE(CG)
#include "WKCACFViewWindow.h"
#include <WebCore/GraphicsContextCG.h>
#endif

#if ENABLE(FULLSCREEN_API)
#include "WebFullScreenManagerProxy.h"
#include <WebCore/FullScreenController.h>
#endif

namespace Ime {
// We need these functions in a separate namespace, because in the global namespace they conflict
// with the definitions in imm.h only by the type modifier (the macro defines them as static) and
// imm.h is included by windows.h
SOFT_LINK_LIBRARY(IMM32)
SOFT_LINK(IMM32, ImmGetContext, HIMC, WINAPI, (HWND hwnd), (hwnd))
SOFT_LINK(IMM32, ImmReleaseContext, BOOL, WINAPI, (HWND hWnd, HIMC hIMC), (hWnd, hIMC))
SOFT_LINK(IMM32, ImmGetCompositionStringW, LONG, WINAPI, (HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen), (hIMC, dwIndex, lpBuf, dwBufLen))
SOFT_LINK(IMM32, ImmSetCandidateWindow, BOOL, WINAPI, (HIMC hIMC, LPCANDIDATEFORM lpCandidate), (hIMC, lpCandidate))
SOFT_LINK(IMM32, ImmSetOpenStatus, BOOL, WINAPI, (HIMC hIMC, BOOL fOpen), (hIMC, fOpen))
SOFT_LINK(IMM32, ImmNotifyIME, BOOL, WINAPI, (HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue), (hIMC, dwAction, dwIndex, dwValue))
SOFT_LINK(IMM32, ImmAssociateContextEx, BOOL, WINAPI, (HWND hWnd, HIMC hIMC, DWORD dwFlags), (hWnd, hIMC, dwFlags))
};

// Soft link functions for gestures and panning.
SOFT_LINK_LIBRARY(USER32);
SOFT_LINK_OPTIONAL(USER32, GetGestureInfo, BOOL, WINAPI, (HGESTUREINFO, PGESTUREINFO));
SOFT_LINK_OPTIONAL(USER32, SetGestureConfig, BOOL, WINAPI, (HWND, DWORD, UINT, PGESTURECONFIG, UINT));
SOFT_LINK_OPTIONAL(USER32, CloseGestureInfoHandle, BOOL, WINAPI, (HGESTUREINFO));

SOFT_LINK_LIBRARY(Uxtheme);
SOFT_LINK_OPTIONAL(Uxtheme, BeginPanningFeedback, BOOL, WINAPI, (HWND));
SOFT_LINK_OPTIONAL(Uxtheme, EndPanningFeedback, BOOL, WINAPI, (HWND, BOOL));
SOFT_LINK_OPTIONAL(Uxtheme, UpdatePanningFeedback, BOOL, WINAPI, (HWND, LONG, LONG, BOOL));

using namespace WebCore;

namespace WebKit {

static const LPCWSTR kWebKit2WebViewWindowClassName = L"WebKit2WebViewWindowClass";

// Constants not available on all platforms.
const int WM_XP_THEMECHANGED = 0x031A;
const int WM_VISTA_MOUSEHWHEEL = 0x020E;

static const int kMaxToolTipWidth = 250;

enum {
    UpdateActiveStateTimer = 1,
};

LRESULT CALLBACK WebView::WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    LONG_PTR longPtr = ::GetWindowLongPtr(hWnd, 0);
    
    if (WebView* webView = reinterpret_cast<WebView*>(longPtr))
        return webView->wndProc(hWnd, message, wParam, lParam);

    if (message == WM_CREATE) {
        LPCREATESTRUCT createStruct = reinterpret_cast<LPCREATESTRUCT>(lParam);

        // Associate the WebView with the window.
        ::SetWindowLongPtr(hWnd, 0, (LONG_PTR)createStruct->lpCreateParams);
        return 0;
    }

    return ::DefWindowProc(hWnd, message, wParam, lParam);
}

LRESULT WebView::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    LRESULT lResult = 0;
    bool handled = true;

    switch (message) {
    case WM_CLOSE:
        m_page->tryClose();
        break;
    case WM_DESTROY:
        m_isBeingDestroyed = true;
        close();
        break;
    case WM_ERASEBKGND:
        lResult = 1;
        break;
    case WM_PAINT:
        lResult = onPaintEvent(hWnd, message, wParam, lParam, handled);
        break;
    case WM_PRINTCLIENT:
        lResult = onPrintClientEvent(hWnd, message, wParam, lParam, handled);
        break;
    case WM_MOUSEACTIVATE:
        setWasActivatedByMouseEvent(true);
        handled = false;
        break;
    case WM_MOUSEMOVE:
    case WM_LBUTTONDOWN:
    case WM_MBUTTONDOWN:
    case WM_RBUTTONDOWN:
    case WM_LBUTTONDBLCLK:
    case WM_MBUTTONDBLCLK:
    case WM_RBUTTONDBLCLK:
    case WM_LBUTTONUP:
    case WM_MBUTTONUP:
    case WM_RBUTTONUP:
    case WM_MOUSELEAVE:
        lResult = onMouseEvent(hWnd, message, wParam, lParam, handled);
        break;
    case WM_MOUSEWHEEL:
    case WM_VISTA_MOUSEHWHEEL:
        lResult = onWheelEvent(hWnd, message, wParam, lParam, handled);
        break;
    case WM_HSCROLL:
        lResult = onHorizontalScroll(hWnd, message, wParam, lParam, handled);
        break;
    case WM_VSCROLL:
        lResult = onVerticalScroll(hWnd, message, wParam, lParam, handled);
        break;
    case WM_GESTURENOTIFY:
        lResult = onGestureNotify(hWnd, message, wParam, lParam, handled);
        break;
    case WM_GESTURE:
        lResult = onGesture(hWnd, message, wParam, lParam, handled);
        break;
    case WM_SYSKEYDOWN:
    case WM_KEYDOWN:
    case WM_SYSCHAR:
    case WM_CHAR:
    case WM_SYSKEYUP:
    case WM_KEYUP:
        lResult = onKeyEvent(hWnd, message, wParam, lParam, handled);
        break;
    case WM_SIZE:
        lResult = onSizeEvent(hWnd, message, wParam, lParam, handled);
        break;
    case WM_WINDOWPOSCHANGED:
        lResult = onWindowPositionChangedEvent(hWnd, message, wParam, lParam, handled);
        break;
    case WM_SETFOCUS:
        lResult = onSetFocusEvent(hWnd, message, wParam, lParam, handled);
        break;
    case WM_KILLFOCUS:
        lResult = onKillFocusEvent(hWnd, message, wParam, lParam, handled);
        break;
    case WM_TIMER:
        lResult = onTimerEvent(hWnd, message, wParam, lParam, handled);
        break;
    case WM_SHOWWINDOW:
        lResult = onShowWindowEvent(hWnd, message, wParam, lParam, handled);
        break;
    case WM_SETCURSOR:
        lResult = onSetCursor(hWnd, message, wParam, lParam, handled);
        break;
    case WM_IME_STARTCOMPOSITION:
        handled = onIMEStartComposition();
        break;
    case WM_IME_REQUEST:
        lResult = onIMERequest(wParam, lParam);
        break;
    case WM_IME_COMPOSITION:
        handled = onIMEComposition(lParam);
        break;
    case WM_IME_ENDCOMPOSITION:
        handled = onIMEEndComposition();
        break;
    case WM_IME_SELECT:
        handled = onIMESelect(wParam, lParam);
        break;
    case WM_IME_SETCONTEXT:
        handled = onIMESetContext(wParam, lParam);
        break;
    default:
        handled = false;
        break;
    }

    if (!handled)
        lResult = ::DefWindowProc(hWnd, message, wParam, lParam);

    return lResult;
}

bool WebView::registerWebViewWindowClass()
{
    static bool haveRegisteredWindowClass = false;
    if (haveRegisteredWindowClass)
        return true;
    haveRegisteredWindowClass = true;

    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style          = CS_DBLCLKS;
    wcex.lpfnWndProc    = WebView::WebViewWndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = sizeof(WebView*);
    wcex.hInstance      = instanceHandle();
    wcex.hIcon          = 0;
    wcex.hCursor        = ::LoadCursor(0, IDC_ARROW);
    wcex.hbrBackground  = 0;
    wcex.lpszMenuName   = 0;
    wcex.lpszClassName  = kWebKit2WebViewWindowClassName;
    wcex.hIconSm        = 0;

    return !!::RegisterClassEx(&wcex);
}

WebView::WebView(RECT rect, WebContext* context, WebPageGroup* pageGroup, HWND parentWindow)
    : m_topLevelParentWindow(0)
    , m_toolTipWindow(0)
    , m_lastCursorSet(0)
    , m_webCoreCursor(0)
    , m_overrideCursor(0)
    , m_trackingMouseLeave(false)
    , m_isInWindow(false)
    , m_isVisible(false)
    , m_wasActivatedByMouseEvent(false)
    , m_isBeingDestroyed(false)
    , m_inIMEComposition(0)
    , m_findIndicatorCallback(0)
    , m_findIndicatorCallbackContext(0)
    , m_pageOverlayInstalled(false)
    , m_lastPanX(0)
    , m_lastPanY(0)
    , m_overPanY(0)
    , m_gestureReachedScrollingLimit(false)
#if USE(ACCELERATED_COMPOSITING)
    , m_layerHostWindow(0)
#endif
{
    registerWebViewWindowClass();

    m_window = ::CreateWindowExW(0, kWebKit2WebViewWindowClassName, 0, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE,
        rect.top, rect.left, rect.right - rect.left, rect.bottom - rect.top, parentWindow ? parentWindow : HWND_MESSAGE, 0, instanceHandle(), this);
    ASSERT(::IsWindow(m_window));
    // We only check our window style, and not ::IsWindowVisible, because m_isVisible only tracks
    // this window's visibility status, while ::IsWindowVisible takes our ancestors' visibility
    // status into account. <http://webkit.org/b/54104>
    ASSERT(m_isVisible == static_cast<bool>(::GetWindowLong(m_window, GWL_STYLE) & WS_VISIBLE));

    m_page = context->createWebPage(this, pageGroup);
    m_page->initializeWebPage();

    CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, (void**)&m_dropTargetHelper);

    // FIXME: Initializing the tooltip window here matches WebKit win, but seems like something
    // we could do on demand to save resources.
    initializeToolTipWindow();

    // Initialize the top level parent window and register it with the WindowMessageBroadcaster.
    windowAncestryDidChange();

#if ENABLE(FULLSCREEN_API)
    m_page->fullScreenManager()->setWebView(this);
#endif
}

WebView::~WebView()
{
    // Tooltip window needs to be explicitly destroyed since it isn't a WS_CHILD.
    if (::IsWindow(m_toolTipWindow))
        ::DestroyWindow(m_toolTipWindow);
}

void WebView::initialize()
{
    ::RegisterDragDrop(m_window, this);

    if (shouldInitializeTrackPointHack()) {
        // If we detected a registry key belonging to a TrackPoint driver, then create fake
        // scrollbars, so the WebView will receive WM_VSCROLL and WM_HSCROLL messages.
        // We create an invisible vertical scrollbar and an invisible horizontal scrollbar to allow
        // for receiving both types of messages.
        ::CreateWindow(TEXT("SCROLLBAR"), TEXT("FAKETRACKPOINTHSCROLLBAR"), WS_CHILD | WS_VISIBLE | SBS_HORZ, 0, 0, 0, 0, m_window, 0, instanceHandle(), 0);
        ::CreateWindow(TEXT("SCROLLBAR"), TEXT("FAKETRACKPOINTVSCROLLBAR"), WS_CHILD | WS_VISIBLE | SBS_VERT, 0, 0, 0, 0, m_window, 0, instanceHandle(), 0);
    }
}

void WebView::initializeUndoClient(const WKViewUndoClient* client)
{
    m_undoClient.initialize(client);
}

void WebView::setParentWindow(HWND parentWindow)
{
    if (m_window) {
        // If the host window hasn't changed, bail.
        if (::GetParent(m_window) == parentWindow)
            return;
        if (parentWindow)
            ::SetParent(m_window, parentWindow);
        else if (!m_isBeingDestroyed) {
            // Turn the WebView into a message-only window so it will no longer be a child of the
            // old parent window and will be hidden from screen. We only do this when
            // isBeingDestroyed() is false because doing this while handling WM_DESTROY can leave
            // m_window in a weird state (see <http://webkit.org/b/29337>).
            ::SetParent(m_window, HWND_MESSAGE);
        }
    }

    windowAncestryDidChange();
}

static HWND findTopLevelParentWindow(HWND window)
{
    if (!window)
        return 0;

    HWND current = window;
    for (HWND parent = GetParent(current); current; current = parent, parent = GetParent(parent)) {
        if (!parent || !(GetWindowLongPtr(current, GWL_STYLE) & (WS_POPUP | WS_CHILD)))
            return current;
    }
    ASSERT_NOT_REACHED();
    return 0;
}

void WebView::windowAncestryDidChange()
{
    HWND newTopLevelParentWindow;
    if (m_window)
        newTopLevelParentWindow = findTopLevelParentWindow(m_window);
    else {
        // There's no point in tracking active state changes of our parent window if we don't have
        // a window ourselves.
        newTopLevelParentWindow = 0;
    }

    if (newTopLevelParentWindow == m_topLevelParentWindow)
        return;

    if (m_topLevelParentWindow)
        WindowMessageBroadcaster::removeListener(m_topLevelParentWindow, this);

    m_topLevelParentWindow = newTopLevelParentWindow;

    if (m_topLevelParentWindow)
        WindowMessageBroadcaster::addListener(m_topLevelParentWindow, this);

    updateActiveState();
}

LRESULT WebView::onMouseEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
{
    NativeWebMouseEvent mouseEvent = NativeWebMouseEvent(hWnd, message, wParam, lParam, m_wasActivatedByMouseEvent);
    setWasActivatedByMouseEvent(false);
    
    switch (message) {
    case WM_LBUTTONDOWN:
    case WM_MBUTTONDOWN:
    case WM_RBUTTONDOWN:
        ::SetFocus(m_window);
        ::SetCapture(m_window);
        break; 
    case WM_LBUTTONUP:
    case WM_MBUTTONUP:
    case WM_RBUTTONUP:
        ::ReleaseCapture();
        break;
    case WM_MOUSEMOVE:
        startTrackingMouseLeave();
        break;
    case WM_MOUSELEAVE:
        stopTrackingMouseLeave();
        break;
    case WM_LBUTTONDBLCLK:
    case WM_MBUTTONDBLCLK:
    case WM_RBUTTONDBLCLK:
        break;
    default:
        ASSERT_NOT_REACHED();
    }

    m_page->handleMouseEvent(mouseEvent);

    handled = true;
    return 0;
}

LRESULT WebView::onWheelEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
{
    NativeWebWheelEvent wheelEvent(hWnd, message, wParam, lParam);
    if (wheelEvent.controlKey()) {
        // We do not want WebKit to handle Control + Wheel, this should be handled by the client application
        // to zoom the page.
        handled = false;
        return 0;
    }

    m_page->handleWheelEvent(wheelEvent);

    handled = true;
    return 0;
}

LRESULT WebView::onHorizontalScroll(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
{
    ScrollDirection direction;
    ScrollGranularity granularity;
    switch (LOWORD(wParam)) {
    case SB_LINELEFT:
        granularity = ScrollByLine;
        direction = ScrollLeft;
        break;
    case SB_LINERIGHT:
        granularity = ScrollByLine;
        direction = ScrollRight;
        break;
    case SB_PAGELEFT:
        granularity = ScrollByDocument;
        direction = ScrollLeft;
        break;
    case SB_PAGERIGHT:
        granularity = ScrollByDocument;
        direction = ScrollRight;
        break;
    default:
        handled = false;
        return 0;
    }

    m_page->scrollBy(direction, granularity);

    handled = true;
    return 0;
}

LRESULT WebView::onVerticalScroll(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
{
    ScrollDirection direction;
    ScrollGranularity granularity;
    switch (LOWORD(wParam)) {
    case SB_LINEDOWN:
        granularity = ScrollByLine;
        direction = ScrollDown;
        break;
    case SB_LINEUP:
        granularity = ScrollByLine;
        direction = ScrollUp;
        break;
    case SB_PAGEDOWN:
        granularity = ScrollByDocument;
        direction = ScrollDown;
        break;
    case SB_PAGEUP:
        granularity = ScrollByDocument;
        direction = ScrollUp;
        break;
    default:
        handled = false;
        return 0;
    }

    m_page->scrollBy(direction, granularity);

    handled = true;
    return 0;
}

LRESULT WebView::onGestureNotify(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
{
    // We shouldn't be getting any gesture messages without SetGestureConfig soft-linking correctly.
    ASSERT(SetGestureConfigPtr());

    GESTURENOTIFYSTRUCT* gn = reinterpret_cast<GESTURENOTIFYSTRUCT*>(lParam);

    POINT localPoint = { gn->ptsLocation.x, gn->ptsLocation.y };
    ::ScreenToClient(m_window, &localPoint);

    bool canPan = m_page->gestureWillBegin(localPoint);

    DWORD dwPanWant = GC_PAN | GC_PAN_WITH_INERTIA | GC_PAN_WITH_GUTTER;
    DWORD dwPanBlock = GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY;
    if (canPan)
        dwPanWant |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY;
    else
        dwPanBlock |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY;

    GESTURECONFIG gc = { GID_PAN, dwPanWant, dwPanBlock };
    return SetGestureConfigPtr()(m_window, 0, 1, &gc, sizeof(gc));
}

LRESULT WebView::onGesture(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
{
    ASSERT(GetGestureInfoPtr());
    ASSERT(CloseGestureInfoHandlePtr());
    ASSERT(UpdatePanningFeedbackPtr());
    ASSERT(BeginPanningFeedbackPtr());
    ASSERT(EndPanningFeedbackPtr());

    if (!GetGestureInfoPtr() || !CloseGestureInfoHandlePtr() || !UpdatePanningFeedbackPtr() || !BeginPanningFeedbackPtr() || !EndPanningFeedbackPtr()) {
        handled = false;
        return 0;
    }

    HGESTUREINFO gestureHandle = reinterpret_cast<HGESTUREINFO>(lParam);
    GESTUREINFO gi = {0};
    gi.cbSize = sizeof(GESTUREINFO);

    if (!GetGestureInfoPtr()(gestureHandle, &gi)) {
        handled = false;
        return 0;
    }

    switch (gi.dwID) {
    case GID_BEGIN:
        m_lastPanX = gi.ptsLocation.x;
        m_lastPanY = gi.ptsLocation.y;
        break;
    case GID_END:
        m_page->gestureDidEnd();
        break;
    case GID_PAN: {
        int currentX = gi.ptsLocation.x;
        int currentY = gi.ptsLocation.y;

        // Reverse the calculations because moving your fingers up should move the screen down, and
        // vice-versa.
        int deltaX = m_lastPanX - currentX;
        int deltaY = m_lastPanY - currentY;

        m_lastPanX = currentX;
        m_lastPanY = currentY;

        // Calculate the overpan for window bounce.
        m_overPanY -= deltaY;

        if (deltaX || deltaY)
            m_page->gestureDidScroll(IntSize(deltaX, deltaY));

        if (gi.dwFlags & GF_BEGIN) {
            BeginPanningFeedbackPtr()(m_window);
            m_gestureReachedScrollingLimit = false;
            m_overPanY = 0;
        } else if (gi.dwFlags & GF_END) {
            EndPanningFeedbackPtr()(m_window, true);
            m_overPanY = 0;
        }

        // FIXME: Support horizontal window bounce - <http://webkit.org/b/58068>.
        // FIXME: Window Bounce doesn't undo until user releases their finger - <http://webkit.org/b/58069>.

        if (m_gestureReachedScrollingLimit)
            UpdatePanningFeedbackPtr()(m_window, 0, m_overPanY, gi.dwFlags & GF_INERTIA);

        CloseGestureInfoHandlePtr()(gestureHandle);

        handled = true;
        return 0;
    }
    default:
        break;
    }

    // If we get to this point, the gesture has not been handled. We forward
    // the call to DefWindowProc by returning false, and we don't need to 
    // to call CloseGestureInfoHandle. 
    // http://msdn.microsoft.com/en-us/library/dd353228(VS.85).aspx
    handled = false;
    return 0;
}

LRESULT WebView::onKeyEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
{
#if ENABLE(FULLSCREEN_API)
    // Trap the ESC key when in full screen mode.
    if (message == WM_KEYDOWN && wParam == VK_ESCAPE && m_fullScreenController && m_fullScreenController->isFullScreen()) {
        m_fullScreenController->exitFullScreen();
        return false;
    }
#endif

    m_page->handleKeyboardEvent(NativeWebKeyboardEvent(hWnd, message, wParam, lParam));

    // We claim here to always have handled the event. If the event is not in fact handled, we will
    // find out later in didNotHandleKeyEvent.
    handled = true;
    return 0;
}

static void drawPageBackground(HDC dc, const WebPageProxy* page, const RECT& rect)
{
    if (!page->drawsBackground() || page->drawsTransparentBackground())
        return;

    ::FillRect(dc, &rect, reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1));
}

void WebView::paint(HDC hdc, const IntRect& dirtyRect)
{
    m_page->endPrinting();
    if (DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(m_page->drawingArea())) {
        // FIXME: We should port WebKit1's rect coalescing logic here.
        Region unpaintedRegion;
        drawingArea->paint(hdc, dirtyRect, unpaintedRegion);

        Vector<IntRect> unpaintedRects = unpaintedRegion.rects();
        for (size_t i = 0; i < unpaintedRects.size(); ++i) {
            RECT winRect = unpaintedRects[i];
            drawPageBackground(hdc, m_page.get(), unpaintedRects[i]);
        }
    } else
        drawPageBackground(hdc, m_page.get(), dirtyRect);

    m_page->didDraw();
}

static void flashRects(HDC dc, const IntRect rects[], size_t rectCount, HBRUSH brush)
{
    for (size_t i = 0; i < rectCount; ++i) {
        RECT winRect = rects[i];
        ::FillRect(dc, &winRect, brush);
    }

    ::GdiFlush();
    ::Sleep(50);
}

static OwnPtr<HBRUSH> createBrush(const Color& color)
{
    return adoptPtr(::CreateSolidBrush(RGB(color.red(), color.green(), color.blue())));
}

LRESULT WebView::onPaintEvent(HWND hWnd, UINT message, WPARAM, LPARAM, bool& handled)
{
    // Update child windows now so that any areas of our window they reveal will be included in the
    // invalid region that ::BeginPaint sees.
    updateChildWindowGeometries();

    PAINTSTRUCT paintStruct;
    HDC hdc = ::BeginPaint(m_window, &paintStruct);

    if (WebPageProxy::debugPaintFlags() & kWKDebugFlashViewUpdates) {
        static HBRUSH brush = createBrush(WebPageProxy::viewUpdatesFlashColor().rgb()).leakPtr();
        IntRect rect = paintStruct.rcPaint;
        flashRects(hdc, &rect, 1, brush);
    }

    paint(hdc, paintStruct.rcPaint);

    ::EndPaint(m_window, &paintStruct);

    handled = true;
    return 0;
}

LRESULT WebView::onPrintClientEvent(HWND hWnd, UINT, WPARAM wParam, LPARAM, bool& handled)
{
    HDC hdc = reinterpret_cast<HDC>(wParam);
    RECT winRect;
    ::GetClientRect(hWnd, &winRect);

    // Twidding the visibility flags tells the DrawingArea to resume painting. Right now, the
    // the visible state of the view only affects whether or not painting happens, but in the
    // future it could affect more, which we wouldn't want to touch here.

    // FIXME: We should have a better way of telling the WebProcess to draw even if we're
    // invisible than twiddling the visibility flag.

    bool wasVisible = isViewVisible();
    if (!wasVisible)
        setIsVisible(true);

    paint(hdc, winRect);

    if (!wasVisible)
        setIsVisible(false);

    handled = true;
    return 0;
}

LRESULT WebView::onSizeEvent(HWND, UINT, WPARAM, LPARAM lParam, bool& handled)
{
    int width = LOWORD(lParam);
    int height = HIWORD(lParam);

    if (m_page && m_page->drawingArea()) {
        m_page->drawingArea()->setSize(IntSize(width, height), m_nextResizeScrollOffset);
        m_nextResizeScrollOffset = IntSize();
    }

#if USE(ACCELERATED_COMPOSITING)
    if (m_layerHostWindow)
        ::MoveWindow(m_layerHostWindow, 0, 0, width, height, FALSE);
#endif

    handled = true;
    return 0;
}

LRESULT WebView::onWindowPositionChangedEvent(HWND, UINT, WPARAM, LPARAM lParam, bool& handled)
{
    if (reinterpret_cast<WINDOWPOS*>(lParam)->flags & SWP_SHOWWINDOW)
        updateActiveStateSoon();

    handled = false;
    return 0;
}

LRESULT WebView::onSetFocusEvent(HWND, UINT, WPARAM, LPARAM lParam, bool& handled)
{
    m_page->viewStateDidChange(WebPageProxy::ViewIsFocused);
    handled = true;
    return 0;
}

LRESULT WebView::onKillFocusEvent(HWND, UINT, WPARAM, LPARAM lParam, bool& handled)
{
    m_page->viewStateDidChange(WebPageProxy::ViewIsFocused);
    handled = true;
    return 0;
}

LRESULT WebView::onTimerEvent(HWND hWnd, UINT, WPARAM wParam, LPARAM, bool& handled)
{
    switch (wParam) {
    case UpdateActiveStateTimer:
        ::KillTimer(hWnd, UpdateActiveStateTimer);
        updateActiveState();
        break;
    }

    handled = true;
    return 0;
}

LRESULT WebView::onShowWindowEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
{
    // lParam is 0 when the message is sent because of a ShowWindow call.
    // FIXME: Since we don't get notified when an ancestor window is hidden or shown, we will keep
    // painting even when we have a hidden ancestor. <http://webkit.org/b/54104>
    if (!lParam)
        setIsVisible(wParam);

    handled = false;
    return 0;
}

LRESULT WebView::onSetCursor(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
{
    if (!m_lastCursorSet) {
        handled = false;
        return 0;
    }

    ::SetCursor(m_lastCursorSet);
    return 0;
}

void WebView::updateActiveState()
{
    m_page->viewStateDidChange(WebPageProxy::ViewWindowIsActive);
}

void WebView::updateActiveStateSoon()
{
    // This function is called while processing the WM_NCACTIVATE message.
    // While processing WM_NCACTIVATE when we are being deactivated, GetActiveWindow() will
    // still return our window. If we were to call updateActiveState() in that case, we would
    // wrongly think that we are still the active window. To work around this, we update our
    // active state after a 0-delay timer fires, at which point GetActiveWindow() will return
    // the newly-activated window.

    ::SetTimer(m_window, UpdateActiveStateTimer, 0, 0);
}

static bool initCommonControls()
{
    static bool haveInitialized = false;
    if (haveInitialized)
        return true;

    INITCOMMONCONTROLSEX init;
    init.dwSize = sizeof(init);
    init.dwICC = ICC_TREEVIEW_CLASSES;
    haveInitialized = !!::InitCommonControlsEx(&init);
    return haveInitialized;
}

void WebView::initializeToolTipWindow()
{
    if (!initCommonControls())
        return;

    m_toolTipWindow = ::CreateWindowEx(WS_EX_TRANSPARENT, TOOLTIPS_CLASS, 0, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
                                       CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                                       m_window, 0, 0, 0);
    if (!m_toolTipWindow)
        return;

    TOOLINFO info = {0};
    info.cbSize = sizeof(info);
    info.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
    info.uId = reinterpret_cast<UINT_PTR>(m_window);

    ::SendMessage(m_toolTipWindow, TTM_ADDTOOL, 0, reinterpret_cast<LPARAM>(&info));
    ::SendMessage(m_toolTipWindow, TTM_SETMAXTIPWIDTH, 0, kMaxToolTipWidth);
    ::SetWindowPos(m_toolTipWindow, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}

void WebView::startTrackingMouseLeave()
{
    if (m_trackingMouseLeave)
        return;
    m_trackingMouseLeave = true;

    TRACKMOUSEEVENT trackMouseEvent;
    trackMouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
    trackMouseEvent.dwFlags = TME_LEAVE;
    trackMouseEvent.hwndTrack = m_window;

    ::TrackMouseEvent(&trackMouseEvent);
}

void WebView::stopTrackingMouseLeave()
{
    if (!m_trackingMouseLeave)
        return;
    m_trackingMouseLeave = false;

    TRACKMOUSEEVENT trackMouseEvent;
    trackMouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
    trackMouseEvent.dwFlags = TME_LEAVE | TME_CANCEL;
    trackMouseEvent.hwndTrack = m_window;

    ::TrackMouseEvent(&trackMouseEvent);
}

bool WebView::shouldInitializeTrackPointHack()
{
    static bool shouldCreateScrollbars;
    static bool hasRunTrackPointCheck;

    if (hasRunTrackPointCheck)
        return shouldCreateScrollbars;

    hasRunTrackPointCheck = true;
    const wchar_t* trackPointKeys[] = { 
        L"Software\\Lenovo\\TrackPoint",
        L"Software\\Lenovo\\UltraNav",
        L"Software\\Alps\\Apoint\\TrackPoint",
        L"Software\\Synaptics\\SynTPEnh\\UltraNavUSB",
        L"Software\\Synaptics\\SynTPEnh\\UltraNavPS2"
    };

    for (size_t i = 0; i < WTF_ARRAY_LENGTH(trackPointKeys); ++i) {
        HKEY trackPointKey;
        int readKeyResult = ::RegOpenKeyExW(HKEY_CURRENT_USER, trackPointKeys[i], 0, KEY_READ, &trackPointKey);
        ::RegCloseKey(trackPointKey);
        if (readKeyResult == ERROR_SUCCESS) {
            shouldCreateScrollbars = true;
            return shouldCreateScrollbars;
        }
    }

    return shouldCreateScrollbars;
}

void WebView::close()
{
    m_undoClient.initialize(0);
    ::RevokeDragDrop(m_window);
    if (m_window) {
        // We can't check IsWindow(m_window) here, because that will return true even while
        // we're already handling WM_DESTROY. So we check !m_isBeingDestroyed instead.
        if (!m_isBeingDestroyed)
            DestroyWindow(m_window);
        // Either we just destroyed m_window, or it's in the process of being destroyed. Either
        // way, we clear it out to make sure we don't try to use it later.
        m_window = 0;
    }
    setParentWindow(0);
    m_page->close();
}

// PageClient

PassOwnPtr<DrawingAreaProxy> WebView::createDrawingAreaProxy()
{
    return DrawingAreaProxyImpl::create(m_page.get());
}

void WebView::setViewNeedsDisplay(const WebCore::IntRect& rect)
{
    RECT r = rect;
    ::InvalidateRect(m_window, &r, false);
}

void WebView::displayView()
{
    ::UpdateWindow(m_window);
}

void WebView::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset)
{
    // FIXME: Actually scroll the view contents.
    setViewNeedsDisplay(scrollRect);
}

void WebView::flashBackingStoreUpdates(const Vector<IntRect>& updateRects)
{
    static HBRUSH brush = createBrush(WebPageProxy::backingStoreUpdatesFlashColor().rgb()).leakPtr();
    HWndDC dc(m_window);
    flashRects(dc, updateRects.data(), updateRects.size(), brush);
}

WebCore::IntSize WebView::viewSize()
{
    RECT clientRect;
    GetClientRect(m_window, &clientRect);

    return IntRect(clientRect).size();
}

bool WebView::isViewWindowActive()
{    
    HWND activeWindow = ::GetActiveWindow();
    return (activeWindow && m_topLevelParentWindow == findTopLevelParentWindow(activeWindow));
}

bool WebView::isViewFocused()
{
    return ::GetFocus() == m_window;
}

bool WebView::isViewVisible()
{
    return m_isVisible;
}

bool WebView::isViewInWindow()
{
    return m_isInWindow;
}

void WebView::pageClosed()
{
}

void WebView::processDidCrash()
{
    updateNativeCursor();
    ::InvalidateRect(m_window, 0, TRUE);
}

void WebView::didRelaunchProcess()
{
    updateNativeCursor();
    ::InvalidateRect(m_window, 0, TRUE);
}

void WebView::toolTipChanged(const String&, const String& newToolTip)
{
    if (!m_toolTipWindow)
        return;

    if (!newToolTip.isEmpty()) {
        // This is necessary because String::charactersWithNullTermination() is not const.
        String toolTip = newToolTip;

        TOOLINFO info = {0};
        info.cbSize = sizeof(info);
        info.uFlags = TTF_IDISHWND;
        info.uId = reinterpret_cast<UINT_PTR>(m_window);
        info.lpszText = const_cast<UChar*>(toolTip.charactersWithNullTermination());
        ::SendMessage(m_toolTipWindow, TTM_UPDATETIPTEXT, 0, reinterpret_cast<LPARAM>(&info));
    }

    ::SendMessage(m_toolTipWindow, TTM_ACTIVATE, !newToolTip.isEmpty(), 0);
}

HCURSOR WebView::cursorToShow() const
{
    if (!m_page->isValid())
        return 0;

    // We only show the override cursor if the default (arrow) cursor is showing.
    static HCURSOR arrowCursor = ::LoadCursor(0, IDC_ARROW);
    if (m_overrideCursor && m_webCoreCursor == arrowCursor)
        return m_overrideCursor;

    return m_webCoreCursor;
}

void WebView::updateNativeCursor()
{
    m_lastCursorSet = cursorToShow();
    if (!m_lastCursorSet)
        return;
    ::SetCursor(m_lastCursorSet);
}

void WebView::setCursor(const WebCore::Cursor& cursor)
{
    if (!cursor.platformCursor()->nativeCursor())
        return;
    m_webCoreCursor = cursor.platformCursor()->nativeCursor();
    updateNativeCursor();
}

void WebView::setCursorHiddenUntilMouseMoves(bool)
{
    notImplemented();
}

void WebView::setOverrideCursor(HCURSOR overrideCursor)
{
    m_overrideCursor = overrideCursor;
    updateNativeCursor();
}

void WebView::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& event)
{
    m_page->setInitialFocus(forward, isKeyboardEventValid, event);
}

void WebView::setScrollOffsetOnNextResize(const IntSize& scrollOffset)
{
    // The next time we get a WM_SIZE message, scroll by the specified amount in onSizeEvent().
    m_nextResizeScrollOffset = scrollOffset;
}

void WebView::didChangeViewportProperties(const WebCore::ViewportAttributes&)
{
}

void WebView::registerEditCommand(PassRefPtr<WebEditCommandProxy> prpCommand, WebPageProxy::UndoOrRedo undoOrRedo)
{
    RefPtr<WebEditCommandProxy> command = prpCommand;
    m_undoClient.registerEditCommand(this, command, undoOrRedo);
}

void WebView::clearAllEditCommands()
{
    m_undoClient.clearAllEditCommands(this);
}

bool WebView::canUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
{
    return m_undoClient.canUndoRedo(this, undoOrRedo);
}

void WebView::executeUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
{
    m_undoClient.executeUndoRedo(this, undoOrRedo);
}
    
void WebView::reapplyEditCommand(WebEditCommandProxy* command)
{
    if (!m_page->isValid() || !m_page->isValidEditCommand(command))
        return;
    
    command->reapply();
}

void WebView::unapplyEditCommand(WebEditCommandProxy* command)
{
    if (!m_page->isValid() || !m_page->isValidEditCommand(command))
        return;
    
    command->unapply();
}

void WebView::setCustomDropTarget(IDropTarget* dropTarget)
{
    if (!m_page->isValid() || !m_window)
        return;

    ::RevokeDragDrop(m_window);

    if (dropTarget)
        ::RegisterDragDrop(m_window, dropTarget);
    else
        ::RegisterDragDrop(m_window, this);
}

FloatRect WebView::convertToDeviceSpace(const FloatRect& rect)
{
    return rect;
}

IntPoint WebView::screenToWindow(const IntPoint& point)
{
    return point;
}

IntRect WebView::windowToScreen(const IntRect& rect)
{
    return rect;
}

FloatRect WebView::convertToUserSpace(const FloatRect& rect)
{
    return rect;
}

HIMC WebView::getIMMContext() 
{
    return Ime::ImmGetContext(m_window);
}

void WebView::prepareCandidateWindow(HIMC hInputContext) 
{
    IntRect caret = m_page->firstRectForCharacterInSelectedRange(0);
    CANDIDATEFORM form;
    form.dwIndex = 0;
    form.dwStyle = CFS_EXCLUDE;
    form.ptCurrentPos.x = caret.x();
    form.ptCurrentPos.y = caret.maxY();
    form.rcArea.top = caret.y();
    form.rcArea.bottom = caret.maxY();
    form.rcArea.left = caret.x();
    form.rcArea.right = caret.maxX();
    Ime::ImmSetCandidateWindow(hInputContext, &form);
}

void WebView::resetIME()
{
    HIMC hInputContext = getIMMContext();
    if (!hInputContext)
        return;
    Ime::ImmNotifyIME(hInputContext, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
    Ime::ImmReleaseContext(m_window, hInputContext);
}

void WebView::setInputMethodState(bool enabled)
{
    Ime::ImmAssociateContextEx(m_window, 0, enabled ? IACE_DEFAULT : 0);
}

void WebView::compositionSelectionChanged(bool hasChanged)
{
    if (m_page->editorState().hasComposition && !hasChanged)
        resetIME();
}

bool WebView::onIMEStartComposition()
{
    LOG(TextInput, "onIMEStartComposition");
    m_inIMEComposition++;

    HIMC hInputContext = getIMMContext();
    if (!hInputContext)
        return false;
    prepareCandidateWindow(hInputContext);
    Ime::ImmReleaseContext(m_window, hInputContext);
    return true;
}

static bool getCompositionString(HIMC hInputContext, DWORD type, String& result)
{
    LONG compositionLength = Ime::ImmGetCompositionStringW(hInputContext, type, 0, 0);
    if (compositionLength <= 0)
        return false;
    Vector<UChar> compositionBuffer(compositionLength / 2);
    compositionLength = Ime::ImmGetCompositionStringW(hInputContext, type, compositionBuffer.data(), compositionLength);
    result = String::adopt(compositionBuffer);
    return true;
}

static void compositionToUnderlines(const Vector<DWORD>& clauses, const Vector<BYTE>& attributes, Vector<CompositionUnderline>& underlines)
{
    if (clauses.isEmpty()) {
        underlines.clear();
        return;
    }
  
    size_t numBoundaries = clauses.size() - 1;
    underlines.resize(numBoundaries);
    for (unsigned i = 0; i < numBoundaries; ++i) {
        underlines[i].startOffset = clauses[i];
        underlines[i].endOffset = clauses[i + 1];
        BYTE attribute = attributes[clauses[i]];
        underlines[i].thick = attribute == ATTR_TARGET_CONVERTED || attribute == ATTR_TARGET_NOTCONVERTED;
        underlines[i].color = Color::black;
    }
}

#if !LOG_DISABLED
#define APPEND_ARGUMENT_NAME(name) \
    if (lparam & name) { \
        if (needsComma) \
            result.appendLiteral(", "); \
        result.appendLiteral(#name); \
        needsComma = true; \
    }

static String imeCompositionArgumentNames(LPARAM lparam)
{
    StringBuilder result;
    bool needsComma = false;

    APPEND_ARGUMENT_NAME(GCS_COMPATTR);
    APPEND_ARGUMENT_NAME(GCS_COMPCLAUSE);
    APPEND_ARGUMENT_NAME(GCS_COMPREADSTR);
    APPEND_ARGUMENT_NAME(GCS_COMPREADATTR);
    APPEND_ARGUMENT_NAME(GCS_COMPREADCLAUSE);
    APPEND_ARGUMENT_NAME(GCS_COMPSTR);
    APPEND_ARGUMENT_NAME(GCS_CURSORPOS);
    APPEND_ARGUMENT_NAME(GCS_DELTASTART);
    APPEND_ARGUMENT_NAME(GCS_RESULTCLAUSE);
    APPEND_ARGUMENT_NAME(GCS_RESULTREADCLAUSE);
    APPEND_ARGUMENT_NAME(GCS_RESULTREADSTR);
    APPEND_ARGUMENT_NAME(GCS_RESULTSTR);
    APPEND_ARGUMENT_NAME(CS_INSERTCHAR);
    APPEND_ARGUMENT_NAME(CS_NOMOVECARET);

    return result.toString();
}

static String imeRequestName(WPARAM wparam)
{
    switch (wparam) {
    case IMR_CANDIDATEWINDOW:
        return "IMR_CANDIDATEWINDOW";
    case IMR_COMPOSITIONFONT:
        return "IMR_COMPOSITIONFONT";
    case IMR_COMPOSITIONWINDOW:
        return "IMR_COMPOSITIONWINDOW";
    case IMR_CONFIRMRECONVERTSTRING:
        return "IMR_CONFIRMRECONVERTSTRING";
    case IMR_DOCUMENTFEED:
        return "IMR_DOCUMENTFEED";
    case IMR_QUERYCHARPOSITION:
        return "IMR_QUERYCHARPOSITION";
    case IMR_RECONVERTSTRING:
        return "IMR_RECONVERTSTRING";
    default:
        return "Unknown (" + String::number(wparam) + ")";
    }
}
#endif

bool WebView::onIMEComposition(LPARAM lparam)
{
    LOG(TextInput, "onIMEComposition %s", imeCompositionArgumentNames(lparam).latin1().data());
    HIMC hInputContext = getIMMContext();
    if (!hInputContext)
        return true;

    if (!m_page->editorState().isContentEditable)
        return true;

    prepareCandidateWindow(hInputContext);

    if (lparam & GCS_RESULTSTR || !lparam) {
        String compositionString;
        if (!getCompositionString(hInputContext, GCS_RESULTSTR, compositionString) && lparam)
            return true;
        
        m_page->confirmComposition(compositionString);
        return true;
    }

    String compositionString;
    if (!getCompositionString(hInputContext, GCS_COMPSTR, compositionString))
        return true;
    
    // Composition string attributes
    int numAttributes = Ime::ImmGetCompositionStringW(hInputContext, GCS_COMPATTR, 0, 0);
    Vector<BYTE> attributes(numAttributes);
    Ime::ImmGetCompositionStringW(hInputContext, GCS_COMPATTR, attributes.data(), numAttributes);

    // Get clauses
    int numBytes = Ime::ImmGetCompositionStringW(hInputContext, GCS_COMPCLAUSE, 0, 0);
    Vector<DWORD> clauses(numBytes / sizeof(DWORD));
    Ime::ImmGetCompositionStringW(hInputContext, GCS_COMPCLAUSE, clauses.data(), numBytes);

    Vector<CompositionUnderline> underlines;
    compositionToUnderlines(clauses, attributes, underlines);

    int cursorPosition = LOWORD(Ime::ImmGetCompositionStringW(hInputContext, GCS_CURSORPOS, 0, 0));

    m_page->setComposition(compositionString, underlines, cursorPosition);

    return true;
}

bool WebView::onIMEEndComposition()
{
    LOG(TextInput, "onIMEEndComposition");
    // If the composition hasn't been confirmed yet, it needs to be cancelled.
    // This happens after deleting the last character from inline input hole.
    if (m_page->editorState().hasComposition)
        m_page->confirmComposition(String());

    if (m_inIMEComposition)
        m_inIMEComposition--;

    return true;
}

LRESULT WebView::onIMERequestCharPosition(IMECHARPOSITION* charPos)
{
    if (charPos->dwCharPos && !m_page->editorState().hasComposition)
        return 0;
    IntRect caret = m_page->firstRectForCharacterInSelectedRange(charPos->dwCharPos);
    charPos->pt.x = caret.x();
    charPos->pt.y = caret.y();
    ::ClientToScreen(m_window, &charPos->pt);
    charPos->cLineHeight = caret.height();
    ::GetWindowRect(m_window, &charPos->rcDocument);
    return true;
}

LRESULT WebView::onIMERequestReconvertString(RECONVERTSTRING* reconvertString)
{
    String text = m_page->getSelectedText();
    unsigned totalSize = sizeof(RECONVERTSTRING) + text.length() * sizeof(UChar);
    
    if (!reconvertString)
        return totalSize;

    if (totalSize > reconvertString->dwSize)
        return 0;
    reconvertString->dwCompStrLen = text.length();
    reconvertString->dwStrLen = text.length();
    reconvertString->dwTargetStrLen = text.length();
    reconvertString->dwStrOffset = sizeof(RECONVERTSTRING);
    memcpy(reconvertString + 1, text.characters(), text.length() * sizeof(UChar));
    return totalSize;
}

LRESULT WebView::onIMERequest(WPARAM request, LPARAM data)
{
    LOG(TextInput, "onIMERequest %s", imeRequestName(request).latin1().data());
    if (!m_page->editorState().isContentEditable)
        return 0;

    switch (request) {
    case IMR_RECONVERTSTRING:
        return onIMERequestReconvertString(reinterpret_cast<RECONVERTSTRING*>(data));

    case IMR_QUERYCHARPOSITION:
        return onIMERequestCharPosition(reinterpret_cast<IMECHARPOSITION*>(data));
    }
    return 0;
}

bool WebView::onIMESelect(WPARAM wparam, LPARAM lparam)
{
    UNUSED_PARAM(wparam);
    UNUSED_PARAM(lparam);
    LOG(TextInput, "onIMESelect locale %ld %s", lparam, wparam ? "select" : "deselect");
    return false;
}

bool WebView::onIMESetContext(WPARAM wparam, LPARAM)
{
    LOG(TextInput, "onIMESetContext %s", wparam ? "active" : "inactive");
    return false;
}

void WebView::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool wasEventHandled)
{
    // Calling ::DefWindowProcW will ensure that pressing the Alt key will generate a WM_SYSCOMMAND
    // event, e.g. See <http://webkit.org/b/47671>.
    if (!wasEventHandled)
        ::DefWindowProcW(event.nativeEvent()->hwnd, event.nativeEvent()->message, event.nativeEvent()->wParam, event.nativeEvent()->lParam);
}

PassRefPtr<WebPopupMenuProxy> WebView::createPopupMenuProxy(WebPageProxy* page)
{
    return WebPopupMenuProxyWin::create(this, page);
}

PassRefPtr<WebContextMenuProxy> WebView::createContextMenuProxy(WebPageProxy* page)
{
    return WebContextMenuProxyWin::create(m_window, page);
}

#if ENABLE(INPUT_TYPE_COLOR)
PassRefPtr<WebColorChooserProxy> WebView::createColorChooserProxy(WebPageProxy*, const WebCore::Color&, const WebCore::IntRect&)
{
    notImplemented();
    return 0;
}
#endif

void WebView::setFindIndicator(PassRefPtr<FindIndicator> prpFindIndicator, bool fadeOut, bool animate)
{
    UNUSED_PARAM(animate);

    if (!m_findIndicatorCallback)
        return;

    HBITMAP hbmp = 0;
    IntRect selectionRect;

    if (RefPtr<FindIndicator> findIndicator = prpFindIndicator) {
        if (ShareableBitmap* contentImage = findIndicator->contentImage()) {
            // Render the contentImage to an HBITMAP.
            void* bits;
            HDC hdc = ::CreateCompatibleDC(0);
            int width = contentImage->bounds().width();
            int height = contentImage->bounds().height();
            BitmapInfo bitmapInfo = BitmapInfo::create(contentImage->size());

            hbmp = CreateDIBSection(0, &bitmapInfo, DIB_RGB_COLORS, static_cast<void**>(&bits), 0, 0);
            HBITMAP hbmpOld = static_cast<HBITMAP>(SelectObject(hdc, hbmp));
#if USE(CG)
            RetainPtr<CGContextRef> context(AdoptCF, CGBitmapContextCreate(bits, width, height,
                8, width * sizeof(RGBQUAD), deviceRGBColorSpaceRef(), kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst));

            GraphicsContext graphicsContext(context.get());
            contentImage->paint(graphicsContext, IntPoint(), contentImage->bounds());
#else
            // FIXME: Implement!
#endif

            ::SelectObject(hdc, hbmpOld);
            ::DeleteDC(hdc);
        }

        selectionRect = IntRect(findIndicator->selectionRectInWindowCoordinates());
    }
    
    // The callback is responsible for calling ::DeleteObject(hbmp).
    (*m_findIndicatorCallback)(toAPI(this), hbmp, selectionRect, fadeOut, m_findIndicatorCallbackContext);
}

void WebView::setFindIndicatorCallback(WKViewFindIndicatorCallback callback, void* context)
{
    m_findIndicatorCallback = callback;
    m_findIndicatorCallbackContext = context;
}

WKViewFindIndicatorCallback WebView::getFindIndicatorCallback(void** context)
{
    if (context)
        *context = m_findIndicatorCallbackContext;
    
    return m_findIndicatorCallback;
}

void WebView::didInstallOrUninstallPageOverlay(bool didInstall)
{
    m_pageOverlayInstalled = didInstall;
}

void WebView::didCommitLoadForMainFrame(bool useCustomRepresentation)
{
}

void WebView::didFinishLoadingDataForCustomRepresentation(const String& suggestedFilename, const CoreIPC::DataReference&)
{
}

double WebView::customRepresentationZoomFactor()
{
    return 1;
}

void WebView::setCustomRepresentationZoomFactor(double)
{
}

void WebView::didChangeScrollbarsForMainFrame() const
{
}

void WebView::findStringInCustomRepresentation(const String&, FindOptions, unsigned)
{
}

void WebView::countStringMatchesInCustomRepresentation(const String&, FindOptions, unsigned)
{
}

void WebView::setIsInWindow(bool isInWindow)
{
    m_isInWindow = isInWindow;
    m_page->viewStateDidChange(WebPageProxy::ViewIsInWindow);
}

void WebView::setIsVisible(bool isVisible)
{
    m_isVisible = isVisible;

    if (m_page)
        m_page->viewStateDidChange(WebPageProxy::ViewIsVisible);
}

#if USE(ACCELERATED_COMPOSITING)

void WebView::enterAcceleratedCompositingMode(const LayerTreeContext& context)
{
#if HAVE(WKQCA)
    ASSERT(!context.isEmpty());

    m_layerHostWindow = context.window;

    IntSize size = viewSize();
    // Ensure the layer host window is behind all other child windows (since otherwise it would obscure them).
    ::SetWindowPos(m_layerHostWindow, HWND_BOTTOM, 0, 0, size.width(), size.height(), SWP_SHOWWINDOW | SWP_NOACTIVATE);
#else
    ASSERT_NOT_REACHED();
#endif
}

void WebView::exitAcceleratedCompositingMode()
{
#if HAVE(WKQCA)
    ASSERT(m_layerHostWindow);

    // Tell the WKCACFViewWindow to destroy itself. We can't call ::DestroyWindow directly because
    // the window is owned by another thread.
    ::PostMessageW(m_layerHostWindow, WKCACFViewWindow::customDestroyMessage, 0, 0);
    m_layerHostWindow = 0;
#else
    ASSERT_NOT_REACHED();
#endif
}

void WebView::updateAcceleratedCompositingMode(const LayerTreeContext&)
{
}
#endif // USE(ACCELERATED_COMPOSITING)

HWND WebView::nativeWindow()
{
    return m_window;
}

void WebView::scheduleChildWindowGeometryUpdate(const WindowGeometry& geometry)
{
    m_geometriesUpdater.addPendingUpdate(geometry);
}

void WebView::updateChildWindowGeometries()
{
    m_geometriesUpdater.updateGeometries(DoNotBringToTop);
}

// WebCore::WindowMessageListener

void WebView::windowReceivedMessage(HWND, UINT message, WPARAM wParam, LPARAM)
{
    switch (message) {
    case WM_NCACTIVATE:
        updateActiveStateSoon();
        break;
    case WM_SETTINGCHANGE:
        // systemParameterChanged(wParam);
        break;
    }
}

HRESULT STDMETHODCALLTYPE WebView::QueryInterface(REFIID riid, void** ppvObject)
{
    *ppvObject = 0;
    if (IsEqualGUID(riid, IID_IUnknown))
        *ppvObject = static_cast<IUnknown*>(this);
    else if (IsEqualGUID(riid, IID_IDropTarget))
        *ppvObject = static_cast<IDropTarget*>(this);
    else
        return E_NOINTERFACE;

    AddRef();
    return S_OK;
}

ULONG STDMETHODCALLTYPE WebView::AddRef(void)
{
    ref();
    return refCount();
}

ULONG STDMETHODCALLTYPE WebView::Release(void)
{
    deref();
    return refCount();
}

static DWORD dragOperationToDragCursor(DragOperation op)
{
    DWORD res = DROPEFFECT_NONE;
    if (op & DragOperationCopy) 
        res = DROPEFFECT_COPY;
    else if (op & DragOperationLink) 
        res = DROPEFFECT_LINK;
    else if (op & DragOperationMove) 
        res = DROPEFFECT_MOVE;
    else if (op & DragOperationGeneric) 
        res = DROPEFFECT_MOVE; // This appears to be the Firefox behaviour
    return res;
}

WebCore::DragOperation WebView::keyStateToDragOperation(DWORD grfKeyState) const
{
    if (!m_page)
        return DragOperationNone;

    // Conforms to Microsoft's key combinations as documented for 
    // IDropTarget::DragOver. Note, grfKeyState is the current 
    // state of the keyboard modifier keys on the keyboard. See:
    // <http://msdn.microsoft.com/en-us/library/ms680129(VS.85).aspx>.
    DragOperation operation = m_page->dragSession().operation;

    if ((grfKeyState & (MK_CONTROL | MK_SHIFT)) == (MK_CONTROL | MK_SHIFT))
        operation = DragOperationLink;
    else if ((grfKeyState & MK_CONTROL) == MK_CONTROL)
        operation = DragOperationCopy;
    else if ((grfKeyState & MK_SHIFT) == MK_SHIFT)
        operation = DragOperationGeneric;

    return operation;
}

HRESULT STDMETHODCALLTYPE WebView::DragEnter(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
{
    m_dragData = 0;
    m_page->resetDragOperation();

    if (m_dropTargetHelper)
        m_dropTargetHelper->DragEnter(m_window, pDataObject, (POINT*)&pt, *pdwEffect);

    POINTL localpt = pt;
    ::ScreenToClient(m_window, (LPPOINT)&localpt);
    DragData data(pDataObject, IntPoint(localpt.x, localpt.y), IntPoint(pt.x, pt.y), keyStateToDragOperation(grfKeyState));
    m_page->dragEntered(&data);
    *pdwEffect = dragOperationToDragCursor(m_page->dragSession().operation);

    m_lastDropEffect = *pdwEffect;
    m_dragData = pDataObject;

    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebView::DragOver(DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
{
    if (m_dropTargetHelper)
        m_dropTargetHelper->DragOver((POINT*)&pt, *pdwEffect);

    if (m_dragData) {
        POINTL localpt = pt;
        ::ScreenToClient(m_window, (LPPOINT)&localpt);
        DragData data(m_dragData.get(), IntPoint(localpt.x, localpt.y), IntPoint(pt.x, pt.y), keyStateToDragOperation(grfKeyState));
        m_page->dragUpdated(&data);
        *pdwEffect = dragOperationToDragCursor(m_page->dragSession().operation);
    } else
        *pdwEffect = DROPEFFECT_NONE;

    m_lastDropEffect = *pdwEffect;
    return S_OK;
}

HRESULT STDMETHODCALLTYPE WebView::DragLeave()
{
    if (m_dropTargetHelper)
        m_dropTargetHelper->DragLeave();

    if (m_dragData) {
        DragData data(m_dragData.get(), IntPoint(), IntPoint(), DragOperationNone);
        m_page->dragExited(&data);
        m_dragData = 0;
        m_page->resetDragOperation();
    }
    return S_OK;
}

static bool maybeCreateSandboxExtensionFromDragData(const DragData& dragData, SandboxExtension::Handle& sandboxExtensionHandle)
{
    if (!dragData.containsFiles())
        return false;

    // Unlike on Mac, we allow multiple files and directories, since on Windows
    // we have actions for those (open the first file, open a Windows Explorer window).

    SandboxExtension::createHandle("\\", SandboxExtension::ReadOnly, sandboxExtensionHandle);
    return true;
}

HRESULT STDMETHODCALLTYPE WebView::Drop(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
{
    if (m_dropTargetHelper)
        m_dropTargetHelper->Drop(pDataObject, (POINT*)&pt, *pdwEffect);

    m_dragData = 0;
    *pdwEffect = m_lastDropEffect;
    POINTL localpt = pt;
    ::ScreenToClient(m_window, (LPPOINT)&localpt);
    DragData data(pDataObject, IntPoint(localpt.x, localpt.y), IntPoint(pt.x, pt.y), keyStateToDragOperation(grfKeyState));

    SandboxExtension::Handle sandboxExtensionHandle;
    bool createdExtension = maybeCreateSandboxExtensionFromDragData(data, sandboxExtensionHandle);
    if (createdExtension)
        m_page->process()->willAcquireUniversalFileReadSandboxExtension();
    SandboxExtension::HandleArray sandboxExtensionForUpload;
    m_page->performDrag(&data, String(), sandboxExtensionHandle, sandboxExtensionForUpload);
    return S_OK;
}

#if ENABLE(FULLSCREEN_API)
FullScreenController* WebView::fullScreenController()
{
    if (!m_fullScreenController)
        m_fullScreenController = adoptPtr(new FullScreenController(this));
    return m_fullScreenController.get();
}

HWND WebView::fullScreenClientWindow() const
{
    return m_window;
}

HWND WebView::fullScreenClientParentWindow() const
{
    return ::GetParent(m_window);
}

void WebView::fullScreenClientSetParentWindow(HWND hostWindow)
{
    setParentWindow(hostWindow);
}

void WebView::fullScreenClientWillEnterFullScreen()
{
    page()->fullScreenManager()->willEnterFullScreen();
}

void WebView::fullScreenClientDidEnterFullScreen()
{
    page()->fullScreenManager()->didEnterFullScreen();
}

void WebView::fullScreenClientWillExitFullScreen()
{
    page()->fullScreenManager()->willExitFullScreen();
}

void WebView::fullScreenClientDidExitFullScreen()
{
    page()->fullScreenManager()->didExitFullScreen();
}

static void fullScreenClientForceRepaintCompleted(WKErrorRef, void* context)
{
    ASSERT(context);
    static_cast<WebView*>(context)->fullScreenController()->repaintCompleted();
}

void WebView::fullScreenClientForceRepaint()
{
    page()->forceRepaint(VoidCallback::create(this, &fullScreenClientForceRepaintCompleted));
}

#endif
} // namespace WebKit
