// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sky/engine/config.h"
#include "sky/engine/core/frame/NewEventHandler.h"

#include "sky/engine/core/dom/Document.h"
#include "sky/engine/core/dom/NodeRenderingTraversal.h"
#include "sky/engine/core/editing/Editor.h"
#include "sky/engine/core/editing/FrameSelection.h"
#include "sky/engine/core/editing/htmlediting.h"
#include "sky/engine/core/events/GestureEvent.h"
#include "sky/engine/core/events/KeyboardEvent.h"
#include "sky/engine/core/events/PointerEvent.h"
#include "sky/engine/core/events/WheelEvent.h"
#include "sky/engine/core/frame/LocalFrame.h"
#include "sky/engine/core/frame/FrameView.h"
#include "sky/engine/core/rendering/RenderObject.h"
#include "sky/engine/core/rendering/RenderView.h"
#include "sky/engine/platform/KeyboardCodes.h"
#include "sky/engine/platform/geometry/FloatPoint.h"
#include "sky/engine/public/platform/WebInputEvent.h"

namespace blink {

static VisiblePosition visiblePositionForHitTestResult(const HitTestResult& hitTestResult)
{
    Node* innerNode = hitTestResult.innerNode();
    VisiblePosition position(innerNode->renderer()->positionForPoint(hitTestResult.localPoint()));
    if (!position.isNull())
        return position;
    return VisiblePosition(firstPositionInOrBeforeNode(innerNode), DOWNSTREAM);
}

template<typename EventType>
static LayoutPoint positionForEvent(const EventType& event)
{
    return roundedLayoutPoint(FloatPoint(event.x, event.y));
}

NewEventHandler::NewEventHandler(LocalFrame& frame)
    : m_frame(frame)
    , m_suppressNextCharEvent(false)
{
}

NewEventHandler::~NewEventHandler()
{
}

Node* NewEventHandler::targetForKeyboardEvent() const
{
    Document* document = m_frame.document();
    if (Node* focusedElement = document->focusedElement())
        return focusedElement;
    return document;
}

Node* NewEventHandler::targetForHitTestResult(const HitTestResult& hitTestResult)
{
    Node* node = hitTestResult.innerNode();
    if (!node)
        return m_frame.document();
    if (node->isTextNode())
        return NodeRenderingTraversal::parent(node);
    return node;
}

HitTestResult NewEventHandler::performHitTest(const LayoutPoint& point)
{
    HitTestResult result(point);
    if (!m_frame.contentRenderer())
        return result;
    m_frame.contentRenderer()->hitTest(HitTestRequest(HitTestRequest::ReadOnly), result);
    return result;
}

bool NewEventHandler::dispatchPointerEvent(PointerState& state, const WebPointerEvent& event)
{
    RefPtr<PointerEvent> pointerEvent = PointerEvent::create(event);
    pointerEvent->setDX(event.x - state.x);
    pointerEvent->setDY(event.y - state.y);
    state.x = event.x;
    state.y = event.y;
    // TODO(abarth): Keep track of how many pointers are targeting the same node
    // and only mark the first one as primary.
    return state.target->dispatchEvent(pointerEvent.release());
}

bool NewEventHandler::dispatchGestureEvent(Node& target, const WebGestureEvent& event)
{
    RefPtr<GestureEvent> gestureEvent = GestureEvent::create(event);
    return target.dispatchEvent(gestureEvent.release());
}

bool NewEventHandler::dispatchKeyboardEvent(Node& target, const WebKeyboardEvent& event)
{
    RefPtr<KeyboardEvent> keyboardEvent = KeyboardEvent::create(event);
    return target.dispatchEvent(keyboardEvent.release());
}

bool NewEventHandler::dispatchWheelEvent(Node& target, const WebWheelEvent& event)
{
    RefPtr<WheelEvent> wheelEvent = WheelEvent::create(event);
    return target.dispatchEvent(wheelEvent.release());
}

bool NewEventHandler::dispatchClickEvent(Node& capturingTarget, const WebPointerEvent& event)
{
    ASSERT(event.type == WebInputEvent::PointerUp);
    HitTestResult hitTestResult = performHitTest(positionForEvent(event));
    Node* releaseTarget = targetForHitTestResult(hitTestResult);
    Node* clickTarget = NodeRenderingTraversal::commonAncestor(*releaseTarget, capturingTarget);
    if (!clickTarget)
        return true;
    // TODO(abarth): Make a proper gesture event that includes information from the event.
    return clickTarget->dispatchEvent(Event::createCancelableBubble(EventTypeNames::click));
}

void NewEventHandler::updateSelectionForPointerDown(const HitTestResult& hitTestResult, const WebPointerEvent& event)
{
    Node* innerNode = hitTestResult.innerNode();
    if (!innerNode->renderer())
        return;
    if (Position::nodeIsUserSelectNone(innerNode))
        return;
    if (!innerNode->dispatchEvent(Event::createCancelableBubble(EventTypeNames::selectstart)))
        return;
    VisiblePosition position = visiblePositionForHitTestResult(hitTestResult);
    // TODO(abarth): Can we change this to setSelectionIfNeeded?
    m_frame.selection().setNonDirectionalSelectionIfNeeded(VisibleSelection(position), CharacterGranularity);
}

bool NewEventHandler::handlePointerEvent(const WebPointerEvent& event)
{
    if (event.type == WebInputEvent::PointerDown)
        return handlePointerDownEvent(event);
    if (event.type == WebInputEvent::PointerUp)
        return handlePointerUpEvent(event);
    if (event.type == WebInputEvent::PointerMove)
        return handlePointerMoveEvent(event);
    ASSERT(event.type == WebInputEvent::PointerCancel);
    return handlePointerCancelEvent(event);
}

bool NewEventHandler::handleGestureEvent(const WebGestureEvent& event)
{
    HitTestResult hitTestResult = performHitTest(positionForEvent(event));
    RefPtr<Node> target = targetForHitTestResult(hitTestResult);
    return target && !dispatchGestureEvent(*target, event);
}

bool NewEventHandler::handleKeyboardEvent(const WebKeyboardEvent& event)
{
    bool shouldSuppressCharEvent = m_suppressNextCharEvent;
    m_suppressNextCharEvent = false;

    if (event.type == WebInputEvent::Char) {
        if (shouldSuppressCharEvent)
            return true;
        // Do we really need to suppress keypress events for these keys anymore?
        if (event.key == VKEY_BACK
            || event.key == VKEY_ESCAPE)
            return true;
    }

    RefPtr<Node> target = targetForKeyboardEvent();
    bool handled = target && !dispatchKeyboardEvent(*target, event);

    // If the keydown event was handled, we don't want to "generate" a keypress
    // event for that keystroke. However, we'll receive a Char event from the
    // embedder regardless, so we set m_suppressNextCharEvent, will will prevent
    // us from dispatching the keypress event when we receive that Char event.
    if (handled && event.type == WebInputEvent::KeyDown)
        m_suppressNextCharEvent = true;

    return handled;
}

bool NewEventHandler::handleWheelEvent(const WebWheelEvent& event)
{
    HitTestResult hitTestResult = performHitTest(positionForEvent(event));
    RefPtr<Node> target = targetForHitTestResult(hitTestResult);
    return target && !dispatchWheelEvent(*target, event);
}

bool NewEventHandler::handlePointerDownEvent(const WebPointerEvent& event)
{
    // In principle, we shouldn't get another pointer down for the same
    // pointer ID, but for mice, we don't get a pointer cancel when you
    // drag outside the window frame on Linux. For now, send the pointer
    // cancel at this point.
    if (event.kind == WebPointerEvent::Mouse
        && m_stateForPointer.find(event.pointer) != m_stateForPointer.end()) {
        WebPointerEvent fakeCancel = event;
        fakeCancel.type = WebInputEvent::PointerCancel;
        handlePointerCancelEvent(fakeCancel);
    }

    ASSERT(m_stateForPointer.find(event.pointer) == m_stateForPointer.end());
    HitTestResult hitTestResult = performHitTest(positionForEvent(event));
    RefPtr<Node> target = targetForHitTestResult(hitTestResult);
    if (!target)
        return false;
    PointerState& state = m_stateForPointer[event.pointer];
    state.target = target;
    bool eventSwallowed = !dispatchPointerEvent(state, event);
    // TODO(abarth): Set the target for the pointer to something determined when
    // dispatching the event.
    updateSelectionForPointerDown(hitTestResult, event);
    return eventSwallowed;
}

bool NewEventHandler::handlePointerUpEvent(const WebPointerEvent& event)
{
    auto it = m_stateForPointer.find(event.pointer);
    if (it == m_stateForPointer.end())
        return false;
    PointerState stateCopy = it->second;
    m_stateForPointer.erase(it);
    ASSERT(stateCopy.target);
    bool eventSwallowed = !dispatchPointerEvent(stateCopy, event);
    // When the user releases the primary pointer, we need to dispatch a tap
    // event to the common ancestor for where the pointer went down and where
    // it came up.
    if (!eventSwallowed && !dispatchClickEvent(*stateCopy.target, event))
        eventSwallowed = true;
    return eventSwallowed;
}

bool NewEventHandler::handlePointerMoveEvent(const WebPointerEvent& event)
{
    auto it = m_stateForPointer.find(event.pointer);
    if (it == m_stateForPointer.end())
        return false;
    PointerState& state = it->second;
    ASSERT(state.target);
    return dispatchPointerEvent(state, event);
}

bool NewEventHandler::handlePointerCancelEvent(const WebPointerEvent& event)
{
    auto it = m_stateForPointer.find(event.pointer);
    if (it == m_stateForPointer.end())
        return false;
    PointerState stateCopy = it->second;
    m_stateForPointer.erase(it);
    ASSERT(stateCopy.target);
    return dispatchPointerEvent(stateCopy, event);
}

}
