#pragma once

#include "trackDefs.h"
#include "trackLockProxy.h"

#include <chrono>
#include <cstdint>
#include <filesystem>
#include <mutex>
#include <span>
#include <string>
#include <vector>

namespace track
{
//--------------------------------------------------------------
class Track
{
  public:
  Track()                                = default;     // Default constructor
  virtual ~Track()                       = default;     // Default destructor
  Track(const Track &obj)                = delete;      // Copy constructor
  Track(Track &&obj) noexcept            = delete;      // Move constructor
  Track &operator=(const Track &obj)     = delete;      // Copy assignment operator
  Track &operator=(Track &&obj) noexcept = delete;      // Move assignment operator

  void logInfo(const std::string &message) const;      // Log an informational message
  void logError(const std::string &message) const;     // Log an error message

  // --- File management ---
  void                  loadFromFile(const std::filesystem::path &filePath);     // Load a MIDI file from disk
  void                  loadFromMemory(std::span<uint8_t> midiBytes);            // Load a MIDI file from memory
  void                  clear();                                                 // Clear the track data
  [[nodiscard]] bool    isLoaded() const;                                        // Check if a MIDI file is loaded
  [[nodiscard]] Seconds getDuration() const;                                     // Get the duration of the track

  void debug() const;     // Debug function to print the track data

  // --- Notes access ---
  TrackLockProxy getNotes() const;     // Get a lock proxy to access the notes safely without copying the data

  protected:
  struct
  {
    mutable std::mutex mtx;      // Protects access to the notes vector
    NotesBuffer        list;     // Vector to store notes
  } m_notes;
};
//--------------------------------------------------------------
}     // namespace track
