/*
 * The UDS Collection
 * Copyright (C) 2000, 2001  Julian v. Bock
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *	(See file COPYING for more information)
 */

#ifndef _uds_random_hh
#define _uds_random_hh


namespace uds
{

/** simple random number generator.
	based on "Die C++ Programmiersprache" (The C++ Programming Language)
	third edition §22.7 */
class Random
{
public:
	/** \param s seed */
	Random( unsigned s = 0 );
	
	/** destructor */
	virtual
	~Random();
	
	/** sets the random seed
		\param s seed
		\param if set to true, the new seed is added to the old one */
	void
	Seed( unsigned s, bool add = false );
	
	/** generates a random number between 0 and 2^32
		\return random number */
	virtual unsigned
	Draw() { return draw(); }
	
	/** generates a random number between 0 and 1
		\return random number */
	virtual double
	FDraw() { return fdraw(); }
	
	/** generates a random number between 0 and 2^32
		\return random number */
	unsigned
	operator () () { return Draw(); }
	
protected:
	
	/** generates a random number between 0 and 2^32
		\return random number */
	unsigned
	draw();
	
	/** generates a random number between 0 and 1
		\return random number */
	double
	fdraw();
	
private:
	/// current random number
	unsigned randx;
};

/** creates a random seed based on the system time and the process ID
	\return random seed */
unsigned
TimeSeed();

/** gets a random seed from /dev/random
	\return random seed */
unsigned
RandomSeed();

/** gets a random seed from /dev/urandom
	\return random seed */
unsigned
URandomSeed();


/** simple random number generator. generates numbers between 0 and a
	specified maximum.
	based on "Die C++ Programmiersprache" (The C++ Programming Language)
	third edition §22.7 */
class URandom : public Random
{
public:
	/** \param m maximum
		\param s random seed */
	URandom( unsigned m, unsigned s = 0 );
	
	/** destructor */
	virtual
	~URandom();
	
	/** sets the maximum
		\param m maximum */
	void
	SetMax( unsigned m ) { max = m; }
	
	/** \return max. value */
	unsigned
	Max() const  { return max; }
	
	/** generates a random number between 0 and the maximum */
	virtual unsigned
	Draw();
	
private:
	/// maximum
	unsigned max;
};

}

#endif // _uds_random_hh
