/*
 * Copyright (C) 2009 Google 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * OWNER 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 "WebPopupMenuImpl.h"

#include "PopupContainer.h"
#include "PopupMenuChromium.h"
#include "WebInputEvent.h"
#include "WebInputEventConversion.h"
#include "WebRange.h"
#include "WebViewClient.h"
#include "WebWidgetClient.h"
#include "core/frame/FrameView.h"
#include "platform/Cursor.h"
#include "platform/NotImplemented.h"
#include "platform/PlatformGestureEvent.h"
#include "platform/PlatformKeyboardEvent.h"
#include "platform/PlatformMouseEvent.h"
#include "platform/PlatformWheelEvent.h"
#include "platform/geometry/IntRect.h"
#include "platform/graphics/GraphicsContext.h"
#include "platform/graphics/skia/SkiaUtils.h"
#include "platform/scroll/FramelessScrollView.h"
#include "public/platform/WebRect.h"
#include <skia/ext/platform_canvas.h>

using namespace WebCore;

namespace blink {

// WebPopupMenu ---------------------------------------------------------------

WebPopupMenu* WebPopupMenu::create(WebWidgetClient* client)
{
    // Pass the WebPopupMenuImpl's self-reference to the caller.
    return adoptRef(new WebPopupMenuImpl(client)).leakRef();
}

// WebWidget ------------------------------------------------------------------

WebPopupMenuImpl::WebPopupMenuImpl(WebWidgetClient* client)
    : m_client(client)
    , m_widget(0)
{
    // Set to impossible point so we always get the first mouse position.
    m_lastMousePosition = WebPoint(-1, -1);
}

WebPopupMenuImpl::~WebPopupMenuImpl()
{
    if (m_widget)
        m_widget->setClient(0);
}

void WebPopupMenuImpl::initialize(FramelessScrollView* widget, const WebRect& bounds)
{
    m_widget = widget;
    m_widget->setClient(this);

    if (m_client) {
        m_client->setWindowRect(bounds);
        m_client->show(WebNavigationPolicy()); // Policy is ignored.
    }
}

void WebPopupMenuImpl::handleMouseMove(const WebMouseEvent& event)
{
    // Don't send mouse move messages if the mouse hasn't moved.
    if (event.x != m_lastMousePosition.x || event.y != m_lastMousePosition.y) {
        m_lastMousePosition = WebPoint(event.x, event.y);
        m_widget->handleMouseMoveEvent(PlatformMouseEventBuilder(m_widget, event));

        // We cannot call setToolTipText() in PopupContainer, because PopupContainer is in WebCore, and we cannot refer to WebKit from Webcore.
        WebCore::PopupContainer* container = static_cast<WebCore::PopupContainer*>(m_widget);
        client()->setToolTipText(container->getSelectedItemToolTip(), container->menuStyle().textDirection() == WebCore::RTL ? WebTextDirectionRightToLeft : WebTextDirectionLeftToRight);
    }
}

void WebPopupMenuImpl::handleMouseLeave(const WebMouseEvent& event)
{
    m_widget->handleMouseMoveEvent(PlatformMouseEventBuilder(m_widget, event));
}

void WebPopupMenuImpl::handleMouseDown(const WebMouseEvent& event)
{
    m_widget->handleMouseDownEvent(PlatformMouseEventBuilder(m_widget, event));
}

void WebPopupMenuImpl::handleMouseUp(const WebMouseEvent& event)
{
    mouseCaptureLost();
    m_widget->handleMouseReleaseEvent(PlatformMouseEventBuilder(m_widget, event));
}

void WebPopupMenuImpl::handleMouseWheel(const WebMouseWheelEvent& event)
{
    m_widget->handleWheelEvent(PlatformWheelEventBuilder(m_widget, event));
}

bool WebPopupMenuImpl::handleGestureEvent(const WebGestureEvent& event)
{
    return m_widget->handleGestureEvent(PlatformGestureEventBuilder(m_widget, event));
}

bool WebPopupMenuImpl::handleTouchEvent(const WebTouchEvent& event)
{

    PlatformTouchEventBuilder touchEventBuilder(m_widget, event);
    bool defaultPrevented(m_widget->handleTouchEvent(touchEventBuilder));
    return defaultPrevented;
}

bool WebPopupMenuImpl::handleKeyEvent(const WebKeyboardEvent& event)
{
    return m_widget->handleKeyEvent(PlatformKeyboardEventBuilder(event));
}

// WebWidget -------------------------------------------------------------------

void WebPopupMenuImpl::close()
{
    if (m_widget)
        m_widget->hide();

    m_client = 0;

    deref(); // Balances ref() from WebPopupMenu::create.
}

void WebPopupMenuImpl::willStartLiveResize()
{
}

void WebPopupMenuImpl::resize(const WebSize& newSize)
{
    if (m_size == newSize)
        return;
    m_size = newSize;

    if (m_widget) {
        IntRect newGeometry(0, 0, m_size.width, m_size.height);
        m_widget->setFrameRect(newGeometry);
    }

    if (m_client) {
        WebRect damagedRect(0, 0, m_size.width, m_size.height);
        m_client->didInvalidateRect(damagedRect);
    }
}

void WebPopupMenuImpl::willEndLiveResize()
{
}

void WebPopupMenuImpl::animate(double)
{
}

void WebPopupMenuImpl::layout()
{
}

void WebPopupMenuImpl::paint(WebCanvas* canvas, const WebRect& rect, PaintOptions)
{
    if (!m_widget)
        return;

    if (!rect.isEmpty()) {
        GraphicsContext context(canvas);
        context.applyDeviceScaleFactor(m_client->deviceScaleFactor());
        m_widget->paint(&context, rect);
    }
}

void WebPopupMenuImpl::themeChanged()
{
    notImplemented();
}

bool WebPopupMenuImpl::handleInputEvent(const WebInputEvent& inputEvent)
{
    if (!m_widget)
        return false;

    // FIXME: WebKit seems to always return false on mouse events methods. For
    // now we'll assume it has processed them (as we are only interested in
    // whether keyboard events are processed).
    switch (inputEvent.type) {
    case WebInputEvent::MouseMove:
        handleMouseMove(*static_cast<const WebMouseEvent*>(&inputEvent));
        return true;

    case WebInputEvent::MouseLeave:
        handleMouseLeave(*static_cast<const WebMouseEvent*>(&inputEvent));
        return true;

    case WebInputEvent::MouseWheel:
        handleMouseWheel(*static_cast<const WebMouseWheelEvent*>(&inputEvent));
        return true;

    case WebInputEvent::MouseDown:
        handleMouseDown(*static_cast<const WebMouseEvent*>(&inputEvent));
        return true;

    case WebInputEvent::MouseUp:
        handleMouseUp(*static_cast<const WebMouseEvent*>(&inputEvent));
        return true;

    // In Windows, RawKeyDown only has information about the physical key, but
    // for "selection", we need the information about the character the key
    // translated into. For English, the physical key value and the character
    // value are the same, hence, "selection" works for English. But for other
    // languages, such as Hebrew, the character value is different from the
    // physical key value. Thus, without accepting Char event type which
    // contains the key's character value, the "selection" won't work for
    // non-English languages, such as Hebrew.
    case WebInputEvent::RawKeyDown:
    case WebInputEvent::KeyDown:
    case WebInputEvent::KeyUp:
    case WebInputEvent::Char:
        return handleKeyEvent(*static_cast<const WebKeyboardEvent*>(&inputEvent));

    case WebInputEvent::TouchStart:
    case WebInputEvent::TouchMove:
    case WebInputEvent::TouchEnd:
    case WebInputEvent::TouchCancel:
        return handleTouchEvent(*static_cast<const WebTouchEvent*>(&inputEvent));

    case WebInputEvent::GestureScrollBegin:
    case WebInputEvent::GestureScrollEnd:
    case WebInputEvent::GestureScrollUpdate:
    case WebInputEvent::GestureScrollUpdateWithoutPropagation:
    case WebInputEvent::GestureFlingStart:
    case WebInputEvent::GestureFlingCancel:
    case WebInputEvent::GestureTap:
    case WebInputEvent::GestureTapUnconfirmed:
    case WebInputEvent::GestureTapDown:
    case WebInputEvent::GestureShowPress:
    case WebInputEvent::GestureTapCancel:
    case WebInputEvent::GestureDoubleTap:
    case WebInputEvent::GestureTwoFingerTap:
    case WebInputEvent::GestureLongPress:
    case WebInputEvent::GestureLongTap:
    case WebInputEvent::GesturePinchBegin:
    case WebInputEvent::GesturePinchEnd:
    case WebInputEvent::GesturePinchUpdate:
        return handleGestureEvent(*static_cast<const WebGestureEvent*>(&inputEvent));

    case WebInputEvent::Undefined:
    case WebInputEvent::MouseEnter:
    case WebInputEvent::ContextMenu:
        return false;
    }
    return false;
}

void WebPopupMenuImpl::mouseCaptureLost()
{
}

void WebPopupMenuImpl::setFocus(bool)
{
}

void WebPopupMenu::setMinimumRowHeight(int minimumRowHeight)
{
    PopupMenuChromium::setMinimumRowHeight(minimumRowHeight);
}

bool WebPopupMenuImpl::setComposition(const WebString&, const WebVector<WebCompositionUnderline>&, int, int)
{
    return false;
}

bool WebPopupMenuImpl::confirmComposition()
{
    return false;
}

bool WebPopupMenuImpl::confirmComposition(ConfirmCompositionBehavior)
{
    return false;
}

bool WebPopupMenuImpl::confirmComposition(const WebString&)
{
    return false;
}

bool WebPopupMenuImpl::compositionRange(size_t* location, size_t* length)
{
    *location = 0;
    *length = 0;
    return false;
}

bool WebPopupMenuImpl::caretOrSelectionRange(size_t* location, size_t* length)
{
    *location = 0;
    *length = 0;
    return false;
}

void WebPopupMenuImpl::setTextDirection(WebTextDirection)
{
}


//-----------------------------------------------------------------------------
// WebCore::HostWindow

void WebPopupMenuImpl::invalidateContentsAndRootView(const IntRect& paintRect)
{
    if (paintRect.isEmpty())
        return;
    if (m_client)
        m_client->didInvalidateRect(paintRect);
}

void WebPopupMenuImpl::invalidateContentsForSlowScroll(const IntRect& updateRect)
{
    invalidateContentsAndRootView(updateRect);
}

void WebPopupMenuImpl::scheduleAnimation()
{
}

void WebPopupMenuImpl::scroll(const IntSize& scrollDelta, const IntRect& scrollRect, const IntRect& clipRect)
{
    if (m_client) {
        int dx = scrollDelta.width();
        int dy = scrollDelta.height();
        m_client->didScrollRect(dx, dy, clipRect);
    }
}

IntPoint WebPopupMenuImpl::screenToRootView(const IntPoint& point) const
{
    notImplemented();
    return IntPoint();
}

IntRect WebPopupMenuImpl::rootViewToScreen(const IntRect& rect) const
{
    notImplemented();
    return IntRect();
}

WebScreenInfo WebPopupMenuImpl::screenInfo() const
{
    return WebScreenInfo();
}

//-----------------------------------------------------------------------------
// WebCore::FramelessScrollViewClient

void WebPopupMenuImpl::popupClosed(FramelessScrollView* widget)
{
    ASSERT(widget == m_widget);
    if (m_widget) {
        m_widget->setClient(0);
        m_widget = 0;
    }
    if (m_client)
        m_client->closeWidgetSoon();
}

} // namespace blink
