#include	<stdlib.h>

#include	"tb.h"
#include	"tb_rand.h"

POINTRNDTBL	PointRnd = { 0, NULL };
COLORRNDTBL	ColorRnd = { 0, NULL };

int		tb_init_pointRndTbl(void)
{
	unsigned int		n;

	if ( PointRnd.tbl != NULL )
		return (0);

	PointRnd.n = 1<<16;	/* 256K バイト */
	if ( (PointRnd.tbl = MALLOC(sizeof(POINT) * PointRnd.n)) == NULL )
		return (-1);	/* error */

	tb_srand(0);
	for ( n = 0; n < PointRnd.n; ++n )
	{
		PointRnd.tbl[n].x = TBcfg.frTest.x1 + (tb_rand() % (TBcfg.frTest.x2 - TBcfg.frTest.x1 + 1));
		PointRnd.tbl[n].y = TBcfg.frTest.y1 + (tb_rand() % (TBcfg.frTest.y2 - TBcfg.frTest.y1 + 1));
	}
	return (0);
}

void	tb_term_pointRndTbl(void)
{
	if ( PointRnd.tbl != NULL )
	{
		FREE(PointRnd.tbl);
		PointRnd.tbl = NULL;
	}
}

int		tb_init_colorRndTbl(void)
{
	unsigned int		n;

	if ( ColorRnd.tbl != NULL )
		return (0);

	ColorRnd.n = 1<<14;	/* 64Kバイト */
	if ( (ColorRnd.tbl  = MALLOC(sizeof(unsigned int) * ColorRnd.n)) == NULL )
		return (-1);	/* error */

	tb_srand(13);
	for ( n = 0; n < ColorRnd.n; ++n )
		ColorRnd.tbl[n] = tb_rand();
	return (0);
}

void	tb_term_colorRndTbl(void)
{
	if ( ColorRnd.tbl != NULL )
	{
		FREE(ColorRnd.tbl);
		ColorRnd.tbl = NULL;
	}
}


static int			jrand;
static unsigned int	ia[56];  /* ia[1..55] */

static void		irn55(void)
{
	int				i;
	unsigned int	j;

	for ( i = 1; i <= 24; i++)
	{
		j = ia[i] - ia[i + 31];
		ia[i] = j;
	}
	for ( i = 25; i <= 55; i++)
	{
		j = ia[i] - ia[i - 24];
		ia[i] = j;
	}
}

void	tb_srand( unsigned int seed )
{
	int				i, ii;
	unsigned int	k;

	ia[55] = seed;
	k = 1;
	for ( i = 1; i <= 54; ++i)
	{
		ii = (21 * i) % 55;
		ia[ii] = k;
		k = seed - k;
		seed = ia[ii];
	}
	irn55();  irn55();  irn55();  /* warm up */
	jrand = 55;
}

unsigned int	tb_rand(void)
{
	if ( ++jrand > 55 )
	{
		irn55();
		jrand = 1;
	}
	return ia[jrand];
}
