#pragma once

#define PI 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068

#include <fstream>
#include <iostream>
#include <sstream>
#include <string> 
#include <vector>
#include <complex>

#include "pixelinfo_sds.h"

#include "boost/geometry.hpp"
#include "boost/math/special_functions/bessel.hpp"
#include "boost/math/special_functions/bessel_prime.hpp"
#include "boost/math/special_functions/legendre.hpp"
#include "boost/math/special_functions/hankel.hpp"
#include "boost/math/special_functions/spherical_harmonic.hpp"
#include "boost/variant/get.hpp"

#include <armadillo>

#define Order0_HP 12
#define Order1_HP 48
#define Order2_HP 192
#define Order3_HP 762
#define PI 3.14159
#define Kappa 4.0

#define HPMaxvalue 19.2


using namespace std;
using namespace boost::math;
using namespace boost::geometry;
using namespace arma;

class healpixkernel_sds
{
public:
	healpixkernel_sds(int order);
	void gethealpixcoordinates(int id, float& theta, float& phi);
	int* gethealpixneighbours(int id);
	int gethealpixorder();
	int gethealpixnumberofpixels();
	float* calculatelegendrekernels(int max_sphorder);
	float* calculatelegendrekernels_bnkra(int max_sphorder);
	float* getpinvlegendrekernels(int hpnumber);
	float* getpinvkernels(int hpnumber);
	void* getmultiplicationresult(int max_sphorder);
	void* return_multiplicationresult_real();
	void* return_multiplicationresult_imag();

	double* create_vonmises(int hpnumber_center);
	double* create_vonmisesfull();
	void* calculateorthogonalLK();
	void* calculateSRFMultiplier(int max_sphorder, int nofmicrophones,int freqrange, vector<float> micanglestheta, vector<float> micanglesphi,float* realpart, float* imagpart);
	void ConvertSphericalToCartesian(float& distance, float& theta, float& phi, float& x, float& y, float& z);
	void ConvertCartesionToSpherical(float& distance, float& theta, float& phi, float& x, float& y, float& z);
	float FindAngleBtw(float& x1, float& y1, float& z1, float& mag1, float& x2, float& y2, float& z2, float& mag2);
	float def_vonmises(float kappa, float costheta);
	float* calculatepw_magnitude(int Micnumber, float* micanglestheta, float* micanglesphi);
	void gethealpixindice(int& id, float theta, float phi);
	void* calc_pinv_matrices(int nofsources, vector<float> Az, vector<float> El);
private:
	int healpixorder;
	vector<pixelinfo_sds*> pixels_invector;
	double* legendrekernels;
	double* legendrekernels_bnkra;
	double* legendrekernels_bnkra_imag;
	float* legendrekernels_infloat;
	float* legendrekernels_infloat_bnkra;
	float* legendrekernels_infloat_bnkra_imag;
	complex<float>* SRFMultiplier;
	vector<fmat> pinv_legendrekernels;
	vector<fmat> res_legendrekernels;
	float* piv_legendre;
	double* vonmises_values;
	float* multiplicationresult;
	float* multiplicationresult_imag;
	float* pinv_multiplier;
	double* pinv_multiplier_indouble;
};

