#pragma once

#include <psemek/random/uniform.hpp>

#include <cmath>

namespace psemek::random
{

	template <typename T>
	struct poisson_distribution
	{
		poisson_distribution(T lambda)
			: exp_mlambda_(std::exp(-lambda))
		{}

		template <typename RNG>
		std::size_t operator()(RNG & rng)
		{
			// Knuth's method

			std::size_t result = 0;
			T product = T{1};

			do
			{
				++result;
				product *= uniform<T>(rng);
			}
			while (product > exp_mlambda_);

			return result - 1;
		}

	private:
		T exp_mlambda_;
	};

}
