#pragma once
#include "buffer.h"
#include "randomaccessaudioreadable.h"
#include "statefuldsp.h"

struct SpeexResamplerState_;
typedef struct SpeexResamplerState_ SpeexResamplerState;

class Resampler final : public RandomAccessAudioReadable, public StatefulDSP {
  enum class State { Reset, ContinuousPlayback };
  std::shared_ptr<RandomAccessAudioReadable> underlyingReadable;
  State state;
  int currentFrameOffset;
  int currentUnderlyingFrameOffset;
  BufferF32 underlyingChunk;
  BufferF32 excessOutput;
  int underlyingChunkOffset;
  int excessOutputOffset;
  int excessOutputLength;
  int numerator;
  int denominator;
  int outputRate;

  SpeexResamplerState *resamplerState;

  void finishInit(int underlyingChannelCount);
  void seekTo(int frameOffset);

public:
  Resampler(std::shared_ptr<RandomAccessAudioReadable> underlyingReadable,
            int numerator, int denominator);
  Resampler(int channelCount, int numerator, int denominator);
  ~Resampler();

  void
  setUnderlying(std::shared_ptr<RandomAccessAudioReadable> underlyingReadable,
                int numerator, int denominator);

  int getSampleRate() const override;
  int getChannelCount() const override;
  int getFrameCount() const override;
  void read(int frameOffset, BufferF32 output) override;
  void read(int frameOffset, std::shared_ptr<BufferF32> output) override;

  int getNumerator() const;
  int getDenominator() const;
  void setSampleRateRatio(int numerator, int denominator);
};