// Copyright 2000
// College of Computer Science
// Northeastern University Boston MA 02115

// This software may be used for educational purposes as long as this copyright
// notice is retained at the top of all files

// Should this software be modified, the words "Modified from Original" must be
// included as a comment below this notice

// All publication rights are retained.  This software or its documentation may
// not be published in any media either in whole or in part.

///////////////////////////////////////////////////////////////////////////////

// Random .h

// Random number generator based explicitly on long data type
// Avoids issues in C library of whether int is short or long
// Builds random-number-in-specified-range calls

// See CACM, Vol. 31, Num. 10, 1192-1201.

///////////////////////////////////////////////////////////////////////////////

#ifndef RANDOM_H_
#define RANDOM_H_

#include "MathUtil.h"
#include <time.h>


// Maximum random number returned by NextRandom
const long MaxRandom = maximum_long - 1;
	
// Minimum random number returned by NextRandom
const long MinRandom = 1;


// SetRandomSeed sets the seed for random number generation
// if (MinRandom <= seed && seed <= MaxRandom) then seed is used
// otherwise the seed is chosen based on an internal clock value

EXPORT void SetRandomSeed(long seed = 0);		// Default to set seed with clock value


// NextRandom updates the random seed and returns its value
// Value will fall in range MinRandom .. MaxRandom

EXPORT long NextRandom();


// RandomDouble returns a random double in the range a .. b

EXPORT double RandomDouble(double a, double b);


// RandomLong returns a random long in the range a .. b
//
// Implementation note:
// If b - a is larger than MaxRandom then values will fill range
// a .. a + MaxRandom rather than the full range a .. b

EXPORT long RandomLong(long a, long b);


// RandomNumber class permits each object to maintain its own random seed
// The member functions exactly mimic the global functions above


// The default initialization uses the C function  clock()  which returns
// the processor time since program startup (with possible wraparound).
// 
// If several RandomNumber objects are initialized in quick succession it
// can happen that all are initialized with the same seed since  clock()
// will not have changed!
//
// At the moment, this problem must be handled by the user since we have
// not decided on an alternate initialization strategy that would avoid
// this dilemma.  The user should choose explicit and distinct seeds to
// ensure that all RandomNumber objects start differently.
//
// We expect to deal with this in a future release.


class EXPORT RandomNumber {
	long TheRandomSeed;			// seed
	
public:
	// constructor
	
	RandomNumber(long seed = 0) { SetRandomSeed(seed); };
	
	// member functions
	
	void SetRandomSeed(long seed = 0);
	
	long NextRandom();
	
	double RandomDouble(double a, double b);
	
	long RandomLong(long a, long b);
};

#endif  // RANDOM_H_
