// Copyright 2016 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 "topaz/examples/ui/jank/jank_view.h"

#include <unistd.h>

#include <string>

#include "lib/component/cpp/connect.h"
#include "src/lib/fxl/logging.h"
#include "src/lib/fxl/macros.h"
#include "src/lib/fxl/time/time_delta.h"

namespace examples {

namespace {
constexpr SkScalar kButtonWidth = 300;
constexpr SkScalar kButtonHeight = 24;
constexpr SkScalar kTextSize = 10;
constexpr SkScalar kMargin = 10;
}  // namespace

const JankView::Button JankView::kButtons[] = {
    {"Hang for 10 seconds", Action::kHang10},
    {"Stutter for 30 seconds", Action::kStutter30},
    {"Crash!", Action::kCrash},
};

JankView::JankView(scenic::ViewContext view_context,
                   fuchsia::fonts::ProviderPtr font_provider)
    : SkiaView(std::move(view_context), "Jank"),
      font_loader_(std::move(font_provider)) {
  font_loader_.LoadDefaultFont([this](sk_sp<SkTypeface> typeface) {
    FXL_CHECK(typeface);  // TODO(jeffbrown): Fail gracefully.
    typeface_ = std::move(typeface);
    InvalidateScene();
  });
}

void JankView::OnSceneInvalidated(
    fuchsia::images::PresentationInfo presentation_info) {
  if (!typeface_)
    return;

  SkCanvas* canvas = AcquireCanvas();
  if (!canvas)
    return;
  DrawContent(canvas);
  ReleaseAndSwapCanvas();

  // Stutter if needed.
  if (stutter_end_time_ > fxl::TimePoint::Now())
    sleep(2);

  // Animate.
  InvalidateScene();
}

void JankView::DrawContent(SkCanvas* canvas) {
  SkScalar hsv[3] = {
      static_cast<SkScalar>(
          fmod(fxl::TimePoint::Now().ToEpochDelta().ToSecondsF() * 60, 360.)),
      1, 1};
  canvas->clear(SkHSVToColor(hsv));

  SkScalar x = kMargin;
  SkScalar y = kMargin;
  for (const auto& button : kButtons) {
    DrawButton(canvas, button.label,
               SkRect::MakeXYWH(x, y, kButtonWidth, kButtonHeight));
    y += kButtonHeight + kMargin;
  }
}

void JankView::DrawButton(SkCanvas* canvas, const char* label,
                          const SkRect& bounds) {
  SkPaint boxPaint;
  boxPaint.setColor(SkColorSetRGB(200, 200, 200));
  canvas->drawRect(bounds, boxPaint);
  boxPaint.setColor(SkColorSetRGB(40, 40, 40));
  boxPaint.setStyle(SkPaint::kStroke_Style);
  canvas->drawRect(bounds, boxPaint);

  SkRect textBounds;
  SkFont textFont;
  textFont.setTypeface(typeface_);
  textFont.setSize(kTextSize);
  textFont.measureText(label, strlen(label), kUTF8_SkTextEncoding, &textBounds);

  SkPaint textPaint;
  textPaint.setColor(SK_ColorBLACK);
  textPaint.setAntiAlias(true);
  canvas->drawSimpleText(label, strlen(label), kUTF8_SkTextEncoding,
                         bounds.centerX() - textBounds.centerX(),
                         bounds.centerY() - textBounds.centerY(), textFont,
                         textPaint);
}

void JankView::OnInputEvent(fuchsia::ui::input::InputEvent event) {
  if (event.is_pointer()) {
    const fuchsia::ui::input::PointerEvent& pointer = event.pointer();
    if (pointer.phase == fuchsia::ui::input::PointerEventPhase::DOWN) {
      SkScalar x = pointer.x;
      SkScalar y = pointer.y;
      if (x >= kMargin && x <= kButtonWidth + kMargin) {
        int index = (y - kMargin) / (kButtonHeight + kMargin);
        if (index >= 0 &&
            size_t(index) < sizeof(kButtons) / sizeof(kButtons[0]) &&
            y < (kButtonHeight + kMargin) * (index + 1))
          OnClick(kButtons[index]);
        return;
      }
    }
  }
}

void JankView::OnClick(const Button& button) {
  switch (button.action) {
    case Action::kHang10: {
      sleep(10);
      break;
    }

    case Action::kStutter30: {
      stutter_end_time_ =
          fxl::TimePoint::Now() + fxl::TimeDelta::FromSeconds(30);
      break;
    }

    case Action::kCrash: {
      abort();
      break;
    }
  }
}

}  // namespace examples
