/*
 * 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 "Cursor.h"
#include "FramelessScrollView.h"
#include "FrameView.h"
#include "IntRect.h"
#include "painting/GraphicsContextBuilder.h"
#include "PlatformKeyboardEvent.h"
#include "PlatformMouseEvent.h"
#include "PlatformWheelEvent.h"
#include "SkiaUtils.h"

#include "WebInputEvent.h"
#include "WebInputEventConversion.h"
#include "WebRect.h"
#include "WebWidgetClient.h"

#include <skia/ext/platform_canvas.h>

using namespace WebCore;

namespace WebKit {

// 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 pos
    m_lastMousePosition = WebPoint(-1, -1);
}

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

void WebPopupMenuImpl::Init(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::MouseMove(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));
    }
}

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

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

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

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

bool WebPopupMenuImpl::KeyEvent(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 WebWidget::Create
}

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::animate()
{
}

void WebPopupMenuImpl::layout()
{
}

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

    if (!rect.isEmpty())
        m_widget->paint(&GraphicsContextBuilder(canvas).context(), rect);
}

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

void WebPopupMenuImpl::composite(bool finish)
{
    notImplemented();
}

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

    // TODO (jcampan): 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:
        MouseMove(*static_cast<const WebMouseEvent*>(&inputEvent));
        return true;

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

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

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

    case WebInputEvent::MouseUp:
        MouseUp(*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 KeyEvent(*static_cast<const WebKeyboardEvent*>(&inputEvent));

    default:
        break;
    }
    return false;
}

void WebPopupMenuImpl::mouseCaptureLost()
{
}

void WebPopupMenuImpl::setFocus(bool enable)
{
}

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

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

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

WebTextInputType WebPopupMenuImpl::textInputType()
{
    return WebTextInputTypeNone;
}

WebRect WebPopupMenuImpl::caretOrSelectionBounds()
{
    return WebRect();
}

void WebPopupMenuImpl::setTextDirection(WebTextDirection direction)
{
}


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

void WebPopupMenuImpl::invalidateContents(const IntRect&, bool)
{
    notImplemented();
}

void WebPopupMenuImpl::invalidateWindow(const IntRect&, bool)
{
    notImplemented();
}

void WebPopupMenuImpl::invalidateContentsAndWindow(const IntRect& paintRect, bool /*immediate*/)
{
    if (paintRect.isEmpty())
        return;
    if (m_client)
        m_client->didInvalidateRect(paintRect);
}

void WebPopupMenuImpl::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate)
{
    invalidateContentsAndWindow(updateRect, immediate);
}

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::screenToWindow(const IntPoint& point) const
{
    notImplemented();
    return IntPoint();
}

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

void WebPopupMenuImpl::scrollRectIntoView(const IntRect&, const ScrollView*) const
{
    // Nothing to be done here since we do not have the concept of a container
    // that implements its own scrolling.
}

void WebPopupMenuImpl::scrollbarsModeDidChange() const
{
    // Nothing to be done since we have no concept of different scrollbar modes.
}

void WebPopupMenuImpl::setCursor(const WebCore::Cursor&)
{
}

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

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

} // namespace WebKit
