#ifndef CGAL_RANDOM_H
#define CGAL_RANDOM_H
#include <cstdlib>

namespace util {

class Random {
  public:
    // creation
    Random( );
    Random( unsigned int  seed);
    
    // operations
    bool    get_bool  ( );
    int     get_int   ( int lower, int upper);
    double  get_double( double lower = 0.0, double upper = 1.0);

    // Computes a random int value smaller than 2^b.
    // It's supposed to be fast, useful for randomized algorithms.
    // The distribution is not perfectly flat, but this is a sacrifice against
    // efficiency.
    template <int b>
    int get_bits()
    {
	assert(0<b && b<16);
        if (val == 0) {
            random_value = (421U * random_value + 2073U) % 32749U;
            val = random_value;
        }
        int ret = val & ((1<<b)-1);
        val >>= 1; // Shifting by b would be slightly better, but is slower.
        return ret;
    }

    int     operator () ( int upper);
  private:
    // data members
    const double  rand_max_plus_1;
    unsigned int random_value; // Current 15 bits random value.
    unsigned int val; // random_value shifted by used bits.
};

// Global variables
// ================
extern  Random  default_random;

// operations
inline
bool
Random::
get_bool( )
{
    return( static_cast< bool>( rand() & 1));
}

inline
int
Random::
get_int( int lower, int upper)
{
    return( lower + static_cast< int>(
      ( static_cast< double>( upper) - lower) * 
      	rand() / rand_max_plus_1));
}

inline
double
Random::
get_double( double lower, double upper)
{
    return( lower + ( ( upper-lower) * 
		      rand() / rand_max_plus_1));
}

inline
int
Random::
operator () ( int upper)
{
    return( get_int( 0, upper));
}

}
#endif // CGAL_RANDOM_H

// ===== EOF ==================================================================