// Copyright 2013 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 "ash/touch/touch_hud_debug.h"

#include <algorithm>
#include <string>
#include <utility>
#include <vector>

#include "ash/root_window_controller.h"
#include "ash/shell.h"
#include "base/json/json_string_value_serializer.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "third_party/skia/include/core/SkPath.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/display/display.h"
#include "ui/display/manager/display_manager.h"
#include "ui/events/event.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/transform.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/widget/widget.h"

namespace ash {

const int kPointRadius = 20;
const SkColor kColors[] = {
    SK_ColorYELLOW,
    SK_ColorGREEN,
    SK_ColorRED,
    SK_ColorBLUE,
    SK_ColorGRAY,
    SK_ColorMAGENTA,
    SK_ColorCYAN,
    SK_ColorWHITE,
    SK_ColorBLACK,
    SkColorSetRGB(0xFF, 0x8C, 0x00),
    SkColorSetRGB(0x8B, 0x45, 0x13),
    SkColorSetRGB(0xFF, 0xDE, 0xAD),
};
const int kAlpha = 0x60;
const int kMaxPaths = arraysize(kColors);
const int kReducedScale = 10;

const char* GetTouchEventLabel(ui::EventType type) {
  switch (type) {
    case ui::ET_UNKNOWN:
      return " ";
    case ui::ET_TOUCH_PRESSED:
      return "P";
    case ui::ET_TOUCH_MOVED:
      return "M";
    case ui::ET_TOUCH_RELEASED:
      return "R";
    case ui::ET_TOUCH_CANCELLED:
      return "C";
    default:
      break;
  }
  return "?";
}

int GetTrackingId(const ui::TouchEvent& event) {
  return 0;
}

// A TouchPointLog represents a single touch-event of a touch point.
struct TouchPointLog {
 public:
  explicit TouchPointLog(const ui::TouchEvent& touch)
      : id(touch.pointer_details().id),
        type(touch.type()),
        location(touch.root_location()),
        timestamp((touch.time_stamp() - base::TimeTicks()).InMillisecondsF()),
        radius_x(touch.pointer_details().radius_x),
        radius_y(touch.pointer_details().radius_y),
        pressure(touch.pointer_details().force),
        tracking_id(GetTrackingId(touch)),
        source_device(touch.source_device_id()) {}

  // Populates a dictionary value with all the information about the touch
  // point.
  std::unique_ptr<base::DictionaryValue> GetAsDictionary() const {
    std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue());

    value->SetInteger("id", id);
    value->SetString("type", std::string(GetTouchEventLabel(type)));
    value->SetString("location", location.ToString());
    value->SetDouble("timestamp", timestamp);
    value->SetDouble("radius_x", radius_x);
    value->SetDouble("radius_y", radius_y);
    value->SetDouble("pressure", pressure);
    value->SetInteger("tracking_id", tracking_id);
    value->SetInteger("source_device", source_device);

    return value;
  }

  int id;
  ui::EventType type;
  gfx::Point location;
  double timestamp;
  float radius_x;
  float radius_y;
  float pressure;
  int tracking_id;
  int source_device;
};

// A TouchTrace keeps track of all the touch events of a single touch point
// (starting from a touch-press and ending at a touch-release or touch-cancel).
class TouchTrace {
 public:
  typedef std::vector<TouchPointLog>::iterator iterator;
  typedef std::vector<TouchPointLog>::const_iterator const_iterator;
  typedef std::vector<TouchPointLog>::reverse_iterator reverse_iterator;
  typedef std::vector<TouchPointLog>::const_reverse_iterator
      const_reverse_iterator;

  TouchTrace() = default;

  void AddTouchPoint(const ui::TouchEvent& touch) {
    log_.push_back(TouchPointLog(touch));
  }

  const std::vector<TouchPointLog>& log() const { return log_; }

  bool active() const {
    return !log_.empty() && log_.back().type != ui::ET_TOUCH_RELEASED &&
           log_.back().type != ui::ET_TOUCH_CANCELLED;
  }

  // Returns a list containing data from all events for the touch point.
  std::unique_ptr<base::ListValue> GetAsList() const {
    std::unique_ptr<base::ListValue> list(new base::ListValue());
    for (const_iterator i = log_.begin(); i != log_.end(); ++i)
      list->Append((*i).GetAsDictionary());
    return list;
  }

  void Reset() { log_.clear(); }

 private:
  std::vector<TouchPointLog> log_;

  DISALLOW_COPY_AND_ASSIGN(TouchTrace);
};

// A TouchLog keeps track of all touch events of all touch points.
class TouchLog {
 public:
  TouchLog() : next_trace_index_(0) {}

  void AddTouchPoint(const ui::TouchEvent& touch) {
    if (touch.type() == ui::ET_TOUCH_PRESSED)
      StartTrace(touch);
    AddToTrace(touch);
  }

  void Reset() {
    next_trace_index_ = 0;
    for (int i = 0; i < kMaxPaths; ++i)
      traces_[i].Reset();
  }

  std::unique_ptr<base::ListValue> GetAsList() const {
    std::unique_ptr<base::ListValue> list(new base::ListValue());
    for (int i = 0; i < kMaxPaths; ++i) {
      if (!traces_[i].log().empty())
        list->Append(traces_[i].GetAsList());
    }
    return list;
  }

  int GetTraceIndex(int touch_id) const {
    return touch_id_to_trace_index_.at(touch_id);
  }

  const TouchTrace* traces() const { return traces_; }

 private:
  void StartTrace(const ui::TouchEvent& touch) {
    // Find the first inactive spot; otherwise, overwrite the one
    // |next_trace_index_| is pointing to.
    int old_trace_index = next_trace_index_;
    do {
      if (!traces_[next_trace_index_].active())
        break;
      next_trace_index_ = (next_trace_index_ + 1) % kMaxPaths;
    } while (next_trace_index_ != old_trace_index);
    int touch_id = touch.pointer_details().id;
    traces_[next_trace_index_].Reset();
    touch_id_to_trace_index_[touch_id] = next_trace_index_;
    next_trace_index_ = (next_trace_index_ + 1) % kMaxPaths;
  }

  void AddToTrace(const ui::TouchEvent& touch) {
    int touch_id = touch.pointer_details().id;
    int trace_index = touch_id_to_trace_index_[touch_id];
    traces_[trace_index].AddTouchPoint(touch);
  }

  TouchTrace traces_[kMaxPaths];
  int next_trace_index_;

  std::map<int, int> touch_id_to_trace_index_;

  DISALLOW_COPY_AND_ASSIGN(TouchLog);
};

// TouchHudCanvas draws touch traces in |FULLSCREEN| and |REDUCED_SCALE| modes.
class TouchHudCanvas : public views::View {
 public:
  explicit TouchHudCanvas(const TouchLog& touch_log)
      : touch_log_(touch_log), scale_(1) {
    SetPaintToLayer();
    layer()->SetFillsBoundsOpaquely(false);

    flags_.setStyle(cc::PaintFlags::kFill_Style);
  }

  ~TouchHudCanvas() override = default;

  void SetScale(int scale) {
    if (scale_ == scale)
      return;
    scale_ = scale;
    gfx::Transform transform;
    transform.Scale(1. / scale_, 1. / scale_);
    layer()->SetTransform(transform);
  }

  int scale() const { return scale_; }

  void TouchPointAdded(int touch_id) {
    int trace_index = touch_log_.GetTraceIndex(touch_id);
    const TouchTrace& trace = touch_log_.traces()[trace_index];
    const TouchPointLog& point = trace.log().back();
    if (point.type == ui::ET_TOUCH_PRESSED)
      StartedTrace(trace_index);
    if (point.type != ui::ET_TOUCH_CANCELLED)
      AddedPointToTrace(trace_index);
  }

  void Clear() {
    for (int i = 0; i < kMaxPaths; ++i)
      paths_[i].reset();

    SchedulePaint();
  }

 private:
  void StartedTrace(int trace_index) {
    paths_[trace_index].reset();
    colors_[trace_index] = SkColorSetA(kColors[trace_index], kAlpha);
  }

  void AddedPointToTrace(int trace_index) {
    const TouchTrace& trace = touch_log_.traces()[trace_index];
    const TouchPointLog& point = trace.log().back();
    const gfx::Point& location = point.location;
    SkScalar x = SkIntToScalar(location.x());
    SkScalar y = SkIntToScalar(location.y());
    SkPoint last;
    if (!paths_[trace_index].getLastPt(&last) || x != last.x() ||
        y != last.y()) {
      paths_[trace_index].addCircle(x, y, SkIntToScalar(kPointRadius));
      SchedulePaint();
    }
  }

  // Overridden from views::View.
  void OnPaint(gfx::Canvas* canvas) override {
    for (int i = 0; i < kMaxPaths; ++i) {
      if (paths_[i].countPoints() == 0)
        continue;
      flags_.setColor(colors_[i]);
      canvas->DrawPath(paths_[i], flags_);
    }
  }

  cc::PaintFlags flags_;

  const TouchLog& touch_log_;
  SkPath paths_[kMaxPaths];
  SkColor colors_[kMaxPaths];

  int scale_;

  DISALLOW_COPY_AND_ASSIGN(TouchHudCanvas);
};

TouchHudDebug::TouchHudDebug(aura::Window* initial_root)
    : TouchObserverHUD(initial_root, "TouchHudDebug"),
      mode_(FULLSCREEN),
      touch_log_(new TouchLog()),
      canvas_(NULL),
      label_container_(NULL) {
  const display::Display& display =
      Shell::Get()->display_manager()->GetDisplayForId(display_id());

  views::View* content = widget()->GetContentsView();

  canvas_ = new TouchHudCanvas(*touch_log_);
  content->AddChildView(canvas_);

  const gfx::Size& display_size = display.size();
  canvas_->SetSize(display_size);

  label_container_ = new views::View;
  label_container_->SetLayoutManager(
      new views::BoxLayout(views::BoxLayout::kVertical));

  for (int i = 0; i < kMaxTouchPoints; ++i) {
    touch_labels_[i] = new views::Label;
    touch_labels_[i]->SetBackgroundColor(SkColorSetARGB(0, 255, 255, 255));
    touch_labels_[i]->SetShadows(gfx::ShadowValues(
        1, gfx::ShadowValue(gfx::Vector2d(1, 1), 0, SK_ColorWHITE)));
    label_container_->AddChildView(touch_labels_[i]);
  }
  label_container_->SetX(0);
  label_container_->SetY(display_size.height() / kReducedScale);
  label_container_->SetSize(label_container_->GetPreferredSize());
  label_container_->SetVisible(false);
  content->AddChildView(label_container_);
}

TouchHudDebug::~TouchHudDebug() = default;

// static
std::unique_ptr<base::DictionaryValue> TouchHudDebug::GetAllAsDictionary() {
  std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue());
  aura::Window::Windows roots = Shell::Get()->GetAllRootWindows();
  for (RootWindowController* root : Shell::GetAllRootWindowControllers()) {
    TouchHudDebug* hud = root->touch_hud_debug();
    if (hud) {
      std::unique_ptr<base::ListValue> list = hud->GetLogAsList();
      if (!list->empty())
        value->Set(base::Int64ToString(hud->display_id()), std::move(list));
    }
  }
  return value;
}

void TouchHudDebug::ChangeToNextMode() {
  switch (mode_) {
    case FULLSCREEN:
      SetMode(REDUCED_SCALE);
      break;
    case REDUCED_SCALE:
      SetMode(INVISIBLE);
      break;
    case INVISIBLE:
      SetMode(FULLSCREEN);
      break;
  }
}

std::unique_ptr<base::ListValue> TouchHudDebug::GetLogAsList() const {
  return touch_log_->GetAsList();
}

void TouchHudDebug::Clear() {
  if (widget()->IsVisible()) {
    canvas_->Clear();
    for (int i = 0; i < kMaxTouchPoints; ++i)
      touch_labels_[i]->SetText(base::string16());
    label_container_->SetSize(label_container_->GetPreferredSize());
  }
}

void TouchHudDebug::SetMode(Mode mode) {
  if (mode_ == mode)
    return;
  mode_ = mode;
  switch (mode) {
    case FULLSCREEN:
      label_container_->SetVisible(false);
      canvas_->SetVisible(true);
      canvas_->SetScale(1);
      canvas_->SchedulePaint();
      widget()->Show();
      break;
    case REDUCED_SCALE:
      label_container_->SetVisible(true);
      canvas_->SetVisible(true);
      canvas_->SetScale(kReducedScale);
      canvas_->SchedulePaint();
      widget()->Show();
      break;
    case INVISIBLE:
      widget()->Hide();
      break;
  }
}

void TouchHudDebug::UpdateTouchPointLabel(int index) {
  int trace_index = touch_log_->GetTraceIndex(index);
  const TouchTrace& trace = touch_log_->traces()[trace_index];
  TouchTrace::const_reverse_iterator point = trace.log().rbegin();
  ui::EventType touch_status = point->type;
  float touch_radius = std::max(point->radius_x, point->radius_y);
  while (point != trace.log().rend() && point->type == ui::ET_TOUCH_CANCELLED)
    point++;
  DCHECK(point != trace.log().rend());
  gfx::Point touch_position = point->location;

  std::string string = base::StringPrintf(
      "%2d: %s %s (%.4f)", index, GetTouchEventLabel(touch_status),
      touch_position.ToString().c_str(), touch_radius);
  touch_labels_[index]->SetText(base::UTF8ToUTF16(string));
}

void TouchHudDebug::OnTouchEvent(ui::TouchEvent* event) {
  if (event->pointer_details().id >= kMaxTouchPoints)
    return;

  touch_log_->AddTouchPoint(*event);
  canvas_->TouchPointAdded(event->pointer_details().id);
  UpdateTouchPointLabel(event->pointer_details().id);
  label_container_->SetSize(label_container_->GetPreferredSize());
}

void TouchHudDebug::OnDisplayMetricsChanged(const display::Display& display,
                                            uint32_t metrics) {
  TouchObserverHUD::OnDisplayMetricsChanged(display, metrics);

  if (display.id() != display_id() || !(metrics & DISPLAY_METRIC_BOUNDS))
    return;
  const gfx::Size& size = display.size();
  canvas_->SetSize(size);
  label_container_->SetY(size.height() / kReducedScale);
}

void TouchHudDebug::SetHudForRootWindowController(
    RootWindowController* controller) {
  controller->set_touch_hud_debug(this);
}

void TouchHudDebug::UnsetHudForRootWindowController(
    RootWindowController* controller) {
  controller->set_touch_hud_debug(NULL);
}

}  // namespace ash
