// 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 "components/exo/touch.h"

#include "components/exo/shell_surface_base.h"
#include "components/exo/surface.h"
#include "components/exo/touch_delegate.h"
#include "components/exo/touch_stylus_delegate.h"
#include "components/exo/wm_helper.h"
#include "ui/aura/window.h"
#include "ui/events/event.h"
#include "ui/wm/core/capture_controller.h"
#include "ui/wm/core/window_util.h"

namespace exo {
namespace {

// Helper function that returns an iterator to the first item in |vector|
// with |value|.
template <typename T, typename U>
typename T::iterator FindVectorItem(T& vector, U value) {
  return std::find(vector.begin(), vector.end(), value);
}

// Helper function that returns true if |vector| contains an item with |value|.
template <typename T, typename U>
bool VectorContainsItem(T& vector, U value) {
  return FindVectorItem(vector, value) != vector.end();
}

gfx::PointF EventLocationInWindow(ui::TouchEvent* event, aura::Window* window) {
  ui::Layer* root = window->GetRootWindow()->layer();
  ui::Layer* target = window->layer();

  gfx::Transform transform;
  target->GetTargetTransformRelativeTo(root, &transform);
  auto point = gfx::Point3F(event->root_location_f());
  transform.TransformPointReverse(&point);
  return point.AsPointF();
}

}  // namespace

////////////////////////////////////////////////////////////////////////////////
// Touch, public:

Touch::Touch(TouchDelegate* delegate) : delegate_(delegate) {
  WMHelper::GetInstance()->AddPreTargetHandler(this);
}

Touch::~Touch() {
  delegate_->OnTouchDestroying(this);
  if (focus_)
    focus_->RemoveSurfaceObserver(this);
  WMHelper::GetInstance()->RemovePreTargetHandler(this);
}

void Touch::SetStylusDelegate(TouchStylusDelegate* delegate) {
  stylus_delegate_ = delegate;
}

bool Touch::HasStylusDelegate() const {
  return !!stylus_delegate_;
}

////////////////////////////////////////////////////////////////////////////////
// ui::EventHandler overrides:

void Touch::OnTouchEvent(ui::TouchEvent* event) {
  bool send_details = false;

  const int touch_pointer_id = event->pointer_details().id;
  switch (event->type()) {
    case ui::ET_TOUCH_PRESSED: {
      // Early out if event doesn't contain a valid target for touch device.
      Surface* target = GetEffectiveTargetForEvent(event);
      if (!target)
        return;

      // If this is the first touch point then target becomes the focus surface
      // until all touch points have been released.
      if (touch_points_.empty()) {
        DCHECK(!focus_);
        focus_ = target;
        focus_->AddSurfaceObserver(this);
      }

      DCHECK(!VectorContainsItem(touch_points_, touch_pointer_id));
      touch_points_.push_back(touch_pointer_id);

      // Convert location to focus surface coordinate space.
      DCHECK(focus_);
      gfx::PointF location = EventLocationInWindow(event, focus_->window());

      // Generate a touch down event for the focus surface. Note that this can
      // be different from the target surface.
      delegate_->OnTouchDown(focus_, event->time_stamp(), touch_pointer_id,
                             location);
      if (stylus_delegate_ &&
          event->pointer_details().pointer_type !=
              ui::EventPointerType::POINTER_TYPE_TOUCH) {
        stylus_delegate_->OnTouchTool(touch_pointer_id,
                                      event->pointer_details().pointer_type);
      }
      send_details = true;
    } break;
    case ui::ET_TOUCH_RELEASED: {
      auto it = FindVectorItem(touch_points_, touch_pointer_id);
      if (it == touch_points_.end())
        return;
      touch_points_.erase(it);

      // Reset focus surface if this is the last touch point.
      if (touch_points_.empty()) {
        DCHECK(focus_);
        focus_->RemoveSurfaceObserver(this);
        focus_ = nullptr;
      }

      delegate_->OnTouchUp(event->time_stamp(), touch_pointer_id);
    } break;
    case ui::ET_TOUCH_MOVED: {
      auto it = FindVectorItem(touch_points_, touch_pointer_id);
      if (it == touch_points_.end())
        return;

      DCHECK(focus_);
      // Convert location to focus surface coordinate space.
      gfx::PointF location = EventLocationInWindow(event, focus_->window());
      delegate_->OnTouchMotion(event->time_stamp(), touch_pointer_id, location);
      send_details = true;
    } break;
    case ui::ET_TOUCH_CANCELLED: {
      auto it = FindVectorItem(touch_points_, touch_pointer_id);
      if (it == touch_points_.end())
        return;

      DCHECK(focus_);
      focus_->RemoveSurfaceObserver(this);
      focus_ = nullptr;

      // Cancel the full set of touch sequences as soon as one is canceled.
      touch_points_.clear();
      delegate_->OnTouchCancel();
    } break;
    default:
      NOTREACHED();
      return;
  }
  if (send_details) {
    // Some devices do not report radius_y/minor. We assume a circular shape
    // in that case.
    float major = event->pointer_details().radius_x * 2.0f;
    float minor = event->pointer_details().radius_y * 2.0f;
    if (!minor)
      minor = major;
    delegate_->OnTouchShape(touch_pointer_id, major, minor);

    if (stylus_delegate_ &&
        event->pointer_details().pointer_type !=
            ui::EventPointerType::POINTER_TYPE_TOUCH) {
      if (!std::isnan(event->pointer_details().force)) {
        stylus_delegate_->OnTouchForce(event->time_stamp(), touch_pointer_id,
                                       event->pointer_details().force);
      }
      stylus_delegate_->OnTouchTilt(
          event->time_stamp(), touch_pointer_id,
          gfx::Vector2dF(event->pointer_details().tilt_x,
                         event->pointer_details().tilt_y));
    }
  }
  // TODO(denniskempin): Extend ui::TouchEvent to signal end of sequence of
  // touch events to send TouchFrame once after all touches have been updated.
  delegate_->OnTouchFrame();
}

////////////////////////////////////////////////////////////////////////////////
// SurfaceObserver overrides:

void Touch::OnSurfaceDestroying(Surface* surface) {
  DCHECK(surface == focus_);
  focus_ = nullptr;
  surface->RemoveSurfaceObserver(this);

  // Cancel touch sequences.
  DCHECK_NE(touch_points_.size(), 0u);
  touch_points_.clear();
  delegate_->OnTouchCancel();
}

////////////////////////////////////////////////////////////////////////////////
// Touch, private:

Surface* Touch::GetEffectiveTargetForEvent(ui::LocatedEvent* event) const {
  Surface* target = ShellSurfaceBase::GetTargetSurfaceForLocatedEvent(event);

  if (!target)
    return nullptr;

  return delegate_->CanAcceptTouchEventsForSurface(target) ? target : nullptr;
}

}  // namespace exo
