// Copyright 2019 The Fuchsia 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 "src/ui/lib/escher/paper/paper_timestamp_graph.h"

namespace escher {

// Used to calculate the area of the debug graph that bars will be drawn in.
static constexpr int32_t kWidthPadding = 150;
static constexpr int32_t kHeightPadding = 100;

static constexpr int32_t kAxisLineThickness = 10;

void PaperTimestampGraph::AddTimestamp(PaperRenderer::Timestamp ts) {
  if (timestamps_.size() >= max_timestamp_count_) {
    for (size_t i = 1; i < timestamps_.size(); ++i) {
      timestamps_[i - 1] = timestamps_[i];
    }
    timestamps_[timestamps_.size() - 1] = ts;
  } else {
    timestamps_.push_back(ts);
  }
}

void PaperTimestampGraph::DrawOn(PaperRenderer* r, vk::Rect2D bounds) {
  // Obtain the smaller bounds that can be drawn within.
  bounds = DrawGraphAxesOn(r, bounds, "TIME", "FRAMES", DebugRects::kWhite);
  DrawGraphContentOn(r, bounds);
}

void PaperTimestampGraph::DrawGraphContentOn(PaperRenderer* r, vk::Rect2D bounds) {
  FX_DCHECK(r) << "no PaperRenderer";

  const uint32_t width = bounds.extent.width;
  const uint32_t height = bounds.extent.height;

  const int16_t x_start = static_cast<int16_t>(bounds.offset.x + 10);
  const int16_t y_axis = static_cast<int16_t>(bounds.offset.y + height);
  const int16_t x_axis = static_cast<int16_t>(bounds.offset.x + width);
  const int16_t h_interval = static_cast<int16_t>(height / 35);
  const int16_t w_interval = static_cast<int16_t>(kSampleLineThickness);

  const int16_t middle_bar = y_axis - (h_interval * 16) + 2;

  for (uint32_t i = 0; i < timestamps_.size(); i++) {
    const auto& ts = timestamps_[i];

    int16_t render_time = ts.render_done - ts.render_start;
    int16_t presentation_time = ts.actual_present - ts.target_present;

    if (static_cast<int16_t>(x_start + (i * w_interval)) <= x_axis) {
      // TODO(fxbug.dev/43208): these are blitting over each other (they all start at y_axis).
      if (render_time != 0) {
        r->DrawVLine(escher::DebugRects::kRed, x_start + (i * w_interval), y_axis,
                     y_axis - (h_interval * render_time), w_interval);
      }
      if (ts.latch_point != 0) {
        r->DrawVLine(escher::DebugRects::kYellow, x_start + (i * w_interval), y_axis,
                     y_axis - (h_interval * ts.latch_point), w_interval);
      }
      if (ts.update_done != 0) {
        r->DrawVLine(escher::DebugRects::kBlue, x_start + (i * w_interval), y_axis,
                     y_axis - (h_interval * ts.update_done), w_interval);
      }
      if (false) {  // presentation_time != 0) {
        r->DrawVLine(escher::DebugRects::kPurple, x_start + (i * w_interval), middle_bar,
                     middle_bar - (h_interval * presentation_time), w_interval);
      }
    } else {
      // TODO(fxbug.dev/7335): Delete and replace values in array
    }
  }
}

vk::Rect2D PaperTimestampGraph::DrawGraphAxesOn(PaperRenderer* r, vk::Rect2D bounds,
                                                std::string x_label, std::string y_label,
                                                DebugRects::Color line_color) {
  FX_DCHECK(r) << "no PaperRenderer";

  const int32_t frame_width = bounds.extent.width;
  const int32_t frame_height = bounds.extent.height;

  const int32_t origin_x = bounds.offset.x + kWidthPadding;
  const int32_t origin_y = bounds.offset.y + frame_height - kHeightPadding;

  const uint16_t x_axis_length = static_cast<uint16_t>(frame_width - kWidthPadding);
  const uint16_t y_axis_length = static_cast<uint16_t>(frame_height - kHeightPadding);
  const uint16_t h_interval = static_cast<uint16_t>((y_axis_length - kHeightPadding) / 35);

  const vk::Rect2D content_bounds{
      {bounds.offset.x + kWidthPadding, bounds.offset.y},
      {bounds.extent.width - kWidthPadding, bounds.extent.height - kHeightPadding}};

  // X-axis
  r->DrawHLine(line_color, origin_y, origin_x, bounds.offset.x + bounds.extent.width,
               kAxisLineThickness);
  r->DrawDebugText(x_label,
                   {bounds.offset.x + 5, bounds.offset.y + (frame_height - kHeightPadding) / 2}, 5);

  // Y-axis
  r->DrawVLine(line_color, origin_x, bounds.offset.y, origin_y, kAxisLineThickness);
  r->DrawDebugText(y_label, {bounds.offset.x + frame_width / 2, origin_y + 25}, 5);

  // Colored bar used to show acceptable vs concerning values (acceptable below bar).
  constexpr auto kAcceptableLine = 0.6;
  r->DrawHLine(DebugRects::kGreen,
               origin_y - static_cast<int32_t>(kAcceptableLine * content_bounds.extent.height),
               origin_x + 10, content_bounds.offset.x + content_bounds.extent.width, 5);

  return content_bounds;
}

}  // namespace escher
