//----------------------------------------------------------------------------
//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
//
//	This library is free software; you can redistribute it and/or
//	modify it under the terms of the GNU Lesser General Public
//	License as published by the Free Software Foundation; either
//	version 2.1 of the License, or (at your option) any later version.
//
//	This library is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//	Lesser General Public License for more details.
//
//	You should have received a copy of the GNU Lesser General Public
//	License along with this library; if not, write to the Free Software
//	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//----------------------------------------------------------------------------

/**
 * @file DistContext.h
 * @date Feb 22, 2009
 * @author Ronald Kluth
 * @brief Declaration of odemx::random::DistContext
 */

#ifndef ODEMX_RANDOM_DISTCONTEXT_INCLUDED
#define ODEMX_RANDOM_DISTCONTEXT_INCLUDED

namespace odemx {
namespace random {

// forward declaration
class Dist;

extern const unsigned long zyqmodulo;

/** \class DistContext

	\ingroup random

	\author Ralf Gerstenberger

	\brief %DistContext stores global data for Dist.

	The random number generator (RNG) Dist does need some 'global'
	data for generating independent random numbers. These data are stored
	in %DistContext.

	\warning The RNG's in the same DistContext are independent
	from one another (within the limits of the RNG in Dist). Those RNG's
	in different DistContexts are NOT independent. Without changing the
	seed manually one will get the same sequence of random numbers in
	every DistContext!

	\since 1.0
*/
class DistContext
{
public:
	/**
		\brief Construction
	*/
	DistContext ();
	/// Destruction
	virtual ~DistContext();

	/**
		\brief Set start seed for new RNG's
		\param n
			new seed

		The new seed will be used for the initialization
		of new RNG's in this context. Choosing a good seed
		is not trivial. The one used as default is known
		to be sufficient for simulations.

		\warning
			The quality of the random numbers
			depends on the selected seed!
	*/
	void setSeed( int n = 0 );

protected:
	friend class Dist;

	/**
		\brief Get current start seed

		This function returns the current seed without
		generating a new seed value. The returned value
		was used for the last created RNG in this context.

		\sa getNextSeed()
	*/
	unsigned long getSeed();

	/**
		\brief Get start seed for a new RNG

		This function returns a new seed. The
		seed is generated by a random number generator
		different from the one used for ordinary random
		numbers. That is why the created random number
		generators in one %DistContext are independent from
		one another.
	*/
	unsigned long getNextSeed();

private:
	unsigned long zyqSeed_;

	/**
		\brief generate next start seed
	*/
	void computeNextSeed();
};

} } // namespace odemx::random

#endif /* ODEMX_RANDOM_DISTCONTEXT_INCLUDED */
