// Copyright 2016 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 "core/input/EventHandlingUtil.h"

#include "core/frame/LocalFrame.h"
#include "core/frame/LocalFrameView.h"
#include "core/layout/LayoutEmbeddedContent.h"
#include "core/layout/LayoutView.h"
#include "core/paint/PaintLayer.h"
#include "platform/scroll/ScrollableArea.h"
#include "public/platform/WebMouseEvent.h"

namespace blink {
namespace EventHandlingUtil {

HitTestResult HitTestResultInFrame(
    LocalFrame* frame,
    const LayoutPoint& point,
    HitTestRequest::HitTestRequestType hit_type) {
  HitTestResult result(HitTestRequest(hit_type), point);

  if (!frame || !frame->ContentLayoutObject())
    return result;
  if (frame->View()) {
    IntRect rect = frame->View()->VisibleContentRect(kIncludeScrollbars);
    if (!rect.Contains(RoundedIntPoint(point)))
      return result;
  }
  frame->ContentLayoutObject()->HitTest(result);
  return result;
}

WebInputEventResult MergeEventResult(WebInputEventResult result_a,
                                     WebInputEventResult result_b) {
  // The ordering of the enumeration is specific. There are times that
  // multiple events fire and we need to combine them into a single
  // result code. The enumeration is based on the level of consumption that
  // is most significant. The enumeration is ordered with smaller specified
  // numbers first. Examples of merged results are:
  // (HandledApplication, HandledSystem) -> HandledSystem
  // (NotHandled, HandledApplication) -> HandledApplication
  static_assert(static_cast<int>(WebInputEventResult::kNotHandled) == 0,
                "WebInputEventResult not ordered");
  static_assert(static_cast<int>(WebInputEventResult::kHandledSuppressed) <
                    static_cast<int>(WebInputEventResult::kHandledApplication),
                "WebInputEventResult not ordered");
  static_assert(static_cast<int>(WebInputEventResult::kHandledApplication) <
                    static_cast<int>(WebInputEventResult::kHandledSystem),
                "WebInputEventResult not ordered");
  return static_cast<WebInputEventResult>(
      max(static_cast<int>(result_a), static_cast<int>(result_b)));
}

WebInputEventResult ToWebInputEventResult(DispatchEventResult result) {
  switch (result) {
    case DispatchEventResult::kNotCanceled:
      return WebInputEventResult::kNotHandled;
    case DispatchEventResult::kCanceledByEventHandler:
      return WebInputEventResult::kHandledApplication;
    case DispatchEventResult::kCanceledByDefaultEventHandler:
      return WebInputEventResult::kHandledSystem;
    case DispatchEventResult::kCanceledBeforeDispatch:
      return WebInputEventResult::kHandledSuppressed;
    default:
      NOTREACHED();
      return WebInputEventResult::kHandledSystem;
  }
}

PaintLayer* LayerForNode(Node* node) {
  if (!node)
    return nullptr;

  LayoutObject* layout_object = node->GetLayoutObject();
  if (!layout_object)
    return nullptr;

  PaintLayer* layer = layout_object->EnclosingLayer();
  if (!layer)
    return nullptr;

  return layer;
}

bool IsInDocument(EventTarget* n) {
  return n && n->ToNode() && n->ToNode()->isConnected();
}

ScrollableArea* AssociatedScrollableArea(const PaintLayer* layer) {
  if (PaintLayerScrollableArea* scrollable_area = layer->GetScrollableArea()) {
    if (scrollable_area->ScrollsOverflow())
      return scrollable_area;
  }

  return nullptr;
}

ContainerNode* ParentForClickEvent(const Node& node) {
  // IE doesn't dispatch click events for mousedown/mouseup events across form
  // controls.
  if (node.IsHTMLElement() && ToHTMLElement(node).IsInteractiveContent())
    return nullptr;

  return FlatTreeTraversal::Parent(node);
}

LayoutPoint ContentPointFromRootFrame(LocalFrame* frame,
                                      const IntPoint& point_in_root_frame) {
  LocalFrameView* view = frame->View();
  // FIXME: Is it really OK to use the wrong coordinates here when view is 0?
  // Historically the code would just crash; this is clearly no worse than that.
  return view ? view->RootFrameToContents(point_in_root_frame)
              : point_in_root_frame;
}

MouseEventWithHitTestResults PerformMouseEventHitTest(
    LocalFrame* frame,
    const HitTestRequest& request,
    const WebMouseEvent& mev) {
  DCHECK(frame);
  DCHECK(frame->GetDocument());

  return frame->GetDocument()->PerformMouseEventHitTest(
      request,
      ContentPointFromRootFrame(frame,
                                FlooredIntPoint(mev.PositionInRootFrame())),
      mev);
}

LocalFrame* SubframeForTargetNode(Node* node) {
  if (!node)
    return nullptr;

  LayoutObject* layout_object = node->GetLayoutObject();
  if (!layout_object || !layout_object->IsLayoutEmbeddedContent())
    return nullptr;

  LocalFrameView* frame_view =
      ToLayoutEmbeddedContent(layout_object)->ChildFrameView();
  if (!frame_view)
    return nullptr;

  return &frame_view->GetFrame();
}

LocalFrame* SubframeForHitTestResult(
    const MouseEventWithHitTestResults& hit_test_result) {
  if (!hit_test_result.IsOverEmbeddedContentView())
    return nullptr;
  return SubframeForTargetNode(hit_test_result.InnerNode());
}

}  // namespace EventHandlingUtil
}  // namespace blink
