/*
 * 	FuzzyRule.h
 *
 * 	This class is used to stock FuzzyRule.
 *
 *	Date 20/01/06
 *
 *	Copyright Piquier Production
 *
 *	Author : Dave Studio
 *
 */

#include "FuzzyRule.h"

using namespace std;


FuzzyRule::FuzzyRule(void){
	result = FuzzyValue(VALUE_EMPTY, -1);
}

FuzzyRule::FuzzyRule(FuzzyValue* fuzzyValueData, Operator* ope, FuzzyValue* result){
	listFuzzyValues = vector<FuzzyValue*>();
	listOperators = vector<Operator*>();
	listFuzzyValues.push_back(fuzzyValueData);
	listFuzzyValues.push_back(result);
	listOperators.push_back(ope);
	int size = listFuzzyValues.size();
	this->result = *listFuzzyValues.at(size - 1);
}

FuzzyRule::FuzzyRule(FuzzyValue* fuzzyValueData1, Operator* ope1,
					 FuzzyValue* fuzzyValueData2, Operator* ope2, 
					 FuzzyValue* result){
	listFuzzyValues = vector<FuzzyValue*>();
	listOperators = vector<Operator*>();
	listFuzzyValues.push_back(fuzzyValueData1);
	listFuzzyValues.push_back(fuzzyValueData2);
	listFuzzyValues.push_back(result);
	listOperators.push_back(ope1);
	listOperators.push_back(ope2);
	int size = listFuzzyValues.size();
	this->result = *listFuzzyValues.at(size - 1);
}

FuzzyRule::FuzzyRule(FuzzyValue* fuzzyValueData1, Operator* ope1,
					 FuzzyValue* fuzzyValueData2, Operator* ope2, 
					 FuzzyValue* fuzzyValueData3, Operator* ope3, 
					 FuzzyValue* result){
	listFuzzyValues = vector<FuzzyValue*>();
	listOperators = vector<Operator*>();
	listFuzzyValues.push_back(fuzzyValueData1);
	listFuzzyValues.push_back(fuzzyValueData2);
	listFuzzyValues.push_back(fuzzyValueData3);
	listFuzzyValues.push_back(result);
	listOperators.push_back(ope1);
	listOperators.push_back(ope2);
	listOperators.push_back(ope3);
	int size = listFuzzyValues.size();
	this->result = *listFuzzyValues.at(size - 1);
}

FuzzyRule::FuzzyRule(std::vector<FuzzyValue*>* lfv, std::vector<Operator*>* lo){
	listFuzzyValues = *lfv;
	listOperators = *lo;
	int size = listFuzzyValues.size();
	this->result = *listFuzzyValues.at(size - 1);
}

FuzzyValue FuzzyRule::getResult(){
	return result;
}

void FuzzyRule::evaluate() {
	int size = listOperators.size();
	result = *(listFuzzyValues.at(0));
	for(int i=0; i<size; i++){
		result = listOperators.at(i)->operate(&result, 
			                                  listFuzzyValues.at(i+1));
	}
}


string FuzzyRule::toString(){
	string thisRule = "";
	int size = listOperators.size();
	for(int i=0; i<size; i++){
		thisRule = thisRule 
				 + Converter::convert(listFuzzyValues.at(i)->getName())
				 + "(" 
				 + Converter::floatToString(listFuzzyValues.at(i)->getValue())
				 + ")" 
				 + " " 
				 + listOperators.at(i)->toString()
				 + " ";
	}
	thisRule = thisRule
		       + Converter::convert(listFuzzyValues.at(size)->getName())
			   + "(" 
			   + Converter::floatToString(result.getValue())
			   + ")";
	return thisRule;
}

void FuzzyRule::update() {
	int size = listFuzzyValues.size();
	for(int i=0; i < size-1; i++){
		listFuzzyValues.at(i)->update();
	}
}

FuzzyRule::~FuzzyRule(void){
}
