/**
  zufall...
  */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "zuf.h"

/* It is crucial that m == n-273 mod 607 at all times;
 * For speed of execution, however, this is never enforced.
 * Instead is is set in the initializer: note 607-273=334
 * Note also that the state.u[607] is not initialized
 */
typedef struct {
    int n;
    unsigned long u[607];
} gsl_ran_zuf_randomState;

static void
gsl_ran_zuf_printState_p(gsl_ran_zuf_randomState *s)
{
    int n;
    printf("%d, {\n",s->n);
    for (n=0; n<607; ++n) {
	printf("%ld,\n",s->u[n]);
    }
    printf("}\n");
}

/* The zufall package was implemented with float's, which is to say 24
 * bits of precision.  Since I'm using long's instead, my RANDMAX
 * reflects this.
 */

#define gsl_ran_zuf_RANDMAX 16777216 /* 2^24 */

inline unsigned long gsl_ran_zuf_random_wstate(void *vState)
{
    int m;
    unsigned long t;
    gsl_ran_zuf_randomState *theState;
    theState = (gsl_ran_zuf_randomState *)vState;

    m = (theState->n - 273 + 607) % 607;
    t = theState->u[theState->n] + theState->u[m];
    while( t>gsl_ran_zuf_RANDMAX) t -= gsl_ran_zuf_RANDMAX;
    theState->u[theState->n] = t;
    if (++theState->n >= 607) theState->n=0;
    
    return t;
}    


void gsl_ran_zuf_seed_wstate(void *vState, int seed)
{
    /* A very elaborate seeding procedure is provided with the
     * zufall package; this is virtually a copy of that procedure */
    
    /* Initialized data */

    int kl = 9373;
    int ij = 1802;

    /* Local variables */
    int i, j, k, l, m;
    double s, t;
    int ii, jj;

    gsl_ran_zuf_randomState *theState;
    theState = (gsl_ran_zuf_randomState *)vState;

    theState->n=0;
    
/*  generates initial seed buffer by linear congruential */
/*  method. Taken from Marsaglia, FSU report FSU-SCRI-87-50 */
/*  variable seed should be 0 < seed <31328 */


    if (seed != 0) {
	ij = seed;
    }

    i = ij / 177 % 177 + 2;
    j = ij % 177 + 2;
    k = kl / 169 % 178 + 1;
    l = kl % 169;
    for (ii = 0; ii < 607; ++ii) {
	s = 0.;
	t = .5;
	/* 24 bits?? */
	for (jj = 1; jj <= 24; ++jj) {
	    m = i * j % 179 * k % 179;
	    i = j;
	    j = k;
	    k = m;
	    l = (l * 53 + 1) % 169;
	    if (l * m % 64 >= 32) {
		s += t;
	    }
	    t *= 0.5;
	}
	theState->u[ii] = s*gsl_ran_zuf_RANDMAX;
    }
} 

static gsl_ran_zuf_randomState state = {
    0, {
        13889833,
        11668030,
        6740098,
        6378503,
        4501108,
        6341980,
        11660504,
        7571991,
        8813239,
        14150200,
        13995880,
        3542668,
        2310894,
        6932668,
        7496842,
        16346723,
        15931154,
        3336484,
        985193,
        1060801,
        3768586,
        5918752,
        11254173,
        10387972,
        4159825,
        3870018,
        8592722,
        4870474,
        9811225,
        7184301,
        8939921,
        1514680,
        12096456,
        8867713,
        1236635,
        6902640,
        15617905,
        16637417,
        14766592,
        6180213,
        6232774,
        15402100,
        9063994,
        1943519,
        14563797,
        7750704,
        681114,
        10969270,
        13698006,
        8351138,
        636402,
        12257392,
        5127399,
        2312334,
        9181324,
        4931202,
        15284210,
        11139115,
        16380880,
        574870,
        5372009,
        2814447,
        4834944,
        15285672,
        10409974,
        11722852,
        16592524,
        8696567,
        12427967,
        5804539,
        12543146,
        10873518,
        7068981,
        297931,
        6332026,
        16240967,
        13197252,
        3930299,
        6624438,
        998388,
        538177,
        14259459,
        9553034,
        16093501,
        15609919,
        10390474,
        3998420,
        9071227,
        3239702,
        13831133,
        10122045,
        13924684,
        16261687,
        11748710,
        14723001,
        12481412,
        14727361,
        16486019,
        4812690,
        4850648,
        2546510,
        9883489,
        11146449,
        13870034,
        10229361,
        1598959,
        8181110,
        16343447,
        12110347,
        3315098,
        2165856,
        15908429,
        490835,
        671103,
        1000859,
        11016720,
        8701552,
        4697138,
        14907911,
        2363461,
        576563,
        9924935,
        1058075,
        3934688,
        15624378,
        16058783,
        3736215,
        1106258,
        10450153,
        8479918,
        8463361,
        4320403,
        4291057,
        2179395,
        2700769,
        808628,
        8465131,
        3699042,
        3180166,
        9696585,
        15493636,
        6383773,
        1540867,
        12099222,
        5849321,
        9574170,
        1592006,
        5268908,
        12228165,
        13532083,
        8211411,
        11313273,
        7082511,
        1326128,
        11531372,
        3902445,
        1197832,
        12755044,
        10419802,
        5661023,
        15835041,
        8774555,
        1121083,
        2530795,
        10101079,
        3835424,
        12821072,
        3693275,
        10122508,
        6511934,
        13695410,
        9562324,
        8882757,
        11119332,
        5850384,
        11158624,
        7599251,
        9481018,
        15552190,
        405824,
        5438657,
        482539,
        15936714,
        15460496,
        13368593,
        12456219,
        16756455,
        11537610,
        1125717,
        1211592,
        1512949,
        1260951,
        589751,
        7364443,
        14027804,
        10738530,
        4671850,
        1266740,
        1004400,
        9777238,
        1901992,
        2006521,
        5112254,
        5392187,
        7969854,
        12490931,
        10666671,
        16244986,
        93852,
        10219978,
        5014950,
        5690608,
        1334550,
        14812850,
        11395161,
        6608072,
        3663012,
        13851352,
        16067185,
        12401423,
        16609091,
        13602886,
        8854003,
        2486529,
        13233746,
        5794406,
        1204963,
        633104,
        13379985,
        411740,
        1884643,
        7317455,
        235113,
        9906386,
        8337844,
        3900567,
        4863503,
        6843846,
        11600469,
        4727417,
        9500567,
        11372557,
        2286490,
        15151674,
        14750517,
        14032113,
        9474754,
        15824396,
        12494757,
        1524887,
        15820419,
        5722769,
        8331836,
        15025760,
        7725931,
        9671595,
        14665328,
        2629704,
        13423129,
        11809066,
        13007577,
        7139131,
        13763726,
        10675040,
        5410534,
        8100277,
        16357203,
        12938282,
        6576322,
        4874906,
        4390370,
        2299392,
        7788919,
        10953581,
        16531972,
        527652,
        755947,
        634885,
        16391793,
        8500697,
        8602932,
        12133803,
        8216640,
        16052869,
        2165003,
        13077009,
        1392473,
        9863799,
        6486196,
        4478025,
        14523119,
        16272661,
        10096154,
        8120216,
        5793592,
        6272927,
        2227365,
        13978360,
        9571004,
        14280057,
        7695088,
        4303425,
        16147077,
        9934658,
        13722190,
        10881661,
        11817461,
        11293696,
        13245963,
        15529348,
        9943692,
        14717187,
        6210721,
        12306622,
        14469892,
        11400416,
        13605600,
        6175502,
        10638591,
        2215253,
        4215321,
        15728623,
        4552581,
        3317221,
        15798369,
        10840832,
        9451513,
        10136618,
        16100505,
        11388631,
        8518008,
        15942511,
        7010064,
        11512209,
        12149299,
        12178069,
        3647421,
        9146608,
        10455986,
        7779437,
        9867464,
        6357644,
        13459012,
        13929218,
        7426306,
        4656700,
        7558826,
        13062304,
        13346541,
        7079484,
        3274493,
        12593515,
        4354263,
        6705450,
        6307106,
        10174275,
        2365915,
        8325080,
        10151284,
        13555202,
        11726578,
        8241848,
        16691801,
        12856571,
        4973005,
        6217891,
        14744395,
        14163626,
        12432070,
        14926900,
        2818625,
        4220333,
        9623666,
        6360929,
        3323884,
        10691459,
        12209160,
        1458374,
        2341216,
        12298768,
        3061135,
        4194030,
        11752673,
        14873830,
        7443801,
        4690825,
        7897363,
        10094201,
        1854854,
        11898360,
        8411263,
        3932579,
        10511909,
        15567781,
        5332967,
        6339715,
        8559476,
        10294070,
        4785313,
        2929850,
        40238,
        6842787,
        10462580,
        3400074,
        15517365,
        6698221,
        4919823,
        4108475,
        7310661,
        1430964,
        671778,
        1860549,
        8824164,
        10269682,
        15918094,
        7680750,
        13045829,
        6429570,
        10551252,
        13862551,
        5240087,
        1967304,
        4134453,
        5946313,
        8477248,
        6061055,
        11828620,
        16273996,
        12164343,
        3294618,
        16639922,
        16540228,
        25933,
        12731948,
        7253676,
        14096351,
        1592440,
        7281330,
        7323796,
        6703670,
        6102784,
        10060071,
        3927275,
        11876883,
        202059,
        14153250,
        8609413,
        4821921,
        10954704,
        11375247,
        8937827,
        7071410,
        10092649,
        11067334,
        1184885,
        12558839,
        1948881,
        5666559,
        13766769,
        1883153,
        10769635,
        3591446,
        16772151,
        6166269,
        14971549,
        2364972,
        16379856,
        8804654,
        12314620,
        3567833,
        14149605,
        4908276,
        3881547,
        4226079,
        4662941,
        5908506,
        139986,
        7478280,
        5670415,
        4008627,
        14526094,
        2721984,
        10952917,
        13121669,
        7010898,
        13526908,
        971087,
        3691066,
        6704833,
        2093732,
        2724907,
        9666875,
        286332,
        7673633,
        10049641,
        14218484,
        6719845,
        8828269,
        12732233,
        2653007,
        10855961,
        14408071,
        14859103,
        11882430,
        11132483,
        5973241,
        13672323,
        6878969,
        2042553,
        6463944,
        7772308,
        9551819,
        14222673,
        7027944,
        1410395,
        13621343,
        106609,
        15395434,
        7340334,
        1934751,
        16261272,
        8717930,
        6014572,
        16295015,
        1427264,
        2311337,
        14553356,
        16331201,
        6200688,
        12002206,
        5729831,
        1257152,
        16649826,
        12810473,
        4067791,
        887966,
        11253814,
        10805006,
        10445736,
        16109802,
        16175439,
        6615605,
        7728134,
        5256550,
        12678984,
        2572784,
        5835104,
        8364232,
        4162203,
        7646638,
        7977295,
        10715920,
        9965021,
        6930705,
        12547057,
        7446566,
        1128570,
        2630705,
        13490433,
        14532920,
        3401919,
        15333462,
        12156704,
        3948268,
        8230474,
        14101645,
        15109278,
        1845384,
        13160060,
        5503421,
        4354802,
        1516080,
        386172,
        9083114,
        13005322,
        7473839,
        4400387,
        15552488,
        10196492,
        2879425,
        6423105,
        14715213,
        6913638,
        15849374,
        13868025,
        14991243,
        1391594,
        858219,
        783627,
        2919213,
        16056679,
        8353977,
        15599115,
        633956,
        5407041,
        9035527,
        8604374,
        10142532,
        9340282,
        8479625,
        14227100,
        7131356,
        3337768,
        9163990,
        5891027,
        9636919,
        7534875
    }
};

#include "zuf-state.c"

/* thats all... */
