
#ifndef __MLISTEPI__
#define __MLISTEPI__

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>

#include "MUtils.h"
#include "MCharImage.h"
#include "MFloatImage.h"

class MFloatImage;

//Liste de points d'interet
class MListePI
{
protected:
	int nbPoints;			//Nombre de points dans la liste
	int nbPointsMax;	//Nombre maximum de points de points dans la liste (dimension des tableaux)

  //pointeur vers l'image sur laquelle ont été calculés les points d'interet
  MCharImage* image;
  //image contenant la valeur du critère (de Harris ou de Moravec)
  MFloatImage* imageCritere;
	
	//Coordonnées de chaque point
	int* tabX;
	int* tabY;

	//Valeurs precalculees autour de chaque point de la liste pour calcul de ZNCC
  //ZNCCMoyenne(P)=1/(11*11)*somme(I(P+d), pour d dans voisinage 5x5 de P)
  //ZNCCNum(P,d)=(I(P+d)-ZNCCMoyenne(P))/ZNCCDenom(P) -> 121 valeurs par point d'interet
  // avec ZNCCDenom(P)==sqrt(somme(ZNCCNum(d)^2, pour d dans voisinage 11x11 de P) )
	float** ZNCCNum;  //ZNCCNum[i] est un tableau de 121 valeurs

	/* //pour essayer calcul de ZNCC avec des short
	float* ZNCCDenom;
	signed short** ZNCCNumShort;*/
					
public:
	MListePI(int inNbPointsMax=0);
	MListePI(int inNbPointsMax,MCharImage& inImage,MFloatImage& inImageCritere);
  ~MListePI();
  void deleteZNCCPrecalculs();

  //Changement des images et remise a zero des tableaux
  void Init(MCharImage& inImage,MFloatImage& inImageCritere);
  
  //Ajout d'un point dans la liste
  void AddPoint(int x,int y) {if (nbPoints<nbPointsMax) {tabX[nbPoints]=x;tabY[nbPoints]=y;nbPoints++;} }
  //troncature de la liste pour garder les N premiers elements
  //retourne le nombre de points reellement conserves
  int Cut(int N) {nbPoints=Min(N,nbPoints); return nbPoints;}

  //Nombre de points dans la liste
  int getNbPoints() {return nbPoints;}

  //Acces aux coordonnees des points d'interet
  int getX(int i) {return tabX[i];}
  int getY(int i) {return tabY[i];}
  //Acces a l'image
  MCharImage& GetImage() {return *image;}
  
  //Acces aux valeurs precalculees des scores ZNCC
	float* getZNCCNum(int i) {return ZNCCNum[i];}

	/*signed short* getZNCCNumShort(int i) {return ZNCCNumShort[i];}
	float getZNCCDenom(int i) {return ZNCCDenom[i];}*/
			
  //Tri des points d'interet par ordre decroissant en fonction du critère (Harris ou Moravec)
  void HeapSort();
  void HeapSortMaxsiftDown(int root, int bottom);

  //Affichage des points pour visualistaion
  void draw(MCharImage &img);
  
  //precalcul en vue du calcul du score ZNCC entre 2 points
  void PrecalculZNCC11x11();
  
};

#endif

