#include "FIHistograms.h"

#include "vislearning/baselib/FastFilter.h"
#include "vislearning/image/GenericImageTools.h"

#include "vislearning/baselib/ColorSpace.h"

using namespace OBJREC;
using namespace NICE;
using namespace std;

void FIHistograms::buildHSVMap ( 
	    CachedExample *ce,
	    int subsamplex, 
	    int subsampley,
	    int numBinsH, 
	    int numBinsS,
	    int numBinsV )
{
    // build HSV image
    // discrete !!
    // build integral images

    int numBins = numBinsH*numBinsS*numBinsV;
    int xsize;
    int ysize;
    ce->getImageSize ( xsize, ysize );
    
    int xsize_s = xsize / subsamplex;
    int ysize_s = ysize / subsampley;

    if ( ! ce->colorInformationAvailable() ) {
	fprintf (stderr, "FIHistograms: No color information available !\n");
	exit(-1);
    }

    NICE::MultiChannelImageT<int> & colorimg = ce->getIChannel ( CachedExample::I_COLOR );
    assert ( colorimg.numChannels == 3 );

    NICE::MultiChannelImageT<double> hsvimg ( xsize, ysize, colorimg.numChannels, true );

    ColorSpace::convert ( hsvimg, colorimg, 
			  ColorSpace::COLORSPACE_HSL, 
			  ColorSpace::COLORSPACE_RGB,
			  1.0, 255.0 );

    int *discretecolor = new int [ xsize * ysize ];

    long k = 0;
    for ( int y = 0 ; y < hsvimg.ysize ; y++ )
	for ( int x = 0 ; x < hsvimg.xsize ; x++,k++ )
	{
	    double h = hsvimg.data[0][k];
	    double s = hsvimg.data[1][k];
	    double v = hsvimg.data[2][k];

	    int hbin = (int)(numBinsH * h);
	    if ( hbin >= numBinsH ) hbin = numBinsH - 1;
	    int sbin = (int)(numBinsS * s);
	    if ( sbin >= numBinsS ) sbin = numBinsS - 1;
	    int vbin = (int)(numBinsV * v);
	    if ( vbin >= numBinsV ) vbin = numBinsV - 1;

	    int bin = ( hbin*numBinsS + sbin )*numBinsV + vbin;

	    discretecolor[k] = bin;
	}

    hsvimg.freeData();

    NICE::MultiChannelImageT<double> & colorhist = ce->getDChannel ( CachedExample::D_INTEGRALCOLOR );
    colorhist.reInit ( xsize_s, ysize_s, numBins, true );
    colorhist.setAll ( 0 );

    long korig = 0;
    for ( int y = 0 ; y < ysize ; y++ )
	for ( int x = 0 ; x < xsize ; x++,korig++ )
	{
	    int xs = x / subsamplex;
	    int ys = y / subsampley;

	    if ( xs >= xsize_s ) xs = xsize_s-1;
	    if ( xs < 0 ) xs = 0;
	    if ( ys >= ysize_s ) ys = ysize_s-1;
	    if ( ys < 0 ) ys = 0;
	    int k = xs + ys*xsize_s;
	    int val = discretecolor[korig];

	    if ( val >= colorhist.numChannels )
	    {
		fprintf (stderr, "v %d nc %d\n", val, colorhist.numChannels );
	    }
	    colorhist.data[val][k] += 1;

	    if ( !finite(colorhist.data[val][k]) ) {
		fprintf (stderr, "EOH Image failed: %f\n", colorhist.data[val][k]);
		exit(-1);
	    }
	}

    delete [] discretecolor;

    fprintf (stderr, "Calculating Integral Images\n");

    for ( uint i = 0 ; i < colorhist.numChannels ; i++ )
	colorhist.calcIntegral ( i );

    fprintf (stderr, "FIGradients: finished\n");

}