// Copyright 2022 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>
#include <forward_list>

#define PW_LOG_LEVEL PW_LOG_LEVEL_DEBUG

#include "ansi.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_coordinates/vec2.h"
#include "pw_coordinates/vec_int.h"
#include "pw_display/display.h"
#include "pw_draw/draw.h"
#include "pw_draw/font_set.h"
#include "pw_draw/pigweed_farm.h"
#include "pw_draw/text_area.h"
#include "pw_framebuffer/rgb565.h"
#include "pw_log/log.h"
#include "pw_spin_delay/delay.h"
#include "pw_string/string_builder.h"
#include "pw_sys_io/sys_io.h"
#include "pw_touchscreen/touchscreen.h"

using pw::color::colors_pico8_rgb565;

namespace {

typedef bool (*bool_function_pointer)();
typedef pw::coordinates::Vec3Int (*vec3int_function_pointer)();
pw::framebuffer::FramebufferRgb565 frame_buffer = FramebufferRgb565();
pw::draw::TextArea log_text_area(&frame_buffer, &pw::draw::font6x8);

class DemoDecoder : public AnsiDecoder {
 protected:
  virtual void SetFgColor(uint8_t r, uint8_t g, uint8_t b) {
    log_text_area.SetForegroundColor(pw::color::ColorRGBA(r, g, b).ToRgb565());
  }
  virtual void SetBgColor(uint8_t r, uint8_t g, uint8_t b) {
    log_text_area.SetBackgroundColor(pw::color::ColorRGBA(r, g, b).ToRgb565());
  }
  virtual void EmitChar(char c) { log_text_area.DrawCharacter(c); }
};

DemoDecoder demo_decoder = DemoDecoder();

void (*write_log_to_screen)(std::string_view) = [](std::string_view log) {
  static int cursor_x = 0;
  static int cursor_y =
      log_text_area.framebuffer->height - log_text_area.current_font->height;
  log_text_area.SetCursor(cursor_x, cursor_y);

  for (auto c : log) {
    demo_decoder.ProcessChar(c);
  }
  demo_decoder.ProcessChar('\n');

  cursor_x = log_text_area.cursor_x;
  cursor_y = log_text_area.cursor_y;

  pw::sys_io::WriteLine(log).IgnoreError();
};

const wchar_t pigweed_banner[] = {
    L"▒█████▄   █▓  ▄███▒  ▒█    ▒█ ░▓████▒ ░▓████▒ ▒▓████▄\n"
    L" ▒█░  █░ ░█▒ ██▒ ▀█▒ ▒█░ █ ▒█  ▒█   ▀  ▒█   ▀  ▒█  ▀█▌\n"
    L" ▒█▄▄▄█░ ░█▒ █▓░ ▄▄░ ▒█░ █ ▒█  ▒███    ▒███    ░█   █▌\n"
    L" ▒█▀     ░█░ ▓█   █▓ ░█░ █ ▒█  ▒█   ▄  ▒█   ▄  ░█  ▄█▌\n"
    L" ▒█      ░█░ ░▓███▀   ▒█▓▀▓█░ ░▓████▒ ░▓████▒ ▒▓████▀\n"};

void draw_sprite_and_text_demo() {
  int sprite_pos_x = 10;
  int sprite_pos_y = 24;
  int sprite_scale = 4;
  int border_size = 8;

  // Draw the dark blue border
  pw::draw::DrawRectWH(
      &frame_buffer,
      sprite_pos_x - border_size,
      sprite_pos_y - border_size,
      pigweed_farm_sprite_sheet.width * sprite_scale + (border_size * 2),
      pigweed_farm_sprite_sheet.height * sprite_scale + (border_size * 2),
      colors_pico8_rgb565[COLOR_DARK_BLUE],
      true);

  // Shrink the border
  border_size = 4;

  // Draw the light blue background
  pw::draw::DrawRectWH(
      &frame_buffer,
      sprite_pos_x - border_size,
      sprite_pos_y - border_size,
      pigweed_farm_sprite_sheet.width * sprite_scale + (border_size * 2),
      pigweed_farm_sprite_sheet.height * sprite_scale + (border_size * 2),
      colors_pico8_rgb565[COLOR_BLUE],
      true);

  // Draw the Sun
  frame_buffer.SetPenColor(colors_pico8_rgb565[COLOR_ORANGE]);
  pw::draw::DrawCircle(
      &frame_buffer,
      sprite_pos_x + (pigweed_farm_sprite_sheet.width * sprite_scale) - 32,
      sprite_pos_y,
      20,
      true);
  frame_buffer.SetPenColor(colors_pico8_rgb565[COLOR_YELLOW]);
  pw::draw::DrawCircle(
      &frame_buffer,
      sprite_pos_x + (pigweed_farm_sprite_sheet.width * sprite_scale) - 32,
      sprite_pos_y,
      18,
      true);

  // Draw the farm sprite's shadow
  pigweed_farm_sprite_sheet.current_index = 1;
  pw::draw::DrawSprite(&frame_buffer,
                       sprite_pos_x + 2,
                       sprite_pos_y + 2,
                       &pigweed_farm_sprite_sheet,
                       4);

  // Draw the farm sprite
  pigweed_farm_sprite_sheet.current_index = 0;
  pw::draw::DrawSprite(
      &frame_buffer, sprite_pos_x, sprite_pos_y, &pigweed_farm_sprite_sheet, 4);

  // Draw some text
  pw::draw::TextArea text_area(&frame_buffer, &pw::draw::font6x8_box_chars);

  // Start drawing a x=0, y=72
  text_area.DrawCharacter('\n', 0, 72);

  // Draw the Pigweed "ASCII" banner.
  text_area.SetForegroundColor(colors_pico8_rgb565[COLOR_PINK]);
  text_area.SetCharacterWrap(false);
  text_area.DrawText(pigweed_banner);
  text_area.SetCharacterWrap(true);

  text_area.SetFont(&pw::draw::font6x8);
  for (int c = pw::draw::font6x8.starting_character;
       c <= pw::draw::font6x8.ending_character;
       c++) {
    if (c % 32 == 0) {
      text_area.DrawCharacter('\n');
    }
    text_area.SetForegroundColor(0);
    text_area.SetBackgroundColor(colors_endesga32_rgb565[c % 32]);
    text_area.DrawCharacter(c);
  }
  // Reset background to black
  text_area.SetBackgroundColor(0);
  text_area.DrawCharacter('\n');

  text_area.SetForegroundColor(0xFFFF);
  text_area.SetFont(&pw::draw::font6x8);
  text_area.DrawTestFontSheet(32, text_area.cursor_x, text_area.cursor_y);
  text_area.DrawText("\n\nBox Characters:\n");

  text_area.SetFont(&pw::draw::font6x8_box_chars);
  text_area.DrawTestFontSheet(32, text_area.cursor_x, text_area.cursor_y);

  text_area.SetFont(&pw::draw::font6x8);
  text_area.DrawCharacter('\n');
}

bool_function_pointer touch_screen_available_func;
vec3int_function_pointer get_touch_screen_point_func;
bool_function_pointer new_touch_event_func;
bool touch_screen_exists = false;

void setup_touchscreen_functions() {
  // Default to using pw::touchscreen but use pw::display if it's supported.
  touch_screen_available_func = &pw::touchscreen::Available;
  get_touch_screen_point_func = &pw::touchscreen::GetTouchPoint;
  new_touch_event_func = &pw::touchscreen::NewTouchEvent;
  // Check if pw::display implements touchscreen functions
  if (pw::display::TouchscreenAvailable()) {
    touch_screen_available_func = &pw::display::TouchscreenAvailable;
    get_touch_screen_point_func = &pw::display::GetTouchPoint;
    new_touch_event_func = &pw::display::NewTouchEvent;
  }
  touch_screen_exists = (*touch_screen_available_func)();
}

void create_demo_log_messages() {
  // Create some demo log messages.
  PW_LOG_CRITICAL("An irrecoverable error has occurred!");
  PW_LOG_ERROR("There was an error on our last operation");
  PW_LOG_WARN("Looks like something is amiss; consider investigating");
  PW_LOG_INFO("The operation went as expected");
  PW_LOG_DEBUG("Debug output");
}

// Full resolution
#define FRAMEBUFFER_WIDTH 320
#define FRAMEBUFFER_HEIGHT 240
#define FRAMEBUFFER_UPDATE_FUNCTION Update

// Half resolution
// #define FRAMEBUFFER_WIDTH 160
// #define FRAMEBUFFER_HEIGHT 120
// #define FRAMEBUFFER_UPDATE_FUNCTION UpdatePixelDouble

uint16_t display_framebuffer_data[FRAMEBUFFER_WIDTH * FRAMEBUFFER_HEIGHT];

}  // namespace

int main() {
  // Timing variables
  uint32_t frame_start_millis = pw::spin_delay::Millis();
  uint32_t frames = 0;
  int frames_per_second = 0;

  uint32_t time_start_delta = 0;
  uint32_t delta_time = 30000;  // Initial guess

  uint32_t time_start_button_check = pw::spin_delay::Millis();
  uint32_t delta_button_check = pw::spin_delay::Millis();

  uint32_t time_start_game_logic = 0;
  uint32_t delta_game_logic = 0;

  uint32_t time_start_draw_screen = 0;
  uint32_t delta_screen_draw = 0;

  uint32_t time_start_screen_spi_update = 0;
  uint32_t delta_screen_spi_update = 0;

  pw::board_led::Init();

  frame_buffer.SetFramebufferData(
      display_framebuffer_data, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT);

  // Clear the framebuffer to black
  frame_buffer.SetPenColor(0);
  pw::draw::Fill(&frame_buffer);

  // Init the display and touchscreen.
  PW_LOG_INFO("pw::display::Init()");
  pw::display::Init();
  PW_LOG_INFO("pw::touchscreen::Init()");
  pw::touchscreen::Init();

  // Change log output function to write_log_to_screen.
  log_text_area.SetBackgroundColor(0);
  pw::log_basic::SetOutput(*write_log_to_screen);

  // Touchscreen Functions
  setup_touchscreen_functions();

  // Touch event variables
  Vec2 screen_center =
      Vec2(frame_buffer.width / 2.0, frame_buffer.height / 2.0);
  Vec2 touch_location;
  Vec2 touch_location_from_origin;
  float touch_location_angle;
  float touch_location_length;

  pw::coordinates::Vec3Int last_frame_touch_state(0, 0, 0);

  draw_sprite_and_text_demo();
  // Push the frame buffer to the screen.
  pw::display::FRAMEBUFFER_UPDATE_FUNCTION(&frame_buffer);

  // Setup the log message button position variables.
  pw::draw::TextArea button_text_area(&frame_buffer, &pw::draw::font6x8);
  int button_width = 19 * button_text_area.current_font->width;
  int button_height = button_text_area.current_font->height;
  int button_pos_x = frame_buffer.width - button_width;
  int button_pos_y = 0;
  button_text_area.SetCursor(button_pos_x, button_pos_y);
  button_text_area.SetForegroundColor(colors_pico8_rgb565[COLOR_BLACK]);
  button_text_area.SetBackgroundColor(colors_pico8_rgb565[COLOR_BLUE]);

  // The display loop.
  while (1) {
    time_start_delta = pw::spin_delay::Millis();

    // Input Update Phase
    time_start_button_check = pw::spin_delay::Millis();

    pw::coordinates::Vec3Int point = (*get_touch_screen_point_func)();
    // Check for touchscreen events.
    if (touch_screen_exists && (*new_touch_event_func)()) {
      if (point.z > 0) {
        bool button_just_pressed = false;
        if (point.z != last_frame_touch_state.z)
          button_just_pressed = true;
        // New touch event
        touch_location = Vec2(point.x, point.y);
        touch_location_from_origin = touch_location - screen_center;
        touch_location_angle = touch_location_from_origin.angle();
        touch_location_length = touch_location_from_origin.length();

        PW_LOG_DEBUG("Touch: x:%d, y:%d, z:%d", point.x, point.y, point.z);

        // Find the angle and length of the touch location from the
        // screen_center.
        //
        // touch_location_angle will fall within the range [-pi, pi]
        // Map it to [0, 2*pi] instead.
        // if (touch_location_angle < 0)
        //   touch_location_angle = kTwoPi + touch_location_angle;
        // touch_location_angle = kTwoPi - touch_location_angle;
        // PW_LOG_DEBUG("       degrees:%f length:%f",
        //              degrees(touch_location_angle),
        //              touch_location_length);

        // If a button was just pressed, call create_demo_log_messages.
        if (button_just_pressed && touch_location.x >= button_pos_x &&
            touch_location.y >= button_pos_y &&
            touch_location.x < button_pos_x + button_width &&
            touch_location.y < button_pos_y + button_height) {
          create_demo_log_messages();
        }
      }
    }
    last_frame_touch_state.x = point.x;
    last_frame_touch_state.y = point.y;
    last_frame_touch_state.z = point.z;

    // End Input Update Phase
    delta_button_check = pw::spin_delay::Millis() - time_start_button_check;

    // Game Logic Phase
    time_start_game_logic = pw::spin_delay::Millis();

    // End Game Logic Phase
    delta_game_logic = pw::spin_delay::Millis() - time_start_game_logic;

    // Draw Phase
    time_start_draw_screen = pw::spin_delay::Millis();

    button_text_area.SetCursor(button_pos_x, button_pos_y);
    button_text_area.DrawText(" Click to add logs ");

    // End Draw Phase
    delta_screen_draw = pw::spin_delay::Millis() - time_start_draw_screen;

    // Display Write Phase
    time_start_screen_spi_update = pw::spin_delay::Millis();

    pw::display::FRAMEBUFFER_UPDATE_FUNCTION(&frame_buffer);

    // End Display Write Phase
    delta_screen_spi_update =
        pw::spin_delay::Millis() - time_start_screen_spi_update;

    // FPS Count Update
    delta_time = pw::spin_delay::Millis() - time_start_delta;

    // Every second make a log message.
    frames++;
    if (pw::spin_delay::Millis() > frame_start_millis + 1000) {
      // Log FPS Stats
      PW_LOG_INFO(
          "Time: %u - FPS: %d", pw::spin_delay::Millis(), frames_per_second);

      frames_per_second = frames;
      frames = 0;

      frame_start_millis = pw::spin_delay::Millis();
    }
  }
}
