#include "rosa/agent/experimental/LinearFunctionBlock.hpp"

LinearFunctionBlock::LinearFunctionBlock() {
	//printf(" > Linear Function Block created\n");
}
/*
LinearFunctionBlock::LinearFunctionBlock(char* name){
	//printf(" > %s (id:%u) created\n", name, id);
}
*/
LinearFunctionBlock::~LinearFunctionBlock() {
	//TODO: delete allocated memory
}

//NOTE: for this time being, linear functions have to be filled beginning from lowest x value 
bool LinearFunctionBlock::addLinearFunction(LinearFunction *linearFunction) {
	if (vLinearFunctions.empty()) {
		//printf("empty\n");
		if (!(linearFunction->getDomain()->lowerBoundaryExist())) {
			vLinearFunctions.push_back(linearFunction);
			//printf(" - added function\n");
			return true;
		}
	}
	else
	{
		//printf("nicht empty\n");
		if (vLinearFunctions.back()->getDomain()->upperBoundaryExist() && linearFunction->getDomain()->lowerBoundaryExist()) {
			//printf("last function ub = %f, new function lb = %f\n", lLinearFunctions.back()->getDomain()->getUpperBoundary(), linearFunction->getDomain()->getLowerBoundary());
			if (vLinearFunctions.back()->getDomain()->getUpperBoundary() == linearFunction->getDomain()->getLowerBoundary()) {
				vLinearFunctions.push_back(linearFunction);
				//printf(" - added function\n");
				return true;
			}
		}
	}

	printf(" - couldn't add function\n");
	return false;
}

//NOTE: Specific Function for CAH Project (DATE18) 
void LinearFunctionBlock::changeFunctionBlockIncr(float newBoundary) {
	vLinearFunctions[1]->setDomain(true, (float)0, true, newBoundary);
	vLinearFunctions[1]->setKandD((float)0, (float)0, newBoundary, (float)1);
	vLinearFunctions[2]->setDomain(true, newBoundary, false);
}

void LinearFunctionBlock::changeFunctionBlockDecr(float newBoundary) {
	vLinearFunctions[1]->setDomain(true, (float)0, true, newBoundary);
	vLinearFunctions[1]->setKandD((float)0, (float)1, newBoundary, (float)0);
	vLinearFunctions[2]->setDomain(true, newBoundary, false);
}



//TODO: jump discontinuity -> user must have the probability to set the value there
float LinearFunctionBlock::getY(float x) {	
	for (auto &linearFunction : vLinearFunctions) {
		if (linearFunction->getDomain()->lowerBoundaryExist() && linearFunction->getDomain()->upperBoundaryExist()) {
			if (x >= linearFunction->getDomain()->getLowerBoundary() && x <= linearFunction->getDomain()->getUpperBoundary()) {
				return linearFunction->getY(x);
			}
		}
		else if (linearFunction->getDomain()->lowerBoundaryExist()) {
			if (x >= linearFunction->getDomain()->getLowerBoundary()) {
				return linearFunction->getY(x);
			}
		}
		else if (linearFunction->getDomain()->upperBoundaryExist()) {
			if (x <= linearFunction->getDomain()->getUpperBoundary()) {
				return linearFunction->getY(x);
			}
		}
		else {
			return linearFunction->getY(x);
		}
	}

	printf("DEFAULT!!!!!!!!!!!\n");
	getchar();
	//TODO: default return value is maybe not the best
	return 0;
}



void LinearFunctionBlock :: printFunctionBlock() {

	/*
	printf("Name: %s", name);

	
	for (auto &lf : vLinearFunctions) {

		float *lowerBoundary;
		float *upperBoundary;

		if (lf->getDomain()->getLowerBoundary(lowerBoundary))
			printf("(x,y) %f, %f - ", lowerBoundary, lf->getY(*lowerBoundary));
		else
			printf("oo - ");

		if (lf->getDomain()->getUpperBoundary(upperBoundary))
			printf("%f, %f", upperBoundary, lf->getY(*upperBoundary));
		else
			printf("oo");

		printf("\n");
	
	}
	*/	

}