//
// $Id: SNRandom.m,v 1.3 1997/10/31 04:52:05 nygard Exp $
//

//
//  This file is a part of Empire, a game of exploration and conquest.
//  Copyright (C) 1996  Steve Nygard
//
//  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., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//  You may contact the author by:
//     e-mail:  nygard@telusplanet.net
//

#import "Empire.h"

RCSID ("$Id: SNRandom.m,v 1.3 1997/10/31 04:52:05 nygard Exp $");

#import "SNRandom.h"

#ifndef WIN32
#import <libc.h>
#define SRANDOM(x) srandom(x)
#define RANDOM() random()
#else
#define SRANDOM(x) srand(x)
#define RANDOM() rand()
#endif

static SNRandom *_instance = nil;

#define DK_SeedRandom @"SeedRandom"

//======================================================================
// Provide an interface to random number generation, since not all of
// the functions are portable across platforms.
//======================================================================


#define SNRandom_VERSION 1

@implementation SNRandom

//----------------------------------------------------------------------
// The class checks the defaults to see whether is should randomly
// seed the generator.  Not seeding is extremely useful when trying
// to debug stuff that uses this.
//----------------------------------------------------------------------

+ (void) initialize
{
    NSUserDefaults *defaults;
    NSMutableDictionary *riskDefaults;
    BOOL flag;

    if (self == [SNRandom class])
    {
        [self setVersion:SNRandom_VERSION];

        defaults = [NSUserDefaults standardUserDefaults];
        riskDefaults = [NSMutableDictionary dictionary];

        [riskDefaults setObject:@"YES" forKey:DK_SeedRandom];

        [defaults registerDefaults:riskDefaults];

        flag = [defaults boolForKey:DK_SeedRandom];
        if (flag == YES)
        {
            [SNRandom seedGenerator:time (NULL)];
        }
    }
}

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

+ instance
{
    if (_instance == nil)
    {
        _instance = [[SNRandom alloc] init];
    }

    return _instance;
}

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

+ (void) seedGenerator:(int)seed
{
    SRANDOM (seed);
}

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

- (void) seedGenerator:(int)seed
{
    SRANDOM (seed);
}

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

- (long) randomNumber
{
    return RANDOM ();
}

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

- (long) randomNumberModulo:(long)modulus
{
    NSAssert (modulus != 0, @"Modulus cannot be zero.");
    return [self randomNumber] % modulus;
}

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

- (long) randomNumberWithMaximum:(long)maximum
{
    return [self randomNumber] % (maximum + 1);
}

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

- (long) randomNumberBetween:(long)minimum:(long)maximum
{
    if (maximum <= minimum)
        return minimum;
    
    return minimum + [self randomNumberWithMaximum:maximum - minimum];
}

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

#define RANGE_FOR_PERCENT 1000000000

- (double) randomPercent
{
    return (double)[self randomNumberWithMaximum:RANGE_FOR_PERCENT] / RANGE_FOR_PERCENT * 100;
}

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

- (BOOL) randomBoolean
{
    return [self randomNumberWithMaximum:1] == 1;
}

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

- (long) rollDieWithSides:(int)sideCount
{
    return [self randomNumberBetween:1:sideCount];
}

@end
