#ifndef PROBEPARAMETERS_H
#define PROBEPARAMETERS_H

#include <math.h>

#include "model/scenarioGenerator/dtoInternal/probe/ProbeProperties.h"
#include "model/scenarioGenerator/dtoInternal/probe/SecondaryProbeProperties.h"

struct ScenGenProbeParameters_t {
private:
	ScenGenProbeProperties_t _probeProps;
	ScenGenSecondaryProbeProperties_t _scndProbeProps;

	void calcConvexScndProps(float dr, float angle)
	{
        _scndProbeProps.pitchAzimuth = 2 * asinf(_probeProps.pitch / 2 / _probeProps.radius);

		_scndProbeProps.correctionZ = -_probeProps.radius *
                                      cosf(
			(_probeProps.elementNo - 1) / 2.0f * _scndProbeProps.pitchAzimuth) / dr;

		for(auto i = 0; i < _probeProps.elementNo; i++)
		{
			auto temp = ((1 - _probeProps.elementNo) / 2.0f + i) * _scndProbeProps.pitchAzimuth;
			_scndProbeProps.elementAzimuth.push_back(temp);

			_scndProbeProps.elementXPosition.push_back(_probeProps.radius * sinf(temp) / dr);

			_scndProbeProps.elementYPosition.push_back(0);

			_scndProbeProps.elementZPosition.push_back(_probeProps.radius * cosf(
														   temp) / dr +
                                                       _scndProbeProps.correctionZ);
		}

		_scndProbeProps.vcMaxTheta = 0;

		if(angle < _probeProps.fieldOfView)
		{
			_scndProbeProps.fieldOfView = angle;
			_scndProbeProps.virtualOriginalZ = 0;
		}
		else
		{
			_scndProbeProps.fieldOfView = _probeProps.fieldOfView;
			_scndProbeProps.virtualOriginalZ = _probeProps.radius *
                                               (cosf(_scndProbeProps.fieldOfView / 2) -
                                                sinf(_scndProbeProps.fieldOfView / 2) /
                                                tanf(angle / 2));
		}
	}

	void calcLinearScndProps(float dr, bool virtualConvex)
	{
		_scndProbeProps.pitchAzimuth = _probeProps.pitch;

        _scndProbeProps.correctionZ = 0;

		for(auto i = 0; i < _probeProps.elementNo; i++)
		{
			_scndProbeProps.elementAzimuth.push_back(
				((1 - _probeProps.elementNo) / 2.0f + i) * _scndProbeProps.pitchAzimuth);

			_scndProbeProps.elementXPosition.push_back(_scndProbeProps.elementAzimuth[i] / dr);

			_scndProbeProps.elementYPosition.push_back(0);

			_scndProbeProps.elementZPosition.push_back(0);
		}

		if(virtualConvex)
		{
            _scndProbeProps.vcMaxTheta = _probeProps.vcMaxTheta;
			_scndProbeProps.virtualOriginalZ = _probeProps.fieldOfView / 2 / tanf(
				_scndProbeProps.vcMaxTheta);
			_scndProbeProps.fieldOfView = 2 * _scndProbeProps.vcMaxTheta;
		}
		else
		{
			_scndProbeProps.vcMaxTheta = 0;
			_scndProbeProps.virtualOriginalZ = 0;
			_scndProbeProps.fieldOfView = _probeProps.fieldOfView;
		}
	}

public:
	ScenGenProbeProperties_t getProbeProps()
	{
		return _probeProps;
	}

	ScenGenSecondaryProbeProperties_t getScndProbeProps()
	{
		return _scndProbeProps;
	}

	void setProbeProps(ScenGenProbeProperties_t probeProps)
	{
		_probeProps = probeProps;
	}

	void setScndProbeProps(ScenGenSecondaryProbeProperties_t probeProps)
	{
		_scndProbeProps = probeProps;
	}

	void calcScndProps(float dr, float angle, bool virtualConvex)
	{
		if(_probeProps.linear)
		{
			calcLinearScndProps(dr, virtualConvex);
		}
		else
		{
			calcConvexScndProps(dr, angle);
		}
	}
};

#endif //PROBEPARAMETERS_H