/******************************************************************************************
> [KAZOE]                                                                                 <
> Initial Sofware by [Yannick Verdie, Florent Lafarge], Copyright (C) Inria (GEOMETRICA)  <
> All Rights Reserved, 2012, [Version 1.0].                                               <
******************************************************************************************/
#ifndef COMMON_H
#define COMMON_H

#include "DataTree.h"


#define CUDART_PI_F 3.141592654f


#pragma warning(disable:4482)   // Non-standard extension used
enum METHOD_DATATERM : unsigned char {BAYESIAN = 0, BHATTACHARYA = 1};

//-------------------------- Those classes are used for gerResult on host
//----------------------------------------------------------------------------------------------------//
class Shape
{
public:
	enum TYPE_SHAPE {ELLIPSE = 0, CIRCLE = 1, TREE3D = 2};
	TYPE_SHAPE typeObject;
};

class Ellipse_Shape : public Shape
{
public:
	Ellipse_Shape(float a, float b, float c, float d, float e)
	{
		x = a; y= b; angle = c; axis0 = d; axis1 = e;
		typeObject = TYPE_SHAPE::ELLIPSE;
	}

	float x;
	float y;
	float angle;
	float axis0;
	float axis1;

	float getRadius(){return max(axis0 , axis1);}
};



//----------------------------------------------------------------------------------------------------//
//----------------------------------------------------------------------------------------------------//


class Const_Parameter
{
public:
	Const_Parameter( float l, float m, bool r, bool s, char* file, int V)
	{
		Intersections_Alpha = l;
		Hard_Core			= m;
		ConstructDataMap    = r;
		createOctree		= s; //usefull only for Tree3D
		FileName[0] = '\0';
		if ( file)
		{
			int lng = strlen(file);
			if (lng > 0 && lng < 100)
			{
				strcpy(FileName,file);
			}
		}

		Verbose = V;
	}

	Const_Parameter( float l, float m, bool r,char* file, int V)
	{
		Intersections_Alpha = l;
		Hard_Core			= m;
		ConstructDataMap    = r;
		createOctree		= false; //usefull only for Tree3D
		FileName[0] = '\0';
		if ( file)
		{
			int lng = strlen(file);
			if (lng > 0 && lng < 100)
			{
				strcpy(FileName,file);
			}
		}

		Verbose = V;
	}

	~Const_Parameter()
	{
	}

	
	float Intersections_Alpha;
	float Hard_Core;
	bool ConstructDataMap;
	bool createOctree;
	char FileName[100];
	int Verbose;
};

 class bayesian_Parameter : public Const_Parameter
{
public:

	bayesian_Parameter(int a, int b, int c, int d, float g, float h, float i, float j, float k, float l, float m, float n, bool r, char* file, int Verbose)
		: Const_Parameter( l, m,  r, file, Verbose)
	{
		Ellipse_MinWidth	= a;
		Ellipse_MaxWidth	= b;
		Ellipse_MinHeight	= c;
		Ellipse_MaxHeight	= d;
		Bayesian_Alpha		= g;
		Background_Avg		= h;
		Background_Sigma	= i;
		Shape_Avg			= j;
		Shape_Sigma			= k;
		MaxTranslation		= n;
	}

	int Ellipse_MinWidth;
	int Ellipse_MaxWidth;
	int Ellipse_MinHeight;
	int Ellipse_MaxHeight;
	float Bayesian_Alpha;
	float Background_Avg;
	float Background_Sigma;
	float Shape_Avg;
	float Shape_Sigma;
	float MaxTranslation;
};	

class bhatt_Parameter : public Const_Parameter
{
public:
	bhatt_Parameter(int a, int b, int c, int d, float l, float m, float n, float o, float p, float q, bool r, char* file, int Verbose)
		: Const_Parameter( l, m,  r, file, Verbose)
	{
		Ellipse_MinWidth	= a;
		Ellipse_MaxWidth	= b;
		Ellipse_MinHeight	= c;
		Ellipse_MaxHeight	= d;
		MaxTranslation		= n;
		Bhatt_Alpha			= o;
		Bhatt_Thickness		= p;
		Bhatt_Threshold		= q;
	}

	int Ellipse_MinWidth;
	int Ellipse_MaxWidth;
	int Ellipse_MinHeight;
	int Ellipse_MaxHeight;
	float MaxTranslation;
	float Bhatt_Alpha;
	float Bhatt_Thickness;
	float Bhatt_Threshold;
};
//
//

extern "C" float cuda_RJMCMC_init(int* ptrImage, int w, int h, int border, Const_Parameter* param,int size_margin_cell, METHOD_DATATERM method);
extern "C" unsigned int getNbResult();



extern "C" void cuda_delete();
extern "C" void cuda_startTimer();
extern "C" float cuda_getTime();
extern "C" void cuda_resetTime();
extern "C" void cuda_blockandWait();
//
//
//
//
//
//
//	
extern "C" void birth_Simulation_GPU_Ellipse(float temperature, int* ptrImage, int w, int h, int border, Const_Parameter* param);
extern "C" void death_Simulation_GPU_Ellipse(float temperature, int* ptrImage, int w, int h, int border, Const_Parameter* param);
extern "C" void Enlarge_Simulation_GPU_Ellipse(float temperature, int* ptrImage, int w, int h, int border, Const_Parameter* param);
extern "C" void Translate_Simulation_GPU_Ellipse(float temperature, int* ptrImage, int w, int h, int border, Const_Parameter* param);
extern "C" void Rotate_Simulation_GPU_Ellipse(float temperature, int* ptrImage, int w, int h, int border, Const_Parameter* param);
extern "C" float cuda_RJMCMC_init(int* ptrImage, int w, int h, int border, Const_Parameter* param,int size_margin_cell, METHOD_DATATERM method);
extern "C" void getResult_Ellipse_Shape(Ellipse_Shape** a, int * b, double *c, bool verbose = false);
#endif COMMON_H