//
// prng.cxx
// 
// an abstract base class for pseudo-random number generators
//
// Copyright (C) 1996-7 by Leonard Janke (janke@unixg.ubc.ca)

#include <lmisc/lmisc.hxx>
#include <prng/prng.hxx>
#include <iostream.h>
#include <iomanip.h>

PRNG::PRNG(const int bufferSize) : _bufferSize(bufferSize), _withdrawlPos(0)
{
  _buffer=new u8[bufferSize];
}

PRNG::~PRNG()
{
  delete[] _buffer;
}

u8 PRNG::NextByte()
{
  u8 rv=_buffer[_withdrawlPos++];
  if ( _withdrawlPos==_bufferSize )
    {
      RefillBuffer();
      _withdrawlPos=0;
    }
  return rv;
}

u16 PRNG::NextWord()
{
  u16 rv=NextByte()<<8;
  rv|=NextByte();
  
  return  rv;
}

u32 PRNG::NextDWord()
{
  u32 rv=NextByte()<<24;
  rv|=NextByte()<<16;
  rv|=NextByte()<<8;
  rv|=NextByte();
  
  return  rv;
}

void PRNG::NextQuantum(void* quant, const int quantumSize)
{
  u8* quantum=(u8*) quant;
  int fill=quantumSize;
  int insertPos=0;

  int leftOver=_bufferSize-_withdrawlPos;
  leftOver=LC_Min(leftOver,fill);

  memcpy(quantum+insertPos,_buffer+_withdrawlPos,leftOver);
  insertPos+=leftOver;
  fill-=leftOver;
  _withdrawlPos+=leftOver;

  if ( _withdrawlPos==_bufferSize )
    {
      RefillBuffer();
      _withdrawlPos=0;
    }

  if ( fill==0 )
    return;

  for (int i=0; i<(fill/_bufferSize); i++)
    {
      memcpy(quantum+insertPos,_buffer,_bufferSize);
      insertPos+=_bufferSize;
      RefillBuffer();
    }
  fill%=_bufferSize;

  memcpy(quantum+insertPos,_buffer,fill);
  _withdrawlPos=fill;
}
