#ifndef _TESTING_HELPERS_H
#define _TESTING_HELPERS_H

#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/core/utility.hpp>
#include<opencv2/features2d.hpp>

#include<iostream>
#include<fstream>

#include"Road_segmentation.h"
#include"weather.h"

using namespace RoadStateMonitor;
//using namespace WeatherAnalysis;



/*
zmenšenie obrázka so zachovaním pomeru hrán
*/
cv::Mat resize_image(const cv::Mat& input, float width)
{
	int tmp;

	if (input.rows > input.cols)
		tmp = input.size().height;
	else
		tmp = input.size().width;

	double scale = width / tmp;
	

	cv::Mat resized = input(cv::Rect(0, 0, input.cols, input.rows - 17));
	cv::resize(resized, resized, cv::Size(0, 0), scale, scale);

	//if (crop) resized = resized(cv::Rect(resized.rows / 4, 0, resized.rows, resized.cols));

	cv::GaussianBlur(resized, resized, cv::Size(1, 1), 0);

	return resized;
}


/*
načítanie všetkých obrázkov zo zadaného priečinku
*/
std::vector<cv::Mat> load_images(const std::string& path, std::vector<std::string>& file_names)
{
	cv::glob(path + "*.jpg", file_names, false);

	if(file_names.empty()) cv::glob(path + "*.png", file_names, false);

	std::vector<cv::Mat> images;
	size_t count = file_names.size(); //number of png files in images folder
	for (size_t i = 0; i < count; i++)
		images.push_back(resize_image(cv::imread(file_names[i]), 500));

	return images;
}

/*
Mat preprocessed_image(const Mat& input)
{
	Mat cropped_input;
	cv::resize(input, cropped_input, { 500,500 });
	cropped_input = cropped_input(cv::Rect(0, 0, cropped_input.cols, cropped_input.rows / 2));

	cv::cvtColor(cropped_input, cropped_input, cv::COLOR_BGR2GRAY);

	GaussianBlur(cropped_input, cropped_input, cv::Size(3, 3), 0, 0, cv::BORDER_DEFAULT);

	return cropped_input;
}
*/

/*
metóda na testovanie analýzy stavu vozovky
*/
void test_road_state(const std::vector<std::string>& image_names, const std::vector<cv::Mat>& loaded_images)
{

	if (image_names.empty() ||
		loaded_images.empty() ||
		image_names.size() != loaded_images.size())
	{
		throw std::invalid_argument("Input file corrupted in test_road_state()!\n");
	}

	std::ofstream out_file{ "rychlotest.txt" };
	//std::cout << image_names[0] << std::endl;
	ESegment_method meth = ESegment_method::CANNY;
	CRoad_segmentation ref(loaded_images[0], meth);
	//ref.calculate_histogram();
	ref.draw_image();
	cv::waitKey();
	for (size_t i{ 1 }; i < image_names.size(); ++i)
	{
		//cv::imshow("original", loaded_images[0]);
		//cv::imshow("actual", loaded_images[i]);
		ref.calculate_histogram();
		//ref.draw_image();
		auto start = std::chrono::high_resolution_clock::now();
		CRoad_segmentation act(loaded_images[i], ref.get_indexes());
		act.calculate_histogram();
		//act.draw_image();
		auto stop = std::chrono::high_resolution_clock::now();
		auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start);
		double hist_corell = cv::compareHist(ref.get_histogram(), act.get_histogram(), cv::HISTCMP_CORREL);
		out_file << image_names[i] << "\n" << "Histogram correlation = (" << abs(hist_corell) * 100 << "%)\t" << RoadStateMonitor::precipitation_intensity(ref.get_road(), act.get_road()) << "\tTime = " << duration.count() << "ms \n\n";
		//cv::waitKey();
		//cv::destroyAllWindows();

	}

	out_file.close();
}


/*
metóda na testovanie prítomnosti zrážok
*/
void test_snowing(const std::vector<std::string>& image_names, const std::vector<cv::Mat>& loaded_images)
{
	if (image_names.empty() ||
		loaded_images.empty() ||
		image_names.size() != loaded_images.size())
	{
		throw std::invalid_argument("Input file corrupted in test_road_state()!\n");
	}

	std::ofstream out_file{ "rychlotest.txt" };

	int res_prev = 0, intensity{ -15 };
	for (size_t i{ 1 }; i < image_names.size(); ++i)
	{
		
		auto start = std::chrono::high_resolution_clock::now();

		int res = image_subtraction(loaded_images[i - 1], loaded_images[i]);

		auto stop = std::chrono::high_resolution_clock::now();
		auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start);

		out_file << "Background = " << image_names[i - 1] << "\nAct = " << image_names[i] << "\nPrecipitation actual = " << res << "\tPrecipitation previous = " << res_prev;
		//std::cout << "res = " << res << "\tprev_res = " << res_prev <<"\n";

		

		if (res >= res_prev + 500 )
		{
			intensity = intensity + ((res - res_prev) / 500);
			out_file << " -> Precipitation is increasing\t";
		}
		else if (res <= res_prev - 500)
		{
			intensity = intensity - (( res_prev - res) / 500);
			//if (intensity < 0) intensity = 0;
			out_file << " -> Precipitation is decreasing\t";
		}
		else out_file << " -> Precipitation is the same\t\t\t";

		if (intensity < 0) intensity = 0;

		out_file << "\tIntensity = " << intensity << "\tTime = " << duration.count() << "ms \n\n";
		res_prev = res;

	}
	out_file.close();
}


/*
metóda na testovanie prítomnosti hmly
*/
void test_fog(const std::vector<std::string>& image_names, const std::vector<cv::Mat>& loaded_images)
{

	if (image_names.empty() ||
		loaded_images.empty() ||
		image_names.size() != loaded_images.size())
	{
		throw std::invalid_argument("Input file corrupted in test_road_state()!\n");
	}

	std::ofstream out_file{ "rychlotest.txt" };

	int tresh{};
	EWeather_method method = EWeather_method::CANNY;
	cv::Mat ref_clone = loaded_images[0].clone();
	cv::cvtColor(ref_clone, ref_clone, cv::COLOR_BGR2GRAY);

	cv::Mat cropped = loaded_images[0](cv::Rect(0, 0, loaded_images[0].cols, 10 * loaded_images[0].rows / 100));
	CFog ref(cropped, tresh, method);
	ref.calculate_histogram(ref_clone);
	ref.calculate_contrast(cropped);
	double ref_fft = ref.FFT(cropped);

	out_file << "Ref. image = " << image_names[0] << "\nLow threshold = " << ref.get_high_tresh() / 2 << "\tHigh threshold = " << ref.get_high_tresh() <<
		"\tEdges = " << ref.get_edges() << "\tContrast = " << ref.get_contrast() << "\tFFT = " << ref_fft << "\n";

	for (size_t i{ 1 }; i < image_names.size(); ++i)
	{
		ref_clone = loaded_images[i].clone();
		cv::cvtColor(ref_clone, ref_clone, cv::COLOR_BGR2GRAY);
		//cv::imshow("clone1", ref_clone);
		cropped = loaded_images[i](cv::Rect(0, 0, loaded_images[i].cols, 10 * loaded_images[i].rows / 100/*sunny.rows/4, sunny.cols, 10*sunny.rows/100*/));
		auto start = std::chrono::high_resolution_clock::now();
		CFog act(cropped, ref.get_high_tresh(), method);
		act.calculate_histogram(ref_clone);
		act.calculate_contrast(cropped);
		ref_fft = act.FFT(cropped);
		//act.is_foggy(ref);
		auto stop = std::chrono::high_resolution_clock::now();
		auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start);
		double hist_corell = cv::compareHist(ref.get_histogram(), act.get_histogram(), cv::HISTCMP_CORREL);
		out_file << std::boolalpha << image_names[i] << "\n" << "Histogram correlation = (" << abs(hist_corell) * 100 << "%)\t" << "Foggy = " << act.is_foggy(ref) <<
			"\tEdges = " << act.get_edges() << "\tContrast = " << act.get_contrast() << "\tFFT = " << ref_fft << "\tVisibility = " << act.visibility(ref) << "%\tTime = " << duration.count() << "ms \n\n";

		//cv::waitKey();
		cv::destroyAllWindows();
	}

	out_file.close();
}


#endif