//
// PerlinNoise
// -----------
//
// Based on:
// * Siggraph '85 pp 287-296, Ken Perlin: "An Image Sythesizer" 
// * Graphic Gems II pp 397-401, Greg Ward : "A recursive implementation of the Perlin Noise function"
// * http://mrl.nyu.edu/~perlin/doc/oscar.html
//
// 27/11/00 Pieter.Peers@cs.kuleuven.ac.be
//

#ifndef _PerlinNoise_H_
#define _PerlinNoise_H_

namespace xrml {

#define MaxDim (int)sizeof(int)       // number of dimensions is limited by size of integer

class PerlinNoise {

public:
  PerlinNoise(int dim = 1, int cPoints = 256);
  PerlinNoise(const PerlinNoise& src);
  PerlinNoise& operator=(const PerlinNoise& src);
  ~PerlinNoise();

  // state values
  int *Perm;                       // hashtable of indexes
  double *G;                       // random value hashtable

  // 
  int getDimension(void) { return dimension; }
  int getCtrlPoints(void) { return ctrlPoints; }

  // coord must be in [0. 1[ interval!!
  float noise(float *coord);
  float turbulence(float *coord, float octaves = 10, float persistence = .70710678);
  void Dnoise(float *coord, float *norm, float pixelsize);

private:
  int dimension, ctrlPoints;       // # of dimensions, # of control points in hastable

  // tables used for evaluation
  float  *r;                      // positions on hypercube around element
  float  *s;                      // splines on hypercube edges
  int    *b;                      // hypercube(element) indeces
  int    *index;                  // hash table
  double *interp;                 // interpolation table
};

}  // namespace xrml

#endif /* _PerlinNoise_H_ */
