// 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 <cstdint>

#define PW_LOG_MODULE_NAME "SnakeGame"
#define PW_LOG_LEVEL PW_LOG_LEVEL_DEBUG

#include "app_common/common.h"
#include "graphics/surface.hpp"
#include "libkudzu/framecounter.h"
#include "pw_assert/check.h"
#include "pw_board_led/led.h"
#include "pw_display/display.h"
#include "pw_framebuffer/framebuffer.h"
#include "pw_log/log.h"
#include "pw_spin_delay/delay.h"
#include "pw_system/target_hooks.h"
#include "pw_system/work_queue.h"
#include "pw_thread/detached_thread.h"
#include "pw_thread/thread_core.h"
#include "pw_touchscreen/buttons.h"
#include "pw_touchscreen/touchscreen.h"
#include "snake/game.h"

namespace {

constexpr uint32_t kFramesPerSecond = 16;
constexpr uint32_t kWaitMillis = 1000 / kFramesPerSecond;

class PollingTouchButtonsThread : public pw::thread::ThreadCore {
 public:
  PollingTouchButtonsThread(
      pw::touchscreen::Touchscreen& touchscreen,
      pw::touchscreen::DirectionButtonListener& button_listener,
      int32_t display_width,
      int32_t display_height)
      : touchscreen_(touchscreen),
        buttons_(button_listener, display_width, display_height) {}

  void Run() override {
    while (true) {
      pw::touchscreen::TouchEvent touch_event = touchscreen_.GetTouchPoint();
      buttons_.OnTouchEvent(touch_event);
      pw::spin_delay::WaitMillis(kWaitMillis);
    }
  }

 private:
  pw::touchscreen::Touchscreen& touchscreen_;
  pw::touchscreen::DirectionTouchButtons buttons_;
};

void MainTask(void*) {
  pw::board_led::Init();
  PW_CHECK_OK(Common::Init());

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

  blit::Surface screen = blit::Surface(
      static_cast<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();

  const auto display_width = framebuffer.size().width;
  const auto display_height = framebuffer.size().height;
  display.ReleaseFramebuffer(std::move(framebuffer));

  snake::Game game(display_width, display_height);
  PollingTouchButtonsThread touch_buttons_thread{
      Common::GetTouchscreen(), game, display_width, display_height};
  pw::thread::DetachedThread(Common::TouchscreenThreadOptions(),
                             touch_buttons_thread);

  game.Start();

  // Display and app loop.
  kudzu::FrameCounter frame_counter = kudzu::FrameCounter();
  uint32_t last_report_time = pw::spin_delay::Millis();
  while (true) {
    frame_counter.StartFrame();

    // Get frame buffer.
    framebuffer = display.GetFramebuffer();
    PW_CHECK(framebuffer.is_valid());
    screen.data = static_cast<uint8_t*>(framebuffer.data());
    // Clear the screen
    screen.pen = blit::Pen(0, 0, 0);
    screen.clear();

    // Let game draw its frame.
    game.OnFrame(framebuffer);

    // Update timers
    frame_counter.EndDraw();

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

    frame_counter.EndFrame();

    pw::spin_delay::WaitMillis(kWaitMillis);

    // Periodically make a log message.
    if (pw::spin_delay::Millis() > last_report_time + 10000) {
      Common::EndOfFrameCallback();
      last_report_time = pw::spin_delay::Millis();
    }
  }
}

}  // namespace

namespace pw::system {

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

}  // namespace pw::system
