///
/// HybridPlaybackEngineSpec.hpp
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
/// https://github.com/mrousavy/nitro
/// Copyright © Marc Rousavy @ Margelo
///

#pragma once

#if __has_include(<NitroModules/HybridObject.hpp>)
#include <NitroModules/HybridObject.hpp>
#else
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
#endif

// Forward declaration of `PlaybackState` to properly resolve imports.
namespace margelo::nitro::aviation { enum class PlaybackState; }
// Forward declaration of `MediaPosition` to properly resolve imports.
namespace margelo::nitro::aviation { struct MediaPosition; }
// Forward declaration of `HybridMediaItemSpec` to properly resolve imports.
namespace margelo::nitro::aviation { class HybridMediaItemSpec; }
// Forward declaration of `ItemSource` to properly resolve imports.
namespace margelo::nitro::aviation { enum class ItemSource; }
// Forward declaration of `SubtitleTrack` to properly resolve imports.
namespace margelo::nitro::aviation { struct SubtitleTrack; }
// Forward declaration of `AudioTrack` to properly resolve imports.
namespace margelo::nitro::aviation { struct AudioTrack; }
// Forward declaration of `RepeatMode` to properly resolve imports.
namespace margelo::nitro::aviation { enum class RepeatMode; }
// Forward declaration of `RemoteCommand` to properly resolve imports.
namespace margelo::nitro::aviation { enum class RemoteCommand; }
// Forward declaration of `NowPlayingInfo` to properly resolve imports.
namespace margelo::nitro::aviation { struct NowPlayingInfo; }
// Forward declaration of `HybridAudioSessionSpec` to properly resolve imports.
namespace margelo::nitro::aviation { class HybridAudioSessionSpec; }
// Forward declaration of `RemoteCommandEvent` to properly resolve imports.
namespace margelo::nitro::aviation { struct RemoteCommandEvent; }
// Forward declaration of `PlaybackMetricEvent` to properly resolve imports.
namespace margelo::nitro::aviation { struct PlaybackMetricEvent; }
// Forward declaration of `AvailableTracks` to properly resolve imports.
namespace margelo::nitro::aviation { struct AvailableTracks; }
// Forward declaration of `DomainEvent` to properly resolve imports.
namespace margelo::nitro::aviation { struct DomainEvent; }
// Forward declaration of `AviationInterruptionMode` to properly resolve imports.
namespace margelo::nitro::aviation { enum class AviationInterruptionMode; }
// Forward declaration of `BecomingNoisyBehavior` to properly resolve imports.
namespace margelo::nitro::aviation { enum class BecomingNoisyBehavior; }
// Forward declaration of `VideoTrackSelection` to properly resolve imports.
namespace margelo::nitro::aviation { struct VideoTrackSelection; }
// Forward declaration of `SubtitleTrackSelection` to properly resolve imports.
namespace margelo::nitro::aviation { struct SubtitleTrackSelection; }
// Forward declaration of `AudioTrackSelection` to properly resolve imports.
namespace margelo::nitro::aviation { struct AudioTrackSelection; }
// Forward declaration of `PreloadConfig` to properly resolve imports.
namespace margelo::nitro::aviation { struct PreloadConfig; }
// Forward declaration of `BufferConfig` to properly resolve imports.
namespace margelo::nitro::aviation { struct BufferConfig; }

#include <string>
#include "PlaybackState.hpp"
#include "MediaPosition.hpp"
#include <memory>
#include "HybridMediaItemSpec.hpp"
#include <optional>
#include "ItemSource.hpp"
#include "SubtitleTrack.hpp"
#include <vector>
#include "AudioTrack.hpp"
#include "RepeatMode.hpp"
#include <NitroModules/Promise.hpp>
#include "RemoteCommand.hpp"
#include "NowPlayingInfo.hpp"
#include "HybridAudioSessionSpec.hpp"
#include <functional>
#include "RemoteCommandEvent.hpp"
#include "PlaybackMetricEvent.hpp"
#include "AvailableTracks.hpp"
#include "DomainEvent.hpp"
#include "AviationInterruptionMode.hpp"
#include "BecomingNoisyBehavior.hpp"
#include "VideoTrackSelection.hpp"
#include "SubtitleTrackSelection.hpp"
#include "AudioTrackSelection.hpp"
#include "PreloadConfig.hpp"
#include "BufferConfig.hpp"

namespace margelo::nitro::aviation {

  using namespace margelo::nitro;

  /**
   * An abstract base class for `PlaybackEngine`
   * Inherit this class to create instances of `HybridPlaybackEngineSpec` in C++.
   * You must explicitly call `HybridObject`'s constructor yourself, because it is virtual.
   * @example
   * ```cpp
   * class HybridPlaybackEngine: public HybridPlaybackEngineSpec {
   * public:
   *   HybridPlaybackEngine(...): HybridObject(TAG) { ... }
   *   // ...
   * };
   * ```
   */
  class HybridPlaybackEngineSpec: public virtual HybridObject {
    public:
      // Constructor
      explicit HybridPlaybackEngineSpec(): HybridObject(TAG) { }

      // Destructor
      ~HybridPlaybackEngineSpec() override = default;

    public:
      // Properties
      virtual std::string getEngineId() = 0;
      virtual PlaybackState getState() = 0;
      virtual MediaPosition getMediaPosition() = 0;
      virtual std::optional<std::shared_ptr<HybridMediaItemSpec>> getCurrentItem() = 0;
      virtual ItemSource getCurrentItemSource() = 0;
      virtual bool getIsLive() = 0;
      virtual bool getIsPlaying() = 0;
      virtual bool getIsPaused() = 0;
      virtual bool getIsLoaded() = 0;
      virtual std::vector<SubtitleTrack> getAvailableSubtitleTracks() = 0;
      virtual std::vector<AudioTrack> getAvailableAudioTracks() = 0;
      virtual double getVolume() = 0;
      virtual void setVolume(double volume) = 0;
      virtual double getRate() = 0;
      virtual void setRate(double rate) = 0;
      virtual bool getMuted() = 0;
      virtual void setMuted(bool muted) = 0;
      virtual bool getLoop() = 0;
      virtual void setLoop(bool loop) = 0;
      virtual std::vector<std::shared_ptr<HybridMediaItemSpec>> getQueueItems() = 0;
      virtual double getQueueIndex() = 0;
      virtual double getQueueCount() = 0;
      virtual RepeatMode getRepeatMode() = 0;
      virtual void setRepeatMode(RepeatMode repeatMode) = 0;
      virtual bool getShuffleEnabled() = 0;
      virtual void setShuffleEnabled(bool shuffleEnabled) = 0;

    public:
      // Methods
      virtual std::shared_ptr<Promise<void>> load(const std::shared_ptr<HybridMediaItemSpec>& item) = 0;
      virtual std::shared_ptr<Promise<void>> loadAndPlay(const std::shared_ptr<HybridMediaItemSpec>& item) = 0;
      virtual std::shared_ptr<Promise<void>> play() = 0;
      virtual std::shared_ptr<Promise<void>> pause() = 0;
      virtual std::shared_ptr<Promise<void>> stop() = 0;
      virtual std::shared_ptr<Promise<void>> seekTo(double positionMs) = 0;
      virtual void release() = 0;
      virtual void activateDefaultDecoder() = 0;
      virtual void setQueue(const std::vector<std::shared_ptr<HybridMediaItemSpec>>& items) = 0;
      virtual void addToQueue(const std::shared_ptr<HybridMediaItemSpec>& item) = 0;
      virtual void insertInQueue(const std::shared_ptr<HybridMediaItemSpec>& item, double afterIndex) = 0;
      virtual void removeFromQueue(double index) = 0;
      virtual void moveInQueue(double fromIndex, double toIndex) = 0;
      virtual void clearQueue() = 0;
      virtual std::shared_ptr<Promise<void>> skipToNext() = 0;
      virtual std::shared_ptr<Promise<void>> skipToPrevious() = 0;
      virtual std::shared_ptr<Promise<void>> skipToIndex(double index, bool autoPlay) = 0;
      virtual void setEnabledCommands(const std::vector<RemoteCommand>& commands) = 0;
      virtual void setCompactCommands(const std::vector<RemoteCommand>& commands) = 0;
      virtual void setSkipIntervalMs(double intervalMs) = 0;
      virtual void updateNowPlaying(const NowPlayingInfo& info) = 0;
      virtual void overrideRemoteCommand(RemoteCommand command) = 0;
      virtual void clearRemoteCommandOverride(RemoteCommand command) = 0;
      virtual void setAudioSession(const std::shared_ptr<HybridAudioSessionSpec>& session) = 0;
      virtual void clearCallbacks() = 0;
      virtual void onStateChange(const std::function<void(PlaybackState /* state */)>& callback) = 0;
      virtual void onMediaPositionChange(const std::function<void(const MediaPosition& /* position */)>& callback) = 0;
      virtual void onCurrentItemChange(const std::function<void(const std::optional<std::shared_ptr<HybridMediaItemSpec>>& /* item */, ItemSource /* source */)>& callback) = 0;
      virtual void onRemoteCommand(const std::function<void(const RemoteCommandEvent& /* event */)>& callback) = 0;
      virtual void onError(const std::function<void(const std::string& /* message */, const std::string& /* code */)>& callback) = 0;
      virtual void onPlaybackEnded(const std::function<void()>& callback) = 0;
      virtual void onQueueEnd(const std::function<void()>& callback) = 0;
      virtual void onQueueChange(const std::function<void()>& callback) = 0;
      virtual void onPlaybackMetric(const std::function<void(const PlaybackMetricEvent& /* event */)>& callback) = 0;
      virtual void onTracksAvailable(const std::function<void(const AvailableTracks& /* tracks */)>& callback) = 0;
      virtual void onDomainEvent(const std::function<void(const DomainEvent& /* event */)>& callback) = 0;
      virtual void setInterruptionMode(AviationInterruptionMode mode) = 0;
      virtual void setBecomingNoisyBehavior(BecomingNoisyBehavior behavior) = 0;
      virtual void selectVideoTrack(const VideoTrackSelection& selection) = 0;
      virtual void selectSubtitleTrack(const SubtitleTrackSelection& selection) = 0;
      virtual void selectAudioTrack(const AudioTrackSelection& selection) = 0;
      virtual std::shared_ptr<Promise<void>> clearCache() = 0;
      virtual double getCacheSize() = 0;
      virtual bool isCached(const std::string& uri) = 0;
      virtual void setCacheEnabled(bool enabled) = 0;
      virtual void preload(const std::vector<std::shared_ptr<HybridMediaItemSpec>>& items) = 0;
      virtual void setPreloadConfig(const PreloadConfig& config) = 0;
      virtual void setBufferConfig(const BufferConfig& config) = 0;
      virtual void setCacheMaxSize(double sizeBytes) = 0;
      virtual void setPreloadEnabled(bool enabled) = 0;

    protected:
      // Hybrid Setup
      void loadHybridMethods() override;

    protected:
      // Tag for logging
      static constexpr auto TAG = "PlaybackEngine";
  };

} // namespace margelo::nitro::aviation
