/*
 * PerlinNoise.hpp
 *
 *  Created on: Jul 11, 2008
 *      Author: pete
 */

#ifndef PERLINNOISE_HPP_
#define PERLINNOISE_HPP_

#include <math.h>

class PerlinNoise
{
public:

	float noise_lq[256][256];
	float noise_lq_lite[32][32];
	float noise_mq[256][256];
	float noise_hq[256][256];
	float noise_perlin[512][512];
	float noise_lq_vol[32][32][32];
	float noise_hq_vol[32][32][32];


	PerlinNoise();
	virtual ~PerlinNoise();

private:

	static inline float noise( int x)
	{
	    x = (x<<13)^x;
	    return (((x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 2147483648.0);
	   }

	static inline float noise(int x, int y)
	{
		 int n = x + y * 57;
		 return noise(n);
	}

	static inline float noise(int x, int y, int z)
	{
		 int n = x + y * 57 + z * 141;
		 return noise(n);
	}

	static inline float cos_interp(float a, float b, float x)
	{
		float ft = x * 3.1415927;
		float f = (1 - cos(ft)) * .5;

		return  a*(1-f) + b*f;
	}

	static inline float cubic_interp(float v0, float v1, float v2, float v3, float x)
	{
		float P = (v3 - v2) - (v0 - v1);
		float Q = (v0 - v1) - P;
		float R = v2 - v0;

		return P*pow(x,3) + Q * pow(x,2) + R*x + v1;
	}

	static inline float InterpolatedNoise(float x, float y)
	{
		int integer_X = int(x);
		float fractional_X = x - integer_X;

		int integer_Y = int(y);
		float fractional_Y = y - integer_Y;

		float a0 = noise(integer_X - 1,      integer_Y - 1);
		float a1 = noise(integer_X,          integer_Y - 1);
		float a2 = noise(integer_X + 1,      integer_Y - 1);
		float a3 = noise(integer_X + 2,      integer_Y - 1);

		float x0 = noise(integer_X - 1,      integer_Y);
		float x1 = noise(integer_X,          integer_Y);
		float x2 = noise(integer_X + 1,      integer_Y);
		float x3 = noise(integer_X + 2,      integer_Y);

		float y0 = noise(integer_X + 0,   	 integer_Y + 1);
		float y1 = noise(integer_X,     	 integer_Y + 1);
		float y2 = noise(integer_X + 1, 	 integer_Y + 1);
		float y3 = noise(integer_X + 2, 	 integer_Y + 1);

		float b0 = noise(integer_X - 1,      integer_Y + 2);
		float b1 = noise(integer_X,          integer_Y + 2);
		float b2 = noise(integer_X + 1,      integer_Y + 2);
		float b3 = noise(integer_X + 2,      integer_Y + 2);

		float i0 = cubic_interp(a0 , a1, a2, a3, fractional_X);
		float i1 = cubic_interp(x0 , x1, x2, x3, fractional_X);
		float i2 = cubic_interp(y0 , y1, y2, y3, fractional_X);
		float i3 = cubic_interp(b0 , b1, b2, b3, fractional_X);

		return cubic_interp(i0, i1 , i2 , i3, fractional_Y);

	}

	static inline float perlin_octave_2d(float x,float y, int width, int seed, float period)
	{

	           float freq=1/(float)(period);

	           int num=(int)(width*freq);
	           int step_x=(int)(x*freq);
	           int step_y=(int)(y*freq);
	           float zone_x=x*freq-step_x;
	           float zone_y=y*freq-step_y;
	           int box=step_x+step_y*num;
	           int noisedata=(box+seed);

	           float u=cubic_interp(noise(noisedata-num-1),noise(noisedata-num),noise(noisedata-num+1),noise(noisedata-num+2),zone_x);
	           float a=cubic_interp(noise(noisedata-1),noise(noisedata),noise(noisedata+1),noise(noisedata+2),zone_x);
	           float b=cubic_interp(noise(noisedata+num -1),noise(noisedata+num),noise(noisedata+1+num),noise(noisedata+2+num),zone_x);
	           float v=cubic_interp(noise(noisedata+2*num -1),noise(noisedata+2*num),noise(noisedata+1+2*num),noise(noisedata+2+2*num),zone_x);

	           float value=cubic_interp(u,a,b,v,zone_y);

	          return value;
	}


	static inline float perlin_octave_2d_cos(float x,float y, int width, int seed, float period)
		{

		           float freq=1/(float)(period);

		           int num=(int)(width*freq);
		           int step_x=(int)(x*freq);
		           int step_y=(int)(y*freq);
		           float zone_x=x*freq-step_x;
		           float zone_y=y*freq-step_y;
		           int box=step_x+step_y*num;
		           int noisedata=(box+seed);

		           float a=cos_interp(noise(noisedata),noise(noisedata+1),zone_x);
		           float b=cos_interp(noise(noisedata+num),noise(noisedata+1+num),zone_x);

		           float value=cos_interp(a,b,zone_y);

		          return value;
		}



	static inline float perlin_octave_3d(float x,float y, float z,int width, int seed, float period)
		{
		           float freq=1/(float)(period);

		           int num=(int)(width*freq);
		           int step_x=(int)(x*freq);
		           int step_y=(int)(y*freq);
		           int step_z=(int)(z*freq);
		           float zone_x=x*freq-step_x;
		           float zone_y=y*freq-step_y;
		           float zone_z=z*freq-step_z;

		           int boxB=step_x+step_y+step_z*num;
		           int boxC=step_x+step_y+step_z*(num+1);
		           int boxD=step_x+step_y+step_z*(num+2);
		           int boxA=step_x+step_y+step_z*(num-1);

		           float u,a,b,v,noisedata,box;

		           box = boxA;
		           noisedata=(box+seed);
		           u=cubic_interp(noise(noisedata-num-1),noise(noisedata-num),noise(noisedata-num+1),noise(noisedata-num+2),zone_x);
		           a=cubic_interp(noise(noisedata-1),noise(noisedata),noise(noisedata+1),noise(noisedata+2),zone_x);
		           b=cubic_interp(noise(noisedata+num -1),noise(noisedata+num),noise(noisedata+1+num),noise(noisedata+2+num),zone_x);
		           v=cubic_interp(noise(noisedata+2*num -1),noise(noisedata+2*num),noise(noisedata+1+2*num),noise(noisedata+2+2*num),zone_x);
		           float A=cubic_interp(u,a,b,v,zone_y);

		           box = boxB;
		           noisedata=(box+seed);
		           u=cubic_interp(noise(noisedata-num-1),noise(noisedata-num),noise(noisedata-num+1),noise(noisedata-num+2),zone_x);
		           a=cubic_interp(noise(noisedata-1),noise(noisedata),noise(noisedata+1),noise(noisedata+2),zone_x);
		           b=cubic_interp(noise(noisedata+num -1),noise(noisedata+num),noise(noisedata+1+num),noise(noisedata+2+num),zone_x);
		           v=cubic_interp(noise(noisedata+2*num -1),noise(noisedata+2*num),noise(noisedata+1+2*num),noise(noisedata+2+2*num),zone_x);
		           float B=cubic_interp(u,a,b,v,zone_y);

		           box = boxC;
		           noisedata=(box+seed);
		           u=cubic_interp(noise(noisedata-num-1),noise(noisedata-num),noise(noisedata-num+1),noise(noisedata-num+2),zone_x);
		           a=cubic_interp(noise(noisedata-1),noise(noisedata),noise(noisedata+1),noise(noisedata+2),zone_x);
		           b=cubic_interp(noise(noisedata+num -1),noise(noisedata+num),noise(noisedata+1+num),noise(noisedata+2+num),zone_x);
		           v=cubic_interp(noise(noisedata+2*num -1),noise(noisedata+2*num),noise(noisedata+1+2*num),noise(noisedata+2+2*num),zone_x);
		           float C=cubic_interp(u,a,b,v,zone_y);

		           box = boxD;
		           noisedata=(box+seed);
		           u=cubic_interp(noise(noisedata-num-1),noise(noisedata-num),noise(noisedata-num+1),noise(noisedata-num+2),zone_x);
		           a=cubic_interp(noise(noisedata-1),noise(noisedata),noise(noisedata+1),noise(noisedata+2),zone_x);
		           b=cubic_interp(noise(noisedata+num -1),noise(noisedata+num),noise(noisedata+1+num),noise(noisedata+2+num),zone_x);
		           v=cubic_interp(noise(noisedata+2*num -1),noise(noisedata+2*num),noise(noisedata+1+2*num),noise(noisedata+2+2*num),zone_x);
		           float D=cubic_interp(u,a,b,v,zone_y);

		           float value =cubic_interp(A,B,C,D,zone_z);

		           return value;
		}


	static inline float perlin_noise_2d(int x, int y,  int width, int octaves, int seed, float persistance, float basePeriod)
		{
			float p = persistance;
			float val = 0.0;

			for (int i = 0; i<octaves;i++)
			{
				val += perlin_octave_2d_cos(x,y,width,seed,basePeriod) * p;

				basePeriod *= 0.5;
				p *= persistance;
			}
			return val;
		}

	static inline float perlin_noise_3d(int x, int y, int z, int width, int octaves, int seed, float persistance, float basePeriod)
		{
			float p = persistance;
			float val = 0.0;

			for (int i = 0; i<octaves;i++)
			{
				val += perlin_octave_3d(x,y,z,width,seed,basePeriod) * p;

				basePeriod *= 0.5;
				p *= persistance;
			}
			return val;
		}



};

#endif /* PERLINNOISE_HPP_ */
