/*
	File                 : nsl_sf_window.c
	Project              : LabPlot
	Description          : NSL special window functions
	--------------------------------------------------------------------
	SPDX-FileCopyrightText: 2016-2017 Stefan Gerlach <stefan.gerlach@uni.kn>
	SPDX-License-Identifier: GPL-2.0-or-later
*/

#include "nsl_sf_window.h"
#include "nsl_common.h"
#include <gsl/gsl_math.h>
#include <gsl/gsl_sf_trig.h>

const char* nsl_sf_window_type_name[] = {i18n("Rectangular (Uniform)"),
										 i18n("Triangular"),
										 i18n("Triangular II (Bartlett)"),
										 i18n("Triangular III (Parzen)"),
										 i18n("Welch (Parabolic)"),
										 i18n("Hann (Raised Cosine)"),
										 i18n("Hamming"),
										 i18n("Blackman"),
										 i18n("Nuttall"),
										 i18n("Blackman-Nuttall"),
										 i18n("Blackman-Harris"),
										 i18n("Flat Top"),
										 i18n("Cosine"),
										 i18n("Bartlett-Hann"),
										 i18n("Lanczos")};

int nsl_sf_apply_window(double data[], size_t N, nsl_sf_window_type type) {
	if (N == 0)
		return -1;

	size_t i;
	switch (type) {
	case nsl_sf_window_uniform:
		/* do nothing */
		break;
	case nsl_sf_window_triangle:
		for (i = 0; i < N; i++)
			data[i] = 1.0 - 2. / N * fabs(i - (N - 1) / 2.);
		break;
	case nsl_sf_window_triangleII:
		for (i = 0; i < N; i++)
			data[i] = 1.0 - 2. / (N - 1) * fabs(i - (N - 1) / 2.);
		break;
	case nsl_sf_window_triangleIII:
		for (i = 0; i < N; i++)
			data[i] = 1.0 - 2. / (N + 1) * fabs(i - (N - 1) / 2.);
		break;
	case nsl_sf_window_welch:
		for (i = 0; i < N; i++)
			data[i] = 1.0 - gsl_pow_2(2 * (i - (N - 1) / 2.) / (N + 1));
		break;
	case nsl_sf_window_hann:
		for (i = 0; i < N; i++)
			data[i] = 0.5 * (1. - cos(2. * M_PI * i / (N - 1)));
		break;
	case nsl_sf_window_hamming:
		for (i = 0; i < N; i++)
			data[i] = 0.54 - 0.46 * cos(2. * M_PI * i / (N - 1));
		break;
	case nsl_sf_window_blackman:
		for (i = 0; i < N; i++)
			data[i] = 0.42 - 0.5 * cos(2. * M_PI * i / (N - 1)) + 0.08 * cos(4. * M_PI * i / (N - 1));
		break;
	case nsl_sf_window_nuttall:
		for (i = 0; i < N; i++)
			data[i] = 0.355768 - 0.487396 * cos(2. * M_PI * i / (N - 1)) + 0.144232 * cos(4. * M_PI * i / (N - 1)) - 0.012604 * cos(6. * M_PI * i / (N - 1));
		break;
	case nsl_sf_window_blackman_nuttall:
		for (i = 0; i < N; i++)
			data[i] =
				0.3635819 - 0.4891775 * cos(2. * M_PI * i / (N - 1)) + 0.1365995 * cos(4. * M_PI * i / (N - 1)) - 0.0106411 * cos(6. * M_PI * i / (N - 1));
		break;
	case nsl_sf_window_blackman_harris:
		for (i = 0; i < N; i++)
			data[i] = 0.35875 - 0.48829 * cos(2. * M_PI * i / (N - 1)) + 0.14128 * cos(4. * M_PI * i / (N - 1)) - 0.01168 * cos(6. * M_PI * i / (N - 1));
		break;
	case nsl_sf_window_flat_top:
		for (i = 0; i < N; i++)
			data[i] = 1 - 1.93 * cos(2. * M_PI * i / (N - 1)) + 1.29 * cos(4. * M_PI * i / (N - 1)) - 0.388 * cos(6. * M_PI * i / (N - 1))
				+ 0.028 * cos(8. * M_PI * i / (N - 1));
		break;
	case nsl_sf_window_cosine:
		for (i = 0; i < N; i++)
			data[i] = sin(M_PI * i / (N - 1));
		break;
	case nsl_sf_window_bartlett_hann:
		for (i = 0; i < N; i++)
			data[i] = 0.62 - 0.48 * fabs(i / (double)(N - 1) - 0.5) - 0.38 * cos(2. * M_PI * i / (N - 1));
		break;
	case nsl_sf_window_lanczos:
		for (i = 0; i < N; i++)
			data[i] = gsl_sf_sinc(2. * i / (N - 1) - 1.);
		break;
	}

	return 0;
}
