#pragma once

#ifndef INTERPOLATION_H
#define INTERPOLATION_H

#include <complex>
#include <Eigen/Core>
#include <Eigen/Dense>
#include <stdio.h>
#include <stdlib.h>
#include <Eigen/Core>
#include <Eigen/Dense>


namespace LampInterpolation {
	enum interpolationtype {
		nearest,
		linear,
		cubic,
	};


	/// <summary>
	/// 矩阵为 1xn
	/// </summary>
	template<typename T>
	std::complex<T> interpolation(Eigen::MatrixX<std::complex<T>>& echo, double& index, interpolationtype methodtype)
	{
		assert(echo.rows() != 1 || echo.cols() >= index || index < 0); // 断言
		if (methodtype == interpolationtype::linear) {
			return interpolationLinear(echo, index);
		}
		else if (methodtype == interpolationtype::cubic) {

		}
		else if (methodtype == interpolationtype::nearest) {
			return interpolationNearest(echo, index);
		}
		else {}
		return std::complex<T>(0, 0);
	};

	template<typename T>
	std::complex<T> interpolationLinear(Eigen::MatrixX<std::complex<T>>& echo, double& index)
	{
		size_t last_ids = size_t(std::floor(index));
		size_t next_ids = size_t(std::ceil(index));

		std::complex<T> last_value = echo(1, last_ids);
		std::complex<T> next_value = echo(1, next_ids);

		// 实部，虚部同时插值
		double real = last_value.real() + ((next_value.real() - last_value.real()) / (next_ids - last_ids)) * (index - last_ids);
		double imag = last_value.imag() + ((next_value.imag() - last_value.imag()) / (next_ids - last_ids)) * (index - last_ids);

		return std::complex<T>(T(real), T(imag));
	};

	template<typename T>
	std::complex<T> interpolationNearest(Eigen::MatrixX<std::complex<T>>& echo, double& index)
	{
		size_t nearest_ids = size_t(std::round(index));
		return echo(1, nearest_ids);
	};

}


#endif