// Random Number Generator
//
// For ECS 110 - UC Davis - Coverted to C++ by Ted Krovetz
//
// Implementation based on block cipher RC5 which is copywritten.
// RC5REF.C -- Reference implementation of RC5-32/12/16 in C.
// Copyright (C) 1995 RSA Data Security, Inc. Patent Pending.

#ifndef RANDOM_H
#define RANDOM_H

#include <limits.h>

#if UINT_MAX == 0xffffffffu
  typedef unsigned int WORD;    // Should be 32-bit = 4 bytes
#elif ULONG_MAX == 0xffffffffu
  typedef unsigned long WORD;   // Should be 32-bit = 4 bytes
#else
  !! Error -- This computer does not support 32-bit words
#endif


// ----------------------------------------------------------------------

class Random {
private:
  int one_is_saved;
  WORD saved;
  WORD counter[2];
  WORD *S;      // key table

  void aux_init(unsigned char K[]);
  WORD get_next_WORD(void);
  
public:
  Random(void);                    // Auto Weak Constructor
  Random(WORD seed);               // Weak Constructor, 4 bytes
  Random(unsigned char seed[]);    // Strong Constructor, 16 bytes 
  ~Random(void);                   // Destructor 
  WORD get_rand(WORD min_val, WORD max_val);
};

// ----------------------------------------------------------------------

// Random is a C++ class which produces pseudo random numbers. Seeding
// the generator is done automatically in the constructor. The type
// of the output is 'WORD' which is always 32-bits and unsigned. Standard
// C++ conversions will be applied if the output is assigned to a
// smaller or larger type.
//
// For debugging purposes, you may want to seed the generator
// with a known value. To do so, pass the constructor a value.
//
// get_rand(WORD min_val, WORD max_val) returns an integer at
// least min_val and at most max_val.
//
// EXAMPLE: Output 100 numbers from 1 to 10
//
// #include "Random.h"
//
// Random r;
//
// void main(void)
// {
//   for (int i = 0; i < 100; i++)
//     cout << r.get_rand(1,10) << endl;
// }

#endif