/*
 * Testbench_Config.cpp
 *
 *  Created on: 26.06.2018
 *      Author: edwin
 */

#include "Testbench_Config.h"


vector<Testbench_Config*> Testbench_Config::s_vec_all_created_Configs;
int Testbench_Config::s_counter_of_all_created_configs 	= 0;
int Testbench_Config::s_active_Config 					= 0;

/*
 *
 */
void Testbench_Config::register_Config()
{
	if(s_vec_all_created_Configs.max_size() > s_vec_all_created_Configs.size()){
		s_vec_all_created_Configs.push_back(this);
		this->m_current_index 				= s_counter_of_all_created_configs;
		s_counter_of_all_created_configs 	= s_counter_of_all_created_configs + 1;
	} else {
		cout << "It is not possible to add an Testbench_Config to vector, Testbench_Config not registered" << endl;
	}
}

/*
 *
 */
void Testbench_Config::deregister_Config()
{
	if (!s_vec_all_created_Configs.empty()) {
		int index = 0;
		int old_max_index = 0;
		std::vector<Testbench_Config*>::iterator it = s_vec_all_created_Configs.begin();
		for (; index != this->m_current_index; it++) {
			index = index + 1;
		}
		old_max_index = s_vec_all_created_Configs.size() -1;
		if (index == this->m_current_index) {
			s_vec_all_created_Configs.erase(it);
		}
		if(index < old_max_index) {
			adapt_Indices(index);
		}
		this->m_current_index 				= s_object_is_deleted;
		s_counter_of_all_created_configs 	= s_counter_of_all_created_configs - 1;
	}
}

/*
 *
 */
void Testbench_Config::adapt_Indices(int from_index_to_change)
{
	int index = 0;
	for(index = 0; index < s_vec_all_created_Configs.size(); index++){
		if(index >= from_index_to_change) {
			Testbench_Config* cur_config = s_vec_all_created_Configs[index];
			cur_config->m_current_index = cur_config->m_current_index - 1;
		}
	}

}

Testbench_Config::Testbench_Config()
{
	this->configuration.bound_broken = float(2);
	this->configuration.outter_bound_sim_dif = 0.20;
	this->configuration.inner_bound_sim_dif = 0.01;
	this->configuration.outter_bound_drift = 3 * this->configuration.outter_bound_sim_dif;
	this->configuration.inner_bound_drift = this->configuration.outter_bound_sim_dif;
	this->configuration.length = (float) 10;
	register_Config();
}

/*
 *
 */
Testbench_Config::Testbench_Config(One_Config_t& a_config)
{
	this->configuration = a_config;
	register_Config();
}

/*
 * return the index of the object in the static class vector
 */
int Testbench_Config::get_own_index()
{
	return this->m_current_index;
}

/*
 *
 */
One_Config_t Testbench_Config::get_Config()
{
	if(this != NULL && this->m_current_index != s_object_is_deleted){
		return this->configuration;
	}

}

/*
 *
 */
void Testbench_Config::print()
{
	if(this != NULL && this->m_current_index != s_object_is_deleted) {
	std::cout << "Index of the configuration: " << this->m_current_index;
	std::cout << "The values of the configuration are: ";
	std::cout << "Broken boundary: " << this->configuration.bound_broken << " ";
	std::cout << "Inner boundary similar state: " << this->configuration.inner_bound_sim_dif << " ";
	std::cout << "Outter boundary similar state: " << this->configuration.outter_bound_sim_dif << " ";
	std::cout << "Inner boundary drift: " << this->configuration.inner_bound_drift << " ";
	std::cout << "Outter boundary drift: " << this->configuration.outter_bound_drift << " ";
	std::cout << "Length: " << this->configuration.length << " ";
	std::cout << std::endl;
	}else {
		std::cout << "Object points to NULL" << std::endl;
	}
}

/**
 * returns the index of the active config of the Testbench.
 */
int Testbench_Config::get_active_Config()
{
	return s_active_Config;
}

/**
 * Sets the index for the current config used.
 * @param index value >= 0, -1 = Invalid Index
 *
 */
void Testbench_Config::set_active_Config(const int index)
{
	if(index < s_counter_of_all_created_configs) {
		s_active_Config = index;
	}else {
		s_active_Config = s_INVALID_INDEX;
	}
}


void Testbench_Config::cut_number_of_decimal_digits(std::string & str_number)
{	const std::string 	delimeter = ".";
	const std::string   zero = "0";
	std::string 		str_temp;
	std::size_t 		first_pos;
	std::size_t			length;
	std::size_t			first_not_zero;
	std::size_t			index;
	length = str_number.length();
	first_pos = str_number.find_first_of(delimeter);
	if (first_pos != std::string::npos)
	{
		//0 is the start of the string, add 1 to get also the delimeter into the string
		str_temp =str_number.substr(0, first_pos + 1);
		length = length - first_pos - 1;
		str_number = str_number.substr(first_pos + 1, length);
		first_not_zero = str_number.find_first_not_of(zero);
		if(first_not_zero == std::string::npos)
		{
			str_number = str_temp + str_number[0] + str_number[1];
		}
		else
		{
			for(index = 0; index <= first_not_zero; index++){
				str_temp = str_temp + str_number[index];
			}
			str_number = str_temp;
		}
	}


}

/**
 * returns all parameters of the config as a string.
 * B_b means bound broken border, I_B_d means inner bound drift border
 * O_B_d means outter bound drift border, I_B_s_d means inner bound simular signal border
 * O_B_s_d means outter bound simular signalr border
 */
std::string Testbench_Config::get_Config_as_String()
{ 
	//Ali for file name compatebility in Windows, all ':' chars converted to '-', also blanks removed or changed to '_'    
	std::string config;
	std::string str_part;
	str_part = std::to_string(this->configuration.bound_broken);
	cut_number_of_decimal_digits(str_part);

	config = "_B_b-" + str_part;

	str_part = std::to_string(this->configuration.inner_bound_drift);
	cut_number_of_decimal_digits(str_part);

	config = config + "_I_B_d-"+ str_part;

	str_part = std::to_string(this->configuration.outter_bound_drift);
	cut_number_of_decimal_digits(str_part);

	config = config + "_O_B_d-" + str_part;

	str_part = std::to_string(this->configuration.inner_bound_sim_dif);
	cut_number_of_decimal_digits(str_part);

	config = config + "_I_B_s_d-" + str_part;

	str_part = std::to_string(this->configuration.outter_bound_sim_dif);
	cut_number_of_decimal_digits(str_part);

	config = config + "_O_B_s_d-" + str_part + "";
	config = config + "_Length-" + std::to_string(this->configuration.length) + "";
	return config;
}

/*
 *
 */
Testbench_Config::~Testbench_Config()
{
	deregister_Config();
}
