/*
	ZSimplexNoiseMap.hpp
	Author : Chris Ertel

	Purpose :	Interface to create a map for simplex noise values.

	Changelog
	2/20/11 - Creation (crertel)
*/

#pragma once

#ifndef _ZSIMPLEXNOISEMAP_H
#define _ZSIMPLEXNOISEMAP_H

#include <ZUtil/ZSimplexNoise.hpp>
#include <ZUtil/ZNoiseMap.hpp>
#include <ZUtil/ZUtil.hpp>

class ZSimplexNoiseMap : public ZNoiseMap
{
protected:
	ZSimplexNoise noiseGen;
	float lacunarity;
	float persistence;
	int numberofoctaves;
	float* values;

public:

	ZSimplexNoiseMap()
		: lacunarity(.5), persistence(.5), numberofoctaves(8), values(NULL)
	{
	}

	virtual ~ZSimplexNoiseMap()
	{
	}

	virtual int GetDimensionality() = 0;
	
	//Subclass implementation
	float GetLacunarity() { return this->lacunarity; }
	
	//Subclass implementation
	float GetPersistence() { return this->persistence; }

	//Subclass implementation
	int GetNumberOfOctaves() { return this->numberofoctaves; } 

	//Not implemented
	virtual int GetNumberSamplesInX() = 0;
	//Not implemented
	virtual int GetNumberSamplesInY() = 0;
	//Not implemented
	virtual int GetNumberSamplesInZ() = 0;
	//Not implemented
	virtual int GetNumberSamplesInW() = 0;
	
	/*
	public ZSimplexNoiseMap::GetSamples
	 
	Function to get array of values for noise map.
	 
	@return (float*) - array of values
	*/
	float* GetSamples() { return this->values; }

	//Subclass implementation
	void SetLacunarity(float _lac) { this->lacunarity = _lac; }						// scaling of successive frequencies in noise octaves
	//Subclass implementation
	void SetPersistence(float _per) { this->persistence = _per; }						// scaling of successive amplitudes in noise octaves
	//Subclass implementation
	void SetNumberOfOctaves(int _numOctaves ) { this->numberofoctaves = _numOctaves; }

	//Not implemented
	virtual void SetNumberSamplesInX(int _numSamples) = 0;
	//Not implemented
	virtual void SetNumberSamplesInY(int _numSamples) = 0;
	//Not implemented
	virtual void SetNumberSamplesInZ(int _numSamples) = 0;
	//Not implemented
	virtual void SetNumberSamplesInW(int _numSamples) = 0;

	//Not implemented
	virtual bool Generate(int _seed) = 0;
	//Not implemented
	virtual void Cleanup() = 0;
};

class ZSimplexNoiseMap2D : public ZSimplexNoiseMap
{
protected:
	int numberSamplesInX;
	int numberSamplesInY;

public:
	ZSimplexNoiseMap2D()
		: ZSimplexNoiseMap(), numberSamplesInX(0), numberSamplesInY(0)
	{
	}

	~ZSimplexNoiseMap2D()
	{
		this->Cleanup();
	}

	//Subclass implementation
	int GetDimensionality() { return 2; }
	//Subclass implementation
	int GetNumberSamplesInX() { return this->numberSamplesInX; }
	//Subclass implementation
	int GetNumberSamplesInY() { return this->numberSamplesInY; }
	//Subclass implementation
	int GetNumberSamplesInZ() { return 0; }
	//Subclass implementation
	int GetNumberSamplesInW() { return 0; }

	//Subclass implementation
	void SetNumberSamplesInX(int _numSamples) { this->numberSamplesInX = _numSamples; }
	//Subclass implementation
	void SetNumberSamplesInY(int _numSamples) { this->numberSamplesInY = _numSamples; }
	//Subclass implementation
	void SetNumberSamplesInZ(int _numSamples) { URFP ( _numSamples) ; }
	//Subclass implementation
	void SetNumberSamplesInW(int _numSamples) { URFP ( _numSamples) ; }

	/*
	public ZSimplexNoiseMap2D::getValue
	 
	Gets value at a particular point on the noise map.
	 
	@param _x - x-coordinate to sample
	@param _y - y-coordinate to sample
	@return (double) - value at point (x,y)
	*/
	float getValue(int _x, int _y);

	//Subclass implementation
	bool Generate(int _seed = 0);
	//Subclass implementation
	void Cleanup();
};

class ZSimplexNoiseMap3D : public ZSimplexNoiseMap
{
protected:
	int numberSamplesInX;
	int numberSamplesInY;
	int numberSamplesInZ;

public:
	ZSimplexNoiseMap3D()
		: ZSimplexNoiseMap(), numberSamplesInX(0), numberSamplesInY(0), numberSamplesInZ(0)
	{
	}

	~ZSimplexNoiseMap3D()
	{
		this->Cleanup();
	}
	
	//Subclass implementation
	int GetDimensionality() { return 3; }
	//Subclass implementation
	int GetNumberSamplesInX() { return this->numberSamplesInX; }
	//Subclass implementation
	int GetNumberSamplesInY() { return this->numberSamplesInY; }
	//Subclass implementation
	int GetNumberSamplesInZ() { return this->numberSamplesInZ; }
	//Subclass implementation
	int GetNumberSamplesInW() { return 0; }

	//Subclass implementation
	void SetNumberSamplesInX(int _numSamples) { this->numberSamplesInX = _numSamples; }
	//Subclass implementation
	void SetNumberSamplesInY(int _numSamples) { this->numberSamplesInY = _numSamples; }
	//Subclass implementation
	void SetNumberSamplesInZ(int _numSamples) { this->numberSamplesInZ = _numSamples; }
	//Subclass implementation
	void SetNumberSamplesInW(int _numSamples) { URFP ( _numSamples) ; }

	/*
	public ZSimplexNoiseMap3D::getValue
	 
	Gets value at a particular point on the noise map.
	 
	@param _x - x-coordinate to sample
	@param _y - y-coordinate to sample
	@param _z - z-coordinate to sample
	@return (float) - value at point in noise map.
	*/
	float getValue(int _x, int _y, int _z);

	//Subclass implementation
	bool Generate(int _seed = 0);
	//Subclass implementation
	void Cleanup();
};

class ZSimplexNoiseMap4D : public ZSimplexNoiseMap
{
protected:
	int numberSamplesInX;
	int numberSamplesInY;
	int numberSamplesInZ;
	int numberSamplesInW;

public:
	ZSimplexNoiseMap4D()
		: ZSimplexNoiseMap(), numberSamplesInX(0), numberSamplesInY(0), numberSamplesInZ(0),
		numberSamplesInW(0)
	{
	}

	~ZSimplexNoiseMap4D()
	{
		this->Cleanup();
	}

	//Subclass implementation
	int GetDimensionality() { return 4; }
	//Subclass implementation
	int GetNumberSamplesInX() { return this->numberSamplesInX; }
	//Subclass implementation
	int GetNumberSamplesInY() { return this->numberSamplesInY; }
	//Subclass implementation
	int GetNumberSamplesInZ() { return this->numberSamplesInZ; }
	//Subclass implementation
	int GetNumberSamplesInW() { return this->numberSamplesInW; }

	//Subclass implementation
	void SetNumberSamplesInX(int _numSamples) { this->numberSamplesInX = _numSamples; }
	//Subclass implementation
	void SetNumberSamplesInY(int _numSamples) { this->numberSamplesInY = _numSamples; }
	//Subclass implementation
	void SetNumberSamplesInZ(int _numSamples) { this->numberSamplesInZ = _numSamples; }
	//Subclass implementation
	void SetNumberSamplesInW(int _numSamples) { this->numberSamplesInW = _numSamples; }

	/*
	public ZSimplexNoiseMap4D::getValue
	 
	Gets value at a particular point on the noise map.
	 
	@param _x - x-coordinate to sample
	@param _y - y-coordinate to sample
	@param _z - z-coordinate to sample
	@param _w - w-coordinate to sample
	@return (float) - value at point in noise map. 
	*/
	float getValue(int _x, int _y, int _z, int _w);

	//Subclass implementation
	bool Generate(int _seed = 0);
	//Subclass implementation
	void Cleanup();
};

#endif

