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

#include "randWalk.h"



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

	paths.MakeRoom(1000,1000,1);
	histogram.MakeRoom(1000,1000,1);
	histogram.GetVoxelData()=0;

	//init this walk
	RandomWalk<float> rw;
	//rw.SetWalkMode(RandomWalk<float>::persistent);
	rw.SetWalkMode(RandomWalk<float>::isotropic);
	rw.SetPersistenceTime(10.,1.);
	rw.SetPersistenceHeadingVariance(0.2);
	float speed=2.;

	//several random walks...
	for (int attemptNo=0; attemptNo < 10000; ++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;
		paths.GetVoxelData()=0;
		paths.SetVoxel(round(posX),round(posY),0, 100);

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

		//do the walk...
		for (int step=0; step < 50; ++step)
		{
			//update heading
			//heading += GetRandomGauss(0.f,1.f, &randState); //produces isotropic walks
			//heading += GetRandomGauss(0.f,0.2f, &randState);
			float dx,dy,dz;
			rw.DoOneStep(dx,dy,dz);

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

		//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)
			paths.SaveImage(attemptName);
	}

	histogram.SaveImage("histogram_endPositions.tif");

	return(0);
}
