#include <iostream>
#include <i3d/image3d.h>

#include "randWalk.h"



int main(int argc,char **argv)
{
	i3d::Image3d<i3d::GRAY16> pathsI,pathsC,histogram;

	pathsI.MakeRoom(1000,1000,1); //individual paths
	pathsC.MakeRoom(1000,1000,1); //combined paths
	pathsC.GetVoxelData()=0;
	histogram.MakeRoom(1000,1000,1);
	histogram.GetVoxelData()=0;

	//init this walk
	RandomWalk<float> rw;
	rw.UseWrappedCauchyDistribution(0.8); // => r=0.8
	//rw.UseWrappedNormalDistribution(0.67); // => r=0.8
	//rw.UseUniformDistribution();
	//My own testing 3-peaks distribution:
	/*
	rw.turningAngleDistribution[-1.0]=0.;
	rw.turningAngleDistribution[-0.8]=1.;
	rw.turningAngleDistribution[-0.6]=0.;
	rw.turningAngleDistribution[-0.2]=0.;
	rw.turningAngleDistribution[ 0.0]=1.;
	rw.turningAngleDistribution[+0.2]=0.;
	rw.turningAngleDistribution[+0.6]=0.;
	rw.turningAngleDistribution[+0.8]=1.;
	rw.turningAngleDistribution[+1.0]=0.;
	rw.PrepareRandomTurningField();
	*/
	float speed=2.;

	//several random walks...
	for (int attemptNo=0; attemptNo < 100; ++attemptNo)
	{
		//std::cout << "========== " << attemptNo << "==========\n";

		//name this walk
		char attemptName[50];
		sprintf(attemptName,"wALk%06d.tif",attemptNo);
		if (!(attemptNo % 500)) std::cout << attemptName << "\n";

		//initial position
		float posX=500.f;
		float posY=500.f;
		pathsI.GetVoxelData()=0;
		pathsI.SetVoxel(round(posX),round(posY),0, 100);
		if (attemptNo < 50)
			pathsC.SetVoxel(round(posX),round(posY),0, attemptNo+1);

		//reset initial direction
		// (would rather reset the whole RandomWalk object, but
		//  seeding is not working properly... rapid inits...)
		rw.ResetXYHeading(0.);

		//do the walk...
		for (int step=0; step < 50; ++step)
		{
			//update heading
			float dx,dy;
			rw.DoOneStep2D(dx,dy);

			//update speed...
			//speed += GetRandomGauss(0.f,1.f, &randState);
			
			//update current position
			posX += speed * dx;
			posY += speed * dy;
			
			//draw current position
			pathsI.SetVoxel(round(posX),round(posY),0, 100+5*step);
			if (attemptNo < 50)
				pathsC.SetVoxel(round(posX),round(posY),0, attemptNo+1);
		}

		//record the final position into the histogram of end-positions
		if (histogram.Include(round(posX),round(posY),0))
			histogram.SetVoxel(round(posX),round(posY),0,
			           histogram.GetVoxel(round(posX),round(posY),0)+1);

		if (attemptNo < 50)
			pathsI.SaveImage(attemptName);
	}

	pathsC.SaveImage("wALks_combined.tif");
	histogram.SaveImage("histogram_endPositions.tif");

	return(0);
}
