#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::MultiChannelImage3DT<int> & colorimg = ce->getIChannel ( CachedExample::I_COLOR );
  assert ( colorimg.channels() == 3 );

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

  ColorSpace::convert ( hsvimg,
                        colorimg.getColorMCI(0),
                        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.height() ; y++ )
    for ( int x = 0 ; x < hsvimg.width() ; x++, k++ )
    {
      double h = hsvimg.get(x,y,0);
      double s = hsvimg.get(x,y,1);
      double v = hsvimg.get(x,y,2);

      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::MultiChannelImage3DT<double> & colorhist = ce->getDChannel ( CachedExample::D_INTEGRALCOLOR );
  colorhist.reInit ( xsize_s, ysize_s, 1, numBins);
  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.channels() )
      {
        fprintf ( stderr, "v %d nc %d\n", val, colorhist.channels() );
      }
      colorhist[val](x,y) += 1;

      if ( !NICE::isFinite( colorhist[val](x,y) ) ) {
        fprintf ( stderr, "EOH Image failed: %f\n", colorhist[val](x,y) );
        exit ( -1 );
      }
    }

  delete [] discretecolor;

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

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

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

}