#pragma once
#include <iostream>
#include <limits>
#include <math.h>
#include "taos.h"

long* preprocess(double* sciencedata, int xs, int ys, int cosum_frames, int max_pct);
double* cosum(double* data, int limx, int limy, int frames);
double findmax(double* frame, int limx, int limy);

/*
	Devuelve un puntero de tipo long que contiene un frame binarizado con dimenciones X,Y
*/
long* preprocess(double* sciencedata, int xs, int ys, int cosum_frames, int max_pct) {

	double* frame = NULL;
	long* bframe = (long*)calloc(xs * ys, sizeof(long));

	//Cosuma de los primeros X frames. Nos regresa un solo frame con el cual vamos a trabajar.
	frame = cosum(sciencedata, xs, ys, cosum_frames);

	int indx;
	int row;
	int res;
	float logres;

#pragma region logaritmos
	//Aplicamos logaritmo a cada pixel y un multiplicador
	for (int y = 0; y < ys; y++) {
		row = y * xs;
		for (int x = 0; x < xs; x++) {
			indx = x + row;
			if (frame[indx] <= 0) {
				frame[indx] = 0;
			}
			else {
				logres = log10(frame[indx]);
				res = logres + 0.5;
				frame[indx] = res * 10;
			}
		}
	}
#pragma endregion

#pragma region Binarizacion
	//Conseguimos el maximo
	double max = findmax(frame, xs, ys);


	//Binarizamos
	indx = 0;

	float pct = (float)max_pct / 100;
	double threshold = max * pct;
	for (int y = 0; y < ys; y++) {
		row = y * xs;
		for (int x = 0; x < xs; x++) {

			indx = x + row;

			if (frame[indx] >= threshold) {
				bframe[indx] = 1;
			}
			else {
				bframe[indx] = 0;
			}

		}
	}
#pragma endregion

	return bframe;
}

double* cosum(double* data, int limx, int limy, int frames) {

	int indx;
	int rindx;
	double* rdata = (double*)calloc(limx * limy, sizeof(double));

	for (int y = 0; y < limy; y++) {
		for (int x = 0; x < limx; x++) {
			rindx = x + (limx * y);
			for (int fm = 0; fm < frames; fm++) {
				indx = rindx + (fm * limx * limy);
				rdata[rindx] += data[indx];
			}
		}
	}

	return rdata;
}

double findmax(double* frame, int limx, int limy) {

	double max = std::numeric_limits<double>::min();

	int indx = 0;

	for (int y = 0; y < limy; y++) {
		for (int x = 0; x < limx; x++) {

			indx = x + (limx * y);

			if (frame[indx] > max) {
				max = frame[indx];
			}

		}
	}

	return max;
}