#include "mainWindow.h"

#include "core/appContext.h"

using namespace std;
using namespace quokka_gfx;
//--------------------------------------------------------------
/* Constructor */
MainWindow::MainWindow(AppContext &appContext, quokka_gfx::Application &app)
  : Window(app, "VolaTile", { .w = 1024, .h = 768 }, SDL_WINDOW_RESIZABLE /*| SDL_WINDOW_MAXIMIZED*/)
  , m_appContext(appContext)
  , m_backgroundLayer(*this)
  , m_keyboardLayer(*this, { .w = 1024, .h = 768 })
{
  // Initialization
  SetMinSize({ .w = 1024, .h = 768 });

  // Retrieve the current size of the window (in pixels)
  Size windowSize;
  SDL_GetWindowSize(m_nativeWindow, &windowSize.w, &windowSize.h);

  // Post initialization
  onResize(windowSize);
}
//--------------------------------------------------------------
/* Handle event */
void MainWindow::OnEvent(SDL_Event *event)
{
  // Handle window resize event
  // SDL_EVENT_WINDOW_EXPOSED
  switch (event->type)
  {
    case SDL_EVENT_WINDOW_RESIZED:
    case SDL_EVENT_WINDOW_EXPOSED:
    {
      Size windowSize;

      // Get the current size of the rendering output (in pixels)
      SDL_GetRenderOutputSize(GetRenderer()->getNativeRenderer(), &windowSize.w, &windowSize.h);

      // Update geometry and layout
      onResize(windowSize);

      // Request a redraw of the window content
      Render();
    }
  }
}
//--------------------------------------------------------------
/* Update the window state */
void MainWindow::Update(const float dt)
{
  const auto &inputManager = GetInputManager();
  if (inputManager->isKeyPressed(SDL_SCANCODE_ESCAPE))
    Close();

  // Manage playback state based on user input
  if (inputManager->isKeyPressed(SDL_SCANCODE_S))
    m_playbackState = PlaybackState::Stopped;
  if (inputManager->isKeyPressed(SDL_SCANCODE_P))
  {
    if (m_playbackState == PlaybackState::Playing)
      m_playbackState = PlaybackState::Paused;
    else
      m_playbackState = PlaybackState::Playing;
  }

  // Retrieve active notes and upcoming notes from the track based on the current music time
  updateMusicTime(dt);     // Update music time
  const auto notes = m_appContext.m_hTrack->getTrackWindow(m_musicTime, m_musicTime + 1000ms);

  // Update the visual piano with the active notes
  std::vector<int> activeMidiNotes;
  for (const auto note : notes.activeNotes)
  {
    if (note.noteOn)
      activeMidiNotes.push_back(note.pitch);
  }
  m_keyboardLayer.updateActiveNotes(activeMidiNotes);

  // Update the layers
  m_backgroundLayer.update(dt);
  m_keyboardLayer.update(dt);
}
//--------------------------------------------------------------
/* Draw the window content (returns true if the window content was drawn, false otherwise) */
bool MainWindow::Draw()
{
  const auto renderer = GetRenderer();     // Get the renderer instance

  // Clear the window with a black background
  renderer->setDrawColor(Color::Black);
  renderer->clear();

  // Render the layers in the correct Z-order (from back to front)
  m_backgroundLayer.render();
  m_keyboardLayer.render();

  return true;
}
//--------------------------------------------------------------
/* Handle window resize event */
void MainWindow::onResize(const Size &newSize)
{
  // The window has been resized, it is necessary to update
  // the visual piano layout to fit the new window size. For
  // simplicity, we will just reinitialize the keys
  m_keyboardLayer.initKeys(newSize);
}
//--------------------------------------------------------------
/* Update the current music time based on playback state */
void MainWindow::updateMusicTime(const float dt)
{
  // dt is the delta time in seconds since the last update
  switch (m_playbackState)
  {
    case PlaybackState::Stopped:
      // Reset music time to zero
      m_musicTime = {};
      break;
    case PlaybackState::Playing:
      // Update music time based on delta time
      m_musicTime += std::chrono::milliseconds(static_cast<int>((dt * 5) * 1000.0f));
      break;
    case PlaybackState::Paused:
      // Do not update music time when paused
      break;
  }
}
//--------------------------------------------------------------
