/*            
  SFBRandom.cpp - Arduino API compatibility shims around random.c
  Copyright (C) 2009 The Regents of the University of New Mexico.  All rights reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library 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
  Lesser General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
  USA
*/

#include "SFBTypes.h"
#include "SFBMacros.h"          /* For IN_BODYRAM */ 
#include "SFBRandom.h"

static u32 randomBitBuffer IN_BODYRAM_BSS;     
static u32 randomBitsAvailable IN_BODYRAM_BSS; 

u32 randomBits(u32 n) {
  u32 mask;

  if (n < 32) mask = (1<<n)-1;  // Avoid non-portable 32 bit shift..
  else {
    n = 32;                     // And max out what they can ask for
    mask = -1;
  } 

  if (randomBitsAvailable < n) {
    randomBitBuffer = randomImpl();
    randomBitsAvailable = 32;
  }
  randomBitsAvailable -= n;
  u32 ret = randomBitBuffer&mask;
  randomBitBuffer >>= n;
  return ret;
}


void randomSeed(u32 seed) {
  srandomImpl(seed);
}

long random(u32 max) {
  if (max==0) return 0;  /* bogons.. */
  return randomImpl()%max;
}

long random(int min, int max) {
  if (min > max) return random(max,min);
  return random((u32) (max-min))+min;
}
