/* RandomInt.h declares RandomInt, pseudo-random integer class.
 *
 * Written by: Joel C. Adams, Spring, 1993, at Calvin College.
 * Written for: C++: An Introduction To Computing.
 * Revised: Spring 1997, for C++: An Introduction To Computing 2e.
 * Revised: Summer 2001, for C++: An Introduction To Computing 3e.
 *
 * See RandomInt.doc for class documentation,
 *     RandomInt.cpp for non-trivial operation definitions.
 ******************************************************************/
 
#ifndef RANDOMINT
#define RANDOMINT

#include <iostream>
#include <cstdlib>
#include <cassert>
#include <ctime>
using namespace std;

class RandomInt
{
 public:
  RandomInt();
  RandomInt(int low, int high);
  RandomInt(int seedValue);
  RandomInt(int seedValue, int low, int high);
  
  void print(ostream & out) const;
  RandomInt generate();
  RandomInt generate(int low, int high);
  operator int();

 private:
  void initialize(int low, int high);
  void seededInitialize(int seedValue, int low, int high);
  int nextRandomInt();

  int myLowerBound,
      myUpperBound,
      myRandomValue;

  static bool generatorInitialized;
};

inline RandomInt::RandomInt()
{
  initialize(0, RAND_MAX);
}

inline RandomInt::RandomInt(int low, int high)
{
  assert(0 <= low);
  assert(low < high);
  initialize(low, high);
}

inline RandomInt::RandomInt(int seedValue)
{
  assert(seedValue >= 0);
  seededInitialize(seedValue, 0, RAND_MAX);
}

inline RandomInt::RandomInt(int seedValue, int low, int high)
{
  assert(seedValue >= 0);
  assert(0 <= low);
  assert(low < high);
  seededInitialize(seedValue, low, high);
}

inline void RandomInt::print(ostream & out) const
{
  out << myRandomValue;
}

inline ostream & operator<< (ostream & out, const RandomInt & randInt)
{
  randInt.print(out);
  return out;
}

inline int RandomInt::nextRandomInt()
{
  return myLowerBound + rand() % (myUpperBound - myLowerBound + 1);
}

inline RandomInt RandomInt::generate()
{
  myRandomValue = nextRandomInt();
  return *this;
}

inline RandomInt::operator int() 
{
  return myRandomValue;
}

#endif


