#pragma once

#include <psemek/audio/constants.hpp>

#include <cstdint>
#include <cmath>

namespace psemek::audio
{

	struct duration
	{
	private:
		struct samples_tag{};
		struct frames_tag{};

	public:

		duration()
			: frames_{0}
		{}

		static duration from_samples(std::int64_t samples)
		{
			return duration(samples_tag{}, samples);
		}

		static duration from_frames(std::int64_t samples)
		{
			return duration(frames_tag{}, samples);
		}

		duration(float seconds)
			: frames_{seconds_to_frames(seconds)}
		{}

		duration(duration const & other)
			: frames_{other.frames_}
		{}

		float seconds() const
		{
			return frames_to_seconds(frames_);
		}

		std::int64_t frames() const
		{
			return frames_;
		}

		std::int64_t samples() const
		{
			return frames_ * 2;
		}

		duration & operator = (duration const & other)
		{
			frames_ = other.frames_;
			return *this;
		}

		duration & operator += (duration const & other)
		{
			frames_ += other.frames_;
			return *this;
		}

		duration & operator -= (duration const & other)
		{
			frames_ -= other.frames_;
			return *this;
		}

		friend duration operator + (duration const & d1, duration const & d2)
		{
			return duration{d1.frames() + d2.frames()};
		}

		friend duration operator - (duration const & d1, duration const & d2)
		{
			return duration{d1.frames() - d2.frames()};
		}

	private:
		std::int64_t frames_;

		duration(samples_tag, std::int64_t samples)
			: frames_(samples / 2)
		{}

		duration(frames_tag, std::int64_t frames)
			: frames_(frames)
		{}
	};

}
