// 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.
//
// LCD Facade using imgui running on a host machine.
// Much of this code is from the imgui example:
// https://github.com/ocornut/imgui/tree/master/examples/example_glfw_opengl3
// As well as the wiki page:
// https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples

#include "pw_display_driver_imgui/display_driver.h"

// To silence large number of warnings (at least on macOS).
#define GL_SILENCE_DEPRECATION

#if defined(IMGUI_IMPL_OPENGL_ES2)
#include <GLES2/gl2.h>
#endif
#include <GLFW/glfw3.h>  // Will pull in system OpenGL headers

#include "imgui.h"
#include "imgui_impl_glfw.h"
#include "imgui_impl_opengl3.h"
#include "pw_framebuffer/reader.h"

using pw::color::color_rgb565_t;
using pw::framebuffer::Framebuffer;
using pw::framebuffer::FramebufferReader;
using pw::framebuffer::PixelFormat;

namespace pw::display_driver {

namespace {

constexpr uint16_t kDisplayWidth = 320;
constexpr uint16_t kDisplayHeight = 240;
constexpr size_t kDisplayDataSize = kDisplayWidth * kDisplayHeight;

// OpenGL texture data.
GLuint lcd_pixel_data[kDisplayDataSize];

// imgui state
bool show_imgui_demo_window = false;
ImVec4 clear_color = ImVec4(0.27f, 0.27f, 0.27f, 1.00f);
GLuint lcd_texture = 0;
GLFWwindow* window;
int lcd_texture_display_scale = 3;
int old_lcd_texture_display_scale = 0;
bool lcd_texture_display_mode_nearest = true;
bool old_lcd_texture_display_mode_nearest = true;

bool left_mouse_pressed = false;
int texture_mouse_x = 0;
int texture_mouse_y = 0;

void CleanupAndExit() {
  ImGui_ImplOpenGL3_Shutdown();
  ImGui_ImplGlfw_Shutdown();
  ImGui::DestroyContext();

  glfwDestroyWindow(window);
  glfwTerminate();
  exit(0);
}

void HelpMarker(const char* desc) {
  ImGui::TextDisabled("(?)");
  if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort)) {
    ImGui::BeginTooltip();
    ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
    ImGui::TextUnformatted(desc);
    ImGui::PopTextWrapPos();
    ImGui::EndTooltip();
  }
}

void _SetTexturePixel(
    GLuint x, GLuint y, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
  // Calculate target color
  GLuint target_color;
  GLubyte* colors = (GLubyte*)&target_color;
  colors[0] = r;
  colors[1] = g;
  colors[2] = b;
  colors[3] = a;
  lcd_pixel_data[y * kDisplayWidth + x] = target_color;
}

void _SetTexturePixel(GLuint x, GLuint y, uint8_t r, uint8_t g, uint8_t b) {
  _SetTexturePixel(x, y, r, g, b, 255);
}

void _SetTexturePixel(GLuint x, GLuint y, color_rgb565_t rgb565) {
  pw::color::ColorRGBA c(rgb565);
  _SetTexturePixel(x, y, c.r, c.g, c.b, 255);
}

void UpdateLcdTexture() {
  // Set current texture
  glBindTexture(GL_TEXTURE_2D, lcd_texture);
  // Update texture
  glTexSubImage2D(GL_TEXTURE_2D,
                  0,
                  0,
                  0,
                  kDisplayWidth,
                  kDisplayHeight,
                  GL_RGBA,
                  GL_UNSIGNED_BYTE,
                  lcd_pixel_data);
  // Unbind texture
  glBindTexture(GL_TEXTURE_2D, 0);
}

void SetupLcdTexture(GLuint* out_texture) {
  // Create a OpenGL texture identifier
  GLuint image_texture;
  glGenTextures(1, &image_texture);
  glBindTexture(GL_TEXTURE_2D, image_texture);

  // Setup filtering parameters for display
  GLuint display_mode =
      lcd_texture_display_mode_nearest ? GL_NEAREST : GL_LINEAR;
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, display_mode);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, display_mode);
  glTexParameteri(GL_TEXTURE_2D,
                  GL_TEXTURE_WRAP_S,
                  GL_CLAMP_TO_EDGE);  // This is required on WebGL for non
                                      // power-of-two textures
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);  // Same

  // Upload pixels into texture
#if defined(GL_UNPACK_ROW_LENGTH) && !defined(__EMSCRIPTEN__)
  glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
#endif
  glTexImage2D(GL_TEXTURE_2D,
               0,
               GL_RGBA,
               kDisplayWidth,
               kDisplayHeight,
               0,
               GL_RGBA,
               GL_UNSIGNED_BYTE,
               lcd_pixel_data);

  glBindTexture(GL_TEXTURE_2D, 0);

  *out_texture = image_texture;
}

void glfw_error_callback(int error, const char* description) {
  fprintf(stderr, "Glfw Error %d: %s\n", error, description);
}

}  // namespace

DisplayDriverImgUI::DisplayDriverImgUI() = default;

Status DisplayDriverImgUI::Init() {
  // Setup window
  glfwSetErrorCallback(glfw_error_callback);
  if (!glfwInit())
    return Status::Internal();

    // Decide GL+GLSL versions
#if defined(IMGUI_IMPL_OPENGL_ES2)
  // GL ES 2.0 + GLSL 100
  const char* glsl_version = "#version 100";
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
  glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
#elif defined(__APPLE__)
  // GL 3.2 + GLSL 150
  const char* glsl_version = "#version 150";
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);  // 3.2+ only
  glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);  // Required on Mac
#else
  // GL 3.0 + GLSL 130
  const char* glsl_version = "#version 130";
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
  // glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);  // 3.2+
  // only glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 3.0+ only
#endif

  // Create window with graphics context
  window = glfwCreateWindow(1280, 800, "pw_display", NULL, NULL);
  if (window == NULL)
    return Status::Internal();
  glfwMakeContextCurrent(window);
  glfwSwapInterval(1);  // Enable vsync

  // Setup Dear ImGui context
  IMGUI_CHECKVERSION();
  ImGui::CreateContext();
  ImGuiIO& io = ImGui::GetIO();
  (void)io;
  // io.Fonts->AddFontFromFileTTF("NotoSans-Regular.ttf", 32.0);

  // Enable Keyboard Controls
  io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
  io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
  io.ConfigFlags |= ImGuiConfigFlags_DpiEnableScaleFonts;
  // Enable Gamepad Controls
  // io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;

  // Setup Dear ImGui style
  ImGui::StyleColorsDark();
  // ImGui::StyleColorsLight();
  // ImGui::StyleColorsClassic();

  // Setup Platform/Renderer backends
  ImGui_ImplGlfw_InitForOpenGL(window, true);
  ImGui_ImplOpenGL3_Init(glsl_version);

  SetupLcdTexture(&lcd_texture);
  return OkStatus();
}

void DisplayDriverImgUI::RecreateLcdTexture() {
  if (old_lcd_texture_display_mode_nearest !=
      lcd_texture_display_mode_nearest) {
    old_lcd_texture_display_mode_nearest = lcd_texture_display_mode_nearest;
    SetupLcdTexture(&lcd_texture);
  }
}

void DisplayDriverImgUI::Render() {
  UpdateLcdTexture();

  // Poll and handle events (inputs, window resize, etc.)
  glfwPollEvents();

  left_mouse_pressed = false;
  double mouse_xpos = 0, mouse_ypos = 0;
  glfwGetCursorPos(window, &mouse_xpos, &mouse_ypos);
  if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS) {
    left_mouse_pressed = true;
  }

  // Start the Dear ImGui frame
  ImGui_ImplOpenGL3_NewFrame();
  ImGui_ImplGlfw_NewFrame();
  ImGui::NewFrame();
  ImGuiIO& io = ImGui::GetIO();

  int display_w, display_h;
  glfwGetFramebufferSize(window, &display_w, &display_h);

  // Build the empty dockspace background

  static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;
  ImGuiWindowFlags window_flags =
      ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
  const ImGuiViewport* viewport = ImGui::GetMainViewport();
  ImGui::SetNextWindowPos(viewport->WorkPos);
  ImGui::SetNextWindowSize(viewport->WorkSize);
  ImGui::SetNextWindowViewport(viewport->ID);
  ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
  ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
  window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
                  ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
  window_flags |=
      ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;

  // 0px padding around the dockspace
  ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
  // Start docspace window
  ImGui::Begin("DockSpace", NULL, window_flags);

  // Create empty dockspace container
  ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
  ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);

  ImGui::PopStyleVar();   // Padding around docspace window
  ImGui::PopStyleVar(2);  // WindowRounding and WindowBorderSize

  // Dockspace menu
  if (ImGui::BeginMenuBar()) {
    if (ImGui::BeginMenu("Options")) {
      ImGui::MenuItem("Show Imgui Demo Window", "", &show_imgui_demo_window);
      ImGui::Separator();
      if (ImGui::MenuItem("Quit")) {
        CleanupAndExit();
      }
      ImGui::EndMenu();
    }
    HelpMarker(
        "Window Docking: "
        "\n"
        "- Drag from window title bar or their tab to dock/undock."
        "\n"
        "- Drag from window menu button (upper-left button) to undock an "
        "entire node (all windows)."
        "\n"
        "- Hold SHIFT to disable docking");

    ImGui::EndMenuBar();
  }

  ImGui::End();  // end dockspace

  // 1. Show the big demo window (Most of the sample code is in
  // ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear
  // ImGui!).
  if (show_imgui_demo_window) {
    ImGui::ShowDemoWindow(&show_imgui_demo_window);
  }

  // Draw Screen(s)

  // Screen 1 Window
  ImGui::Begin("Screen 1");
  // Calculate the display texture draw coordinates
  int scaled_width = kDisplayWidth * lcd_texture_display_scale;
  int scaled_height = kDisplayHeight * lcd_texture_display_scale;

  ImVec2 mouse_pos = ImGui::GetCursorScreenPos();
  ImVec2 mouse_coordinates_of_base_image;
  ImGui::Image((void*)(intptr_t)lcd_texture,
               ImVec2(scaled_width, scaled_height),
               // Top left texure coord
               ImVec2(0.0f, 0.0f),
               // Lower right texture coord
               ImVec2(1.0f, 1.0f),
               // Tint (none applied)
               ImVec4(1.0f, 1.0f, 1.0f, 1.0f),
               // Border color (50% white)
               ImVec4(1.0f, 1.0f, 1.0f, 0.5f));
  mouse_coordinates_of_base_image.x =
      floor((io.MousePos.x - mouse_pos.x) / lcd_texture_display_scale);
  mouse_coordinates_of_base_image.y =
      floor((io.MousePos.y - mouse_pos.y) / lcd_texture_display_scale);
  if (ImGui::IsItemHovered()) {
    ImGui::BeginTooltip();
    ImGui::Text("mouse coords = %.1f, %.1f",
                mouse_coordinates_of_base_image.x,
                mouse_coordinates_of_base_image.y);
    ImGui::EndTooltip();
  }
  ImGui::End();  // Screen 1 Window

  // For reference this forces the "Screen 1" window to be docked to the main
  // dockspace:
  //   ImGui::DockBuilderDockWindow("Screen 1", dockspace_id);

  ImGui::Begin("Screen 1 Settings");
  ImGui::Text("Pixel Size = %d x %d", kDisplayWidth, kDisplayHeight);
  ImGui::SliderInt("Integer Scaling", &lcd_texture_display_scale, 1, 10);
  ImGui::Checkbox("Nearest neighbor", &lcd_texture_display_mode_nearest);

  ImGui::Separator();
  texture_mouse_x = mouse_coordinates_of_base_image.x;
  texture_mouse_y = mouse_coordinates_of_base_image.y;
  ImGui::Text("Mouse position = %d, %d", texture_mouse_x, texture_mouse_y);
  ImGui::Text("Mouse Left button pressed: %d", left_mouse_pressed);

  // Demo Window toggle
  ImGui::Separator();

  ImGui::Text("Application average %.3f ms/frame (%.1f FPS)",
              1000.0f / ImGui::GetIO().Framerate,
              ImGui::GetIO().Framerate);

  ImGui::End();

  // Done building the UI
  ImGui::Render();

  glViewport(0, 0, display_w, display_h);
  glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
  glClear(GL_COLOR_BUFFER_BIT);
  // Render ImGui
  ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

  glfwSwapBuffers(window);

  if (glfwWindowShouldClose(window)) {
    CleanupAndExit();
  }
}

void DisplayDriverImgUI::WriteFramebuffer(Framebuffer framebuffer,
                                          WriteCallback write_callback) {
  PW_ASSERT(framebuffer.is_valid());
  PW_ASSERT(framebuffer.pixel_format() == PixelFormat::RGB565);
  RecreateLcdTexture();

  FramebufferReader reader(framebuffer);
  // Copy frame_buffer into lcd_pixel_data
  for (GLuint x = 0; x < kDisplayWidth; x++) {
    for (GLuint y = 0; y < kDisplayHeight; y++) {
      if (auto c = reader.GetPixel(x, y); c.ok()) {
        _SetTexturePixel(x, y, c.value());
      }
    }
  }

  Render();
  write_callback(std::move(framebuffer), OkStatus());
}

Status DisplayDriverImgUI::WriteRow(span<uint16_t> row_pixels,
                                    uint16_t row_idx,
                                    uint16_t col_idx) {
  RecreateLcdTexture();

  for (auto c : row_pixels) {
    _SetTexturePixel(col_idx++, row_idx, c);
  }

  // Rendering here is horribly slow - come up with better solution.
  Render();
  return OkStatus();
}

uint16_t DisplayDriverImgUI::GetWidth() const { return kDisplayWidth; }

uint16_t DisplayDriverImgUI::GetHeight() const { return kDisplayHeight; }

bool DisplayDriverImgUI::NewTouchEvent() { return left_mouse_pressed; }

pw::math::Vector3<int> DisplayDriverImgUI::GetTouchPoint() {
  if (left_mouse_pressed && texture_mouse_x >= 0 &&
      texture_mouse_x < kDisplayWidth && texture_mouse_y >= 0 &&
      texture_mouse_y < kDisplayHeight) {
    return {texture_mouse_x, texture_mouse_y, 1};
  }
  return {0, 0, 0};
}

}  // namespace pw::display_driver
