#include "soundfielddescription.h"

//template <typename Enumeration> auto as_integer(Enumeration const value)->typename std::underlying_type<SamplingRate>::type
//{
//	return static_cast<typename std::underlying_type<Enumeration>::type(value);
//}


soundfielddescription::soundfielddescription(char microphone_array_geometry[])
{
    // parsing and serializing JSON
    json j_complete = json::parse(microphone_array_geometry);

	nofmicrophones = j_complete["NumberofMicrophones"];
	array_type = (ArrayType)j_complete["MicrophoneArrayType"];
	array_scattering_type = (ArrayScattering)j_complete["MicrophoneArrayScat"];
	sampling_rate = samplingrates[static_cast<int>(j_complete["SamplingRate"])];
	sample_type = sampletypes[static_cast<int>(j_complete["SampleType"])];
	block_size = blocksizes[static_cast<int>(j_complete["BlockSize"])];

	microphone_array_params = micarray();

	for (int klm = 0; klm < nofmicrophones; klm++)
	{
		microphone_array_params.addnewmicrophone(j_complete["MicrophoneList"][klm]["xCoord"], j_complete["MicrophoneList"][klm]["yCoord"], j_complete["MicrophoneList"][klm]["zCoord"], j_complete["MicrophoneList"][klm]["micxLookCoord"], j_complete["MicrophoneList"][klm]["micyLookCoord"], j_complete["MicrophoneList"][klm]["miczLookCoord"], j_complete["MicrophoneArrayLookCoord"]["xLookCoord"], j_complete["MicrophoneArrayLookCoord"]["yLookCoord"], j_complete["MicrophoneArrayLookCoord"]["zLookCoord"]);
	}
	micanglestheta = microphone_array_params.getmicthetas();
	micanglesphi = microphone_array_params.getmicphis();

}
void* soundfielddescription::calcsphericalharmonics(double* pressure_real_in, double* pressure_imag_in, double* shd_realpart_out, double* shd_imagpart_out)
{
    int nof_sph = (int)(pow(SHDorder + 1, 2));
    for (int sn = 0; sn < nofsamples; sn++)
    {

        //malloc with zero valued spherical harmonics
        complex<double>* sph_harmonics = (complex<double>*)calloc(nof_sph, sizeof(complex<double>));

        //SHD computation according to the recording microphones
        for (int ml = 0; ml < nofmicrophones; ml++)
        {
            // get the microphone coordinates in theta/phi
            model::point<double, 2, cs::spherical<radian> > p1((micanglestheta.at(ml) * PI / 180), (micanglesphi.at(ml) * PI / 180));
            int counter = 0;
            // SHD calculations according to the spherical harmonics
            for (int sph_n = 0; sph_n <= SHDorder; sph_n++)
            {
                for (int sph_m = ((-1) * sph_n); sph_m <= sph_n; sph_m++)
                {
                    complex<double> calcharmonic_conj = conj((complex<double>)boost::math::spherical_harmonic(sph_n, sph_m, get<0>(p1), get<1>(p1)));
                    *(sph_harmonics + counter) += complex<double>(pressure_real_in[sn* nofmicrophones + ml], pressure_imag_in[sn * nofmicrophones + ml]) * calcharmonic_conj;
                    shd_realpart_out[sn * nof_sph + counter] = sph_harmonics[counter].real();
                    shd_imagpart_out[sn * nof_sph + counter] = sph_harmonics[counter].imag();
                    counter++;
                }
            }
        }
        // Free the allocated space for spherical harmonics
       free(sph_harmonics);
    }
    return 0;
}