// Copyright 2023 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#include <chrono>
#include <cstdint>

#define PW_LOG_LEVEL PW_LOG_LEVEL_DEBUG

#include "app_common/common.h"
#include "graphics/surface.hpp"
#include "libkudzu/framecounter.h"
#include "libkudzu/random.h"
#include "pw_assert/assert.h"
#include "pw_assert/check.h"
#include "pw_color/color.h"
#include "pw_color/colors_endesga32.h"
#include "pw_color/colors_pico8.h"
#include "pw_display/display.h"
#include "pw_framebuffer/framebuffer.h"
#include "pw_log/log.h"
#include "pw_string/string_builder.h"
#include "pw_sys_io/sys_io.h"
#include "pw_system/target_hooks.h"
#include "pw_thread/detached_thread.h"

using pw::color::color_rgb565_t;
using pw::color::kColorsPico8Rgb565;
using pw::display::Display;
using pw::framebuffer::Framebuffer;

namespace {

struct test_particle {
  blit::Vec2 pos;
  blit::Vec2 vel;
  int age;
  bool generated = false;
};

void rain_generate(test_particle& p, blit::Surface screen) {
  p.pos = blit::Vec2(GetRandomFloat(screen.bounds.w), -10 + GetRandomFloat(10));
  p.vel = blit::Vec2(0, 150);
  p.age = 0;
  p.generated = true;
};

void rain(blit::Surface screen,
          pw::chrono::SystemClock::duration elapsed_time,
          blit::Rect text_position) {
  static test_particle s[300];
  static int generate_index = 0;

  // Convert to fractional elapsed seconds.
  auto const elapsed_seconds =
      std::chrono::duration_cast<std::chrono::duration<float>>(elapsed_time);

  rain_generate(s[generate_index++], screen);
  if (generate_index >= 300)
    generate_index = 0;

  blit::Vec2 gvec = blit::Vec2(0, 9.8 * 5);
  blit::Vec2 gravity = gvec * elapsed_seconds.count();

  // Add a little padding to the text box.
  text_position.y -= 2;
  text_position.h += 2;

  for (auto& p : s) {
    if (p.generated) {
      p.vel += gravity;
      p.pos += p.vel * elapsed_seconds.count();

      int floor = screen.bounds.h - 3;

      // Rain lands on top of the text.
      if (text_position.contains(p.pos)) {
        floor = text_position.y;
      }

      if (p.pos.y >= floor) {
        p.pos.y = floor;
        float bounce = (GetRandomFloat(10)) / 80.0f;
        p.vel.y *= -bounce;
        p.vel.x = (GetRandomFloat(30) - 15);
      }
      p.age++;

      int a = p.age / 2;
      int r = 100 - (a / 2);
      int g = 255 - (a * 4);
      int b = 255 - (a / 2);

      if (p.vel.length() > 20) {
        screen.pen = blit::Pen(b, g, r, 100);
        screen.pixel(p.pos + blit::Point(0, -1));
        screen.pen = blit::Pen(b, g, r, 160);
        screen.pixel(p.pos + blit::Point(0, 1));
      }
      screen.pen = blit::Pen(b, g, r, 180);
      screen.pixel(p.pos);
    }
  }
};

void MainTask(void*) {
  // Timing variables
  kudzu::FrameCounter frame_counter = kudzu::FrameCounter();

  PW_CHECK_OK(Common::Init());

  Display& display = Common::GetDisplay();
  Framebuffer framebuffer = display.GetFramebuffer();
  PW_ASSERT(framebuffer.is_valid());

  kudzu::Buttons& kudzu_buttons = Common::GetButtons();

  blit::Surface screen = blit::Surface(
      (uint8_t*)framebuffer.data(),
      blit::PixelFormat::RGB565,
      blit::Size(framebuffer.size().width, framebuffer.size().height));
  screen.pen = blit::Pen(0, 0, 0, 255);
  screen.clear();

  display.ReleaseFramebuffer(std::move(framebuffer));
  const int32_t init_text_pos_x = screen.bounds.w / 2;
  int32_t text_pos_x = init_text_pos_x;
  const int32_t init_text_pos_y = screen.bounds.h * 0.75;
  int32_t text_pos_y = init_text_pos_y;

  // NOTE: colors are in BGR order
  static constexpr const std::array text_colors{
      blit::Pen(0xFF, 0xFF, 0xFF),
      blit::Pen(0xB8, 0xA9, 0xF5),
      blit::Pen(0xFA, 0xCE, 0x5B),
  };
  int text_color_index = 0;

  static const std::array fonts{
      blit::minimal_font,
      blit::outline_font,
      blit::fat_font,
  };
  int font_index = 0;

  // The display loop.
  while (1) {
    kudzu_buttons.Update();
    if (kudzu_buttons.Held(kudzu::button::up)) {
      text_pos_y -= 1;
    }
    if (kudzu_buttons.Held(kudzu::button::down)) {
      text_pos_y += 1;
    }
    if (kudzu_buttons.Held(kudzu::button::left)) {
      text_pos_x -= 1;
    }
    if (kudzu_buttons.Held(kudzu::button::right)) {
      text_pos_x += 1;
    }
    if (kudzu_buttons.Pressed(kudzu::button::a)) {
      text_color_index = (text_color_index + 1) % text_colors.size();
    }
    if (kudzu_buttons.Pressed(kudzu::button::b)) {
      font_index = (font_index + 1) % fonts.size();
    }
    if (kudzu_buttons.Pressed(kudzu::button::start)) {
      text_pos_x = init_text_pos_x;
      text_pos_y = init_text_pos_y;
    }

    frame_counter.StartFrame();

    framebuffer = display.GetFramebuffer();
    PW_ASSERT(framebuffer.is_valid());
    screen.data = (uint8_t*)framebuffer.data();

    // Draw Phase
    // Clear the screen
    screen.pen = blit::Pen(0, 0, 0);
    screen.clear();

    // Draw 32blit animation
    std::string text = "Pigweed + 32blit";
    auto text_size = screen.measure_text(text, fonts[font_index], true);

    // Ensure that the text stays on-screen by wrapping its position around.
    int32_t width = screen.bounds.w;
    int32_t height = screen.bounds.h;

    int32_t min_x = 0 - (text_size.w / 2);
    int32_t max_x = width + (text_size.w / 2);
    int32_t min_y = 0 - (text_size.h / 2);
    int32_t max_y = height + (text_size.h / 2);

    if (text_pos_x < min_x) {
      text_pos_x = max_x;
    }
    if (text_pos_x > max_x) {
      text_pos_x = min_x;
    }
    if (text_pos_y < min_y) {
      text_pos_y = max_y;
    }
    if (text_pos_y > max_y) {
      text_pos_y = min_y;
    }

    blit::Rect text_rect(blit::Point(text_pos_x - (text_size.w / 2),
                                     text_pos_y - (text_size.h / 2)),
                         text_size);

    rain(screen, frame_counter.LastFrameDuration(), text_rect);
    screen.pen = text_colors[text_color_index];
    screen.text(
        text, fonts[font_index], text_rect, true, blit::TextAlign::top_left);

    // Update timers
    frame_counter.EndDraw();

    display.ReleaseFramebuffer(std::move(framebuffer));
    frame_counter.EndFlush();

    // Every second make a log message.
    frame_counter.LogTiming();
  }
}

}  // namespace

namespace pw::system {

void UserAppInit() {
  PW_LOG_INFO("UserAppInit");
  pw::thread::DetachedThread(Common::DisplayDrawThreadOptions(), MainTask);
}

}  // namespace pw::system
