/** 
 * @file IDRandomSampling.cpp
 * @brief random interest point sampling
 * @author Erik Rodner
 * @date 02/05/2008

 */
#include <iostream>

#include "vislearning/features/localfeatures/IDRandomSampling.h"

using namespace OBJREC;

using namespace std;

using namespace NICE;

IDRandomSampling::IDRandomSampling(const Config *conf, int _numSamples) :
	numSamples(_numSamples)
{
	minScale = conf->gD("IDRandomSampling", "min_scale", 1.0);

	srand(time(NULL));
}

IDRandomSampling::~IDRandomSampling()
{
}

int IDRandomSampling::getInterests(const NICE::Image & img,
		std::vector<Vector> & positions) const
{
	// FIXME: is this function broken ??

	double rmin = minScale * 6;

	double rmax = std::min(img.width(), img.height()) / 2.0;
	size_t len = (size_t) (rmax - rmin);

	NICE::Vector p(len);
	double sum = 0.0;
	for (size_t k = 0; k < len; k++)
	{
		double r = k + rmin;

		p[k] = img.width() * img.height() - 2 * (img.width() + img.height())
				* r + 4 * r * r;
		sum += p[k];
	}

	p[0] /= sum;
	for (size_t k = 1; k < len; k++)
	{
		p[k] /= sum;
		p[k] = p[k - 1] + p[k];
	}

	vector<double> sizes;

	for (size_t i = 0; i < (size_t) numSamples; i++)
	{
#ifdef WIN32
		double sr = double( rand() ) / RAND_MAX;
#else
		double sr = drand48();
#endif
		int r = len - 1;
		while ((p[r] > sr) && (r > 0))
			r--;

		sizes.push_back(r);
	}
	sort(sizes.begin(), sizes.end());

	for (size_t i = 0; i < sizes.size(); i++)
	{
		double r = sizes[i];
		double scale = (r + rmin) / 6.0;
#ifdef WIN32
		double x = double( rand() ) / RAND_MAX * (img.width() - 2 * r) + r;
		double y = double( rand() ) / RAND_MAX * (img.height() - 2 * r) + r;
#else
		double x = drand48() * (img.width() - 2 * r) + r;
		double y = drand48() * (img.height() - 2 * r) + r;
#endif

		Vector pos(3);
		pos[0] = x;
		pos[1] = y;
		pos[2] = scale; // FIXME: level = scale??
		positions.push_back(pos);
	}

	fprintf(stderr, "IDRandomSampling finished\n");
	return 0;
}

int IDRandomSampling::getInterests(const ImagePyramid & imp,
		std::vector<Vector> & positions) const
{
	int numLevels = imp.getNumLevels();

	for (int j = 0; j < numSamples; j++)
	{
		int level = rand() % numLevels;

		if ((level < 0) || (level >= numLevels))
			continue;

		const NICE::Image & img = imp.getLevel(level);

		int x = rand() % (img.width() + 1);
		int y = rand() % (img.height() + 1);

		double xo, yo;
		imp.getOriginalCoordinates(x, y, level, xo, yo);

		Vector pos(3);
		pos[0] = xo;
		pos[1] = yo;
		pos[2] = level;
		positions.push_back(pos);
	}
	fprintf(stderr, "IDRandomSampling finished\n");
	return 0;
}
