/*
    Copyright (C) 2012 Bartosz Broda, Jacek Bochenek, Łukasz Biłeńkij, 
    Damian Jaworski, Wojciech Mazur, Dominik Piasecki, Maciej Piasecki, 
    Radosław Ramocki
    
    This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option)
any later version.

    This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. 

    See the LICENSE and COPYING files for more details.
*/

#ifndef WBST_OPTIMIZER_H
#define WBST_OPTIMIZER_H
#include "config.h"
#include "foldinginterface.h"
#include "nfold.h"
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <EALib/ChromosomeT.h>
#include <EALib/PopulationT.h>



class wbst_optimizer
{
public:
	/**
	  * Empty constructor
	  */
	wbst_optimizer();
	~wbst_optimizer();

	/**
	  * Main function responsible for whole process of finding results with brute force search method
	  */
	void startBruteForce();
	/**
	  * Main function responsible for whole process of finding results with genetic algorithm search method
	  */
	void startGenetic();
private:
	/**
	  * Function parsing one of input parameters and creating class  for folds
	  * \returns Pointer to a folding class
	  */
	FoldingInterface* createFoldingClass();
	/**
	  * Function loading questions from WBST file
	  * \param filename Name of file to read
	  * \returns Vector with 1 WBST question in each string
	  */
	std::vector<std::string> loadWBSTFile(std::string filename);

	/**
	  * Function loading WBST functions from file
	  * \param filename File to be loaded
	  * \returns File with all possible functions
	  */
	std::string loadFunctions(std::string filename);
	/**
	  * Function creating WBST file with test based on given parameters
	  * \param WBSTQuestions All read WBST questions
	  * \param filename Name of output file
	  * \param IDVector IDs of questions to be put in output file
	  */
	void createTest(std::vector<std::string> WBSTQuestions,std::string fileName,std::vector<int> IDVector);
	/**
	  * Function evaluating children population on specific WBST test file
	  */
	void evaluatePopulation(std::string foldFileName);
	/**
	  * Function generating another population of children
	  */
	void generateChildren();
	/**
	  * Function initializing base population
	  * \param filename Function file to be parsed
	  */
	void initPopulation(std::string filename);

	/**
	  * Set of function retrieving certain value from specific individual
	  * \param pop Population to extract value from
	  * \param indivNum Number of individual in population
	  * \param chromNum Number of individual's chromosome to extract value from
	  * \param allelNum Number of chromosome's allel with value to be extracted
	  */
	int getIntAllel(Population* pop, size_t indivNum, size_t chromNum, size_t allelNum);
	double getDoubleAllel(Population* pop, size_t indivNum, size_t chromNum, size_t allelNum);
	bool getBoolAllel(Population* pop, size_t indivNum, size_t chromNum, size_t allelNum);

	int getIntAllel(Individual& i, size_t chromNum, size_t allelNum);
	double getDoubleAllel(Individual& i, size_t chromNum, size_t allelNum);
	bool getBoolAllel(Individual& i, size_t chromNum, size_t allelNum);

	std::string indiv2string(Individual& i);

	std::string WBSTFileHeader;
	std::vector<std::string> learningFoldFileNames;
	std::vector<std::vector<int> >testingVector;
	Population* parents;
	Population* children;
	std::vector<std::string> varNamesVector;
	std::vector<std::string> varTypes;
	std::vector<std::vector<std::string>* > varBoundValues;
	std::vector<Chromosome*> parentsChromosomeVector;
	std::vector<Chromosome*> childrenChromosomeVector;
	int populationSize;
	std::string functionName;
};

#endif // WBST_OPTIMIZER_H
