#include "giant.h"

Giant::Giant(uint16_t &_pocetOnu, int16_t _pocetAllocId)
{
	std::map<double, uint16_t> statistikyGrantu;
	for (int i = 0; i < _pocetOnu*_pocetAllocId; i++) {
		casGenerovaniGrantuGiant.push_back(statistikyGrantu);
		Si.push_back(0);
	}	
	PIR = (uint32_t)150;
	GIR = (uint32_t)120;
	PBS = (uint32_t)150;
	GBS = (uint32_t)120;
	SiMax = (uint32_t)1;
	SiMin = (uint32_t)2 * SiMax;
	pocetAllocId = _pocetAllocId;
	pocetOnu = _pocetOnu;
}

std::vector<AllocStruc> Giant::generujBwmapu(double _cas, std::vector<uint32_t> _obsazenostFrontOnu, std::vector<uint8_t>* _dbruNastaveno) {	
	bool assuredRound = true;
	uint32_t nasledujiciStartTime = 0;
	uint32_t volneGranty = 9719;
	uint32_t grantSize = 0;
	uint8_t Flags = 1;
	std::vector<AllocStruc> bwMap;

	for (int i = 0; i < pocetOnu*pocetAllocId; i++) {		
		alokovaneGranty.push_back((uint16_t)0);
	}

	for (uint16_t o = 0; o < pocetOnu; o++) {
		if (volneGranty <= 0)
			break;
		for (uint16_t k = 0; k < 4; k++) {
			if (volneGranty <= 0)
				break;
			grantSize = 0;
			if (Si[(o*pocetAllocId) + k] == 0) {
				if (k == 0)
				{
					grantSize = PIR*SiMax;
				}
				else if (k == 1) {
					if (PIR < _obsazenostFrontOnu[(o*pocetAllocId) + k])
						grantSize = PIR*SiMax;
					else
						grantSize = _obsazenostFrontOnu[(o*pocetAllocId) + k] * SiMax;
				}else if (k == 2) {
					if (GIR < _obsazenostFrontOnu[(o*pocetAllocId) + k])
						grantSize = GIR*SiMax;
					else
						grantSize = _obsazenostFrontOnu[(o*pocetAllocId) + k] * SiMax;

					if (grantSize > GBS)
						grantSize = GBS;
				}
				else if (k == 3)
					grantSize = 1; //délka DBRu					

				if (grantSize == 0 && volneGranty > 0)
					grantSize = 1;

				if (grantSize > volneGranty && grantSize>0)
					grantSize = volneGranty;

				
				volneGranty -= grantSize;
				alokovaneGranty[(o*pocetAllocId) + k] = grantSize;
			}
		}
	}
	for (uint16_t o = 0; o < pocetOnu; o++) {
		if (volneGranty <= 0)
			break;
		for (uint16_t k = 2; k < 4; k++) {
			if (volneGranty <= 0)
				break;
			if (k == 2) {
				if (PIR - GIR < _obsazenostFrontOnu[(o*pocetAllocId) + k])
					grantSize = (PIR - GIR)*SiMin;
				else
					grantSize = _obsazenostFrontOnu[(o*pocetAllocId) + k] * SiMin;

				if (grantSize > PBS - GBS)
					grantSize = PBS - GBS;
			}
			else if (k == 3) {
				if (volneGranty < PIR)
					grantSize = volneGranty*SiMax;
				else
					grantSize = PIR*SiMax;

				if (grantSize > PBS)
					grantSize = PBS;
			}
			volneGranty += alokovaneGranty[(o*pocetAllocId) + k];
			volneGranty -= grantSize;
			alokovaneGranty[(o*pocetAllocId) + k] = grantSize;
		}
	}
		for (uint16_t i = 0; i < pocetOnu*pocetAllocId; i++) {
			if (Si[i] == 0) {
				Flags = 1;
				_dbruNastaveno->at(i) = 1;
				AllocStruc aktualneGenerovanaStruktura = AllocStruc(i, Flags, nasledujiciStartTime, alokovaneGranty[i]);
				bwMap.push_back(aktualneGenerovanaStruktura);
				nasledujiciStartTime += alokovaneGranty[i];
				Si[i] = SiMax;
				casGenerovaniGrantuGiant[i].insert(std::make_pair(_cas, alokovaneGranty[i]));
			}
			else
				Si[i] -= 1;
		}	
	return bwMap;
}	

Giant::Giant() {
}

Giant::~Giant()
{
}

void Giant::vygenerujStatistikyBwMap() {
	for (uint16_t i=0; i < casGenerovaniGrantuGiant.size(); i++) {
		std::map<double, uint16_t>::iterator it = casGenerovaniGrantuGiant[i].begin();

		std::stringstream cestaSouboru;
		cestaSouboru << "BwMapProAllocId" << i << ".txt";
		
		std::ofstream myfile;
		myfile.open(cestaSouboru.str(), std::ofstream::out);
		if (myfile.is_open())
		{
			myfile << "casOdeslani granty\n";
			while (it != casGenerovaniGrantuGiant[i].end())
			{			

				myfile << it->first << " " << it->second << "\n";
				it++;
			}			
		}
		else std::cout << "Soubor nelze otevrit!";
		myfile.close();
	}	
}
