// 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 "third_party/blink/renderer/core/events/pointer_event.h"

#include "third_party/blink/renderer/bindings/core/v8/v8_pointer_event_init.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
#include "third_party/blink/renderer/core/dom/events/event_path.h"
#include "third_party/blink/renderer/core/events/pointer_event_util.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"

namespace blink {

PointerEvent::PointerEvent(const AtomicString& type,
                           const PointerEventInit* initializer,
                           base::TimeTicks platform_time_stamp,
                           MouseEvent::SyntheticEventType synthetic_event_type,
                           WebMenuSourceType menu_source_type)
    : MouseEvent(type,
                 initializer,
                 platform_time_stamp,
                 synthetic_event_type,
                 menu_source_type),
      pointer_id_(0),
      width_(0),
      height_(0),
      pressure_(0),
      tilt_x_(0),
      tilt_y_(0),
      azimuth_angle_(0),
      altitude_angle_(kPiDouble / 2),
      tangential_pressure_(0),
      twist_(0),
      is_primary_(false),
      coalesced_events_targets_dirty_(false),
      predicted_events_targets_dirty_(false) {
  if (initializer->hasPointerId())
    pointer_id_ = initializer->pointerId();
  if (initializer->hasWidth())
    width_ = initializer->width();
  if (initializer->hasHeight())
    height_ = initializer->height();
  if (initializer->hasPressure())
    pressure_ = initializer->pressure();
  if (initializer->hasTiltX())
    tilt_x_ = initializer->tiltX();
  if (initializer->hasTiltY())
    tilt_y_ = initializer->tiltY();
  if (initializer->hasTangentialPressure())
    tangential_pressure_ = initializer->tangentialPressure();
  if (initializer->hasTwist())
    twist_ = initializer->twist();
  if (initializer->hasPointerType())
    pointer_type_ = initializer->pointerType();
  if (initializer->hasIsPrimary())
    is_primary_ = initializer->isPrimary();
  if (initializer->hasCoalescedEvents()) {
    for (auto coalesced_event : initializer->coalescedEvents())
      coalesced_events_.push_back(coalesced_event);
  }
  if (initializer->hasPredictedEvents()) {
    for (auto predicted_event : initializer->predictedEvents())
      predicted_events_.push_back(predicted_event);
  }
  if (initializer->hasAzimuthAngle())
    azimuth_angle_ = initializer->azimuthAngle();
  if (initializer->hasAltitudeAngle())
    altitude_angle_ = initializer->altitudeAngle();
  if ((initializer->hasTiltX() || initializer->hasTiltY()) &&
      !initializer->hasAzimuthAngle() && !initializer->hasAltitudeAngle()) {
    azimuth_angle_ = PointerEventUtil::AzimuthFromTilt(
        PointerEventUtil::TransformToTiltInValidRange(tilt_x_),
        PointerEventUtil::TransformToTiltInValidRange(tilt_y_));
    altitude_angle_ = PointerEventUtil::AltitudeFromTilt(
        PointerEventUtil::TransformToTiltInValidRange(tilt_x_),
        PointerEventUtil::TransformToTiltInValidRange(tilt_y_));
  }
  if ((initializer->hasAzimuthAngle() || initializer->hasAltitudeAngle()) &&
      !initializer->hasTiltX() && !initializer->hasTiltY()) {
    tilt_x_ = PointerEventUtil::TiltXFromSpherical(
        PointerEventUtil::TransformToAzimuthInValidRange(azimuth_angle_),
        PointerEventUtil::TransformToAltitudeInValidRange(altitude_angle_));
    tilt_y_ = PointerEventUtil::TiltYFromSpherical(
        PointerEventUtil::TransformToAzimuthInValidRange(azimuth_angle_),
        PointerEventUtil::TransformToAltitudeInValidRange(altitude_angle_));
  }
}

bool PointerEvent::IsMouseEvent() const {
  if (RuntimeEnabledFeatures::ClickPointerEventEnabled() &&
      (type() == event_type_names::kClick ||
       type() == event_type_names::kAuxclick ||
       type() == event_type_names::kContextmenu)) {
    return true;
  }

  return false;
}

bool PointerEvent::ShouldHaveIntegerCoordinates() const {
  if (RuntimeEnabledFeatures::ClickPointerEventIntegerCoordinatesEnabled() &&
      (type() == event_type_names::kClick ||
       type() == event_type_names::kContextmenu)) {
    return true;
  }
  return false;
}

bool PointerEvent::IsPointerEvent() const {
  return true;
}

double PointerEvent::offsetX() const {
  if (ShouldHaveIntegerCoordinates())
    return MouseEvent::offsetX();
  if (!HasPosition())
    return 0;
  if (!has_cached_relative_position_)
    const_cast<PointerEvent*>(this)->ComputeRelativePosition();
  return offset_location_.X();
}

double PointerEvent::offsetY() const {
  if (ShouldHaveIntegerCoordinates())
    return MouseEvent::offsetY();
  if (!HasPosition())
    return 0;
  if (!has_cached_relative_position_)
    const_cast<PointerEvent*>(this)->ComputeRelativePosition();
  return offset_location_.Y();
}

void PointerEvent::ReceivedTarget() {
  coalesced_events_targets_dirty_ = true;
  predicted_events_targets_dirty_ = true;
  MouseEvent::ReceivedTarget();
}

Node* PointerEvent::toElement() const {
  return nullptr;
}

Node* PointerEvent::fromElement() const {
  return nullptr;
}

HeapVector<Member<PointerEvent>> PointerEvent::getCoalescedEvents() {
  if (coalesced_events_targets_dirty_) {
    for (auto coalesced_event : coalesced_events_)
      coalesced_event->SetTarget(target());
    coalesced_events_targets_dirty_ = false;
  }
  return coalesced_events_;
}

HeapVector<Member<PointerEvent>> PointerEvent::getPredictedEvents() {
  if (predicted_events_targets_dirty_) {
    for (auto predicted_event : predicted_events_)
      predicted_event->SetTarget(target());
    predicted_events_targets_dirty_ = false;
  }
  return predicted_events_;
}

base::TimeTicks PointerEvent::OldestPlatformTimeStamp() const {
  if (coalesced_events_.size() > 0) {
    // Assume that time stamps of coalesced events are in ascending order.
    return coalesced_events_[0]->PlatformTimeStamp();
  }
  return this->PlatformTimeStamp();
}

void PointerEvent::Trace(Visitor* visitor) const {
  visitor->Trace(coalesced_events_);
  visitor->Trace(predicted_events_);
  MouseEvent::Trace(visitor);
}

DispatchEventResult PointerEvent::DispatchEvent(EventDispatcher& dispatcher) {
  if (type().IsEmpty())
    return DispatchEventResult::kNotCanceled;  // Shouldn't happen.

  if (RuntimeEnabledFeatures::ClickPointerEventEnabled() &&
      type() == event_type_names::kClick) {
    // The MouseEvent::DispatchEvent will take care of sending dblclick event if
    // needed.
    return MouseEvent::DispatchEvent(dispatcher);
  }

  DCHECK(!target() || target() != relatedTarget());

  GetEventPath().AdjustForRelatedTarget(dispatcher.GetNode(), relatedTarget());

  return dispatcher.Dispatch();
}

}  // namespace blink
