// -------------------------------------------------------------------- //
// FILE 		: RandomClass.cpp										//
// DATE 		: 15/03/2004											//
// AUTOR		: Aymeric							//
// DESCRIPTION  : class RandomClass										//
// -------------------------------------------------------------------- //


#include <iostream.h>
#include <vcl.h>
#include <time.h>
#include "RandomClass.h"


// -- Search(), MoveAndPlace() and insertionSort() are functions that I used
//    last year. Sort by insertion (recursive method).

// -------------------------------------------------------------------- //
// Search() search the position of an element in an array				//
// in  : the array and the position i									//
// out : the position													//
// -------------------------------------------------------------------- //

int Search(int A[], int i)
{
	int d,f,k;
	if (A[i] >= A[i-1]) return (i);
	if (A[i] <= A[0]) return (0);
	d=0;
	f=i-1;
	while (d+1 != f)
	{
		k=(d+f)/2;
		if (A[i] > A[k]) d=k;
		else f=k;
	}
	return (f);
}


// -------------------------------------------------------------------- //
// MoveAndPlace() move and place an element in an array					//
// in  : the array, the current position i, the destination position r	//
// out : nothing														//
// -------------------------------------------------------------------- //

void MoveAndPlace(int A[], int i, int r)
{
	int temp;
	temp=A[i];
	for (int j=i; j > r; j--) A[j]=A[j-1];
	A[r]=temp;
}


// -------------------------------------------------------------------- //
// insertionSort() sort an array of integers 							//
// in  : an array and a position n										//
// out : return an int													//
// -------------------------------------------------------------------- //

int insertionSort(int A[], int n)
{
	int r;
	// -- if n==0 we can stop the recursition
	if (n == 0) return (1);
	n--;
	insertionSort(A,n);
	r=Search(A,n);
	if (r != n) MoveAndPlace(A,n,r);
}



// -------------------------------------------------------------------- //
// TRandom() constructor												//
// in  : nothing														//
// out : nothing														//
// -------------------------------------------------------------------- //

TRandom::TRandom()
{
	mPrevFileName="";
}


// -------------------------------------------------------------------- //
// Scramble() take the numbers passed in and reorder them				//
// in  : an array of integers and the size								//
// out : nothing														//
// -------------------------------------------------------------------- //

void TRandom::Scramble(int Arr[], int Size)
{
	int i=insertionSort(Arr,Size);
}


// -------------------------------------------------------------------- //
// FillArray() fill an array with random values between Lower and Upper //
// in  : an array, the size, a boolean (determines if values must be	//
//		 unique) and the range (minimum RangeLower and max RangeUpper)	//
// out : nothing														//
// -------------------------------------------------------------------- //

void TRandom::FillArray(int Arr[], int Size, bool Unique, int RangeLower, int RangeUpper)
{
	time_t t;
	srand((unsigned) time(&t));
	int j;

	if (RangeLower > RangeUpper)
	{
		if (Unique) RangeUpper=Size+RangeLower;
		else RangeUpper=Size;
	}

	if ((Unique) && (RangeUpper - RangeLower < Size)) RangeUpper=Size+RangeLower;

	for (int i=0; i < Size; i++)
	{
		j=rand()%(RangeUpper+1);
		if (j < RangeLower) j+=RangeLower;

		if (Unique)
		{
			for (int search=0; search != i; search++)
			{
				if (Arr[search] == j)
				{
					// -- if 'j' is already in the array, we generate another 'j'
					j=rand()%(RangeUpper+1);
					if (j < RangeLower) j+=RangeLower;
					search=-1;
				}
			}
		}
		Arr[i]=j;
	}
}


// -------------------------------------------------------------------- //
// GetFileName() return a random file in the directory in param			//
// in  : type of files, directory and a boolean							//
// out : the full path of the file										//
// -------------------------------------------------------------------- //

AnsiString TRandom::GetFileName(AnsiString Type, AnsiString Dir, bool Unique)
{
	WIN32_FIND_DATA wData;
    AnsiString files=Dir + Type;

	HANDLE listing;
	AnsiString *name;
	AnsiString returnFile="";
	int i=0,j=0;

	listing = ::FindFirstFile(files.c_str(), &wData);

	if (listing == INVALID_HANDLE_VALUE) exit(0);

	// -- we determine the number of files
	while((::FindNextFile(listing, &wData))) i++;

	::FindClose(listing);

	listing = ::FindFirstFile(files.c_str(), &wData);
	name = new AnsiString [i];

	while((::FindNextFile(listing, &wData)))
	{
		if (Unique)
		{
			if (mPrevFileName != wData.cFileName)
			{
				name[j++] = wData.cFileName;
				mPrevFileName = wData.cFileName;
			}
		}
		else
		{
			name[j++] = wData.cFileName;
			mPrevFileName = wData.cFileName;
		}
	}
	::FindClose(listing);

	time_t t;
	srand((unsigned) time(&t));

	if (i == 0) i=1;

	// -- we choose a random row in the array
	returnFile=Dir + name[rand()%i];

	delete []name;

	return(returnFile);
}


