// 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_board_led/led.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::colors_pico8_rgb565;
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),
                     GetRandomFloat(10) - (screen.bounds.h + 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 floor_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();

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

      int floor = -3;
      if (p.pos.x > floor_position.x &&
          p.pos.x < (floor_position.x + floor_position.w))
        floor = -3 - (screen.bounds.h - floor_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 / 2);
      int b = 255;  // -(a * 4);

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

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

  pw::board_led::Init();
  PW_CHECK_OK(Common::Init());

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

  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));

  // The display loop.
  while (1) {
    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, blit::minimal_font, true);
    blit::Rect text_rect(
        blit::Point((screen.bounds.w / 2) - (text_size.w / 2),
                    (screen.bounds.h * .75) - (text_size.h / 2)),
        text_size);

    rain(screen, frame_counter.LastFrameDuration(), text_rect);
    screen.pen = blit::Pen(0xFF, 0xFF, 0xFF);
    screen.text(
        text, blit::minimal_font, 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
