#include <psemek/audio/effect/truncate.hpp>

#include <algorithm>

namespace psemek::audio
{

	namespace
	{

		struct truncate_impl
			: stream
		{
			truncate_impl(stream_ptr stream, duration length)
				: stream_(std::move(stream))
				, remaining_(length.samples())
				, total_length_(stream_->played() + remaining_)
			{}

			std::optional<std::size_t> length() const override
			{
				return total_length_;
			}

			std::size_t read(util::span<float> samples) override
			{
				auto const max_count = std::min<std::size_t>(remaining_, samples.size());
				auto const count = stream_->read(samples.prefix(max_count));
				remaining_ -= count;
				return count;
			}

			std::size_t played() const override
			{
				return stream_->played();
			}

		private:
			stream_ptr stream_;
			std::size_t remaining_;
			std::size_t total_length_;
		};

	}

	stream_ptr truncate(stream_ptr stream, duration length)
	{
		return std::make_shared<truncate_impl>(std::move(stream), length);
	}

}
