//
// CGeneration.h
//

#include "interface.h"
#include "CString.h"
#include <stdlib.h>
#include <time.h>
#include "parser.h"

#ifdef graphicOut
  #include <qtextedit.h>
  #include <qlineedit.h>
  #include "PaintPane.h"
#endif

#ifdef consoleOut
  #include <iostream>
  using namespace std;
#endif

#ifndef _CGeneration_
  #define _CGeneration_

class CGeneration
{
  public:

  CGeneration(InnerForm * inner, int numgen, int numElite, int generationsCount, int fitnessSelected, int maxGenBestSolutionUnchanged);
  ~CGeneration();

  CString* binarySearch(double val);

  void fillRandom();

  void selection(int method, int parameter);
  void selectionRoulette(void);
  void selectionTournament(int number);
  void selectionRandom(void);

  void crossover(double crossoverProbability, int method);
  void crossoverSimple(CString& first, CString& second, CString& tmp);
  void crossoverTwoPoint(CString& first, CString& second, CString& tmp);
  void crossoverUniform(CString& first, CString& second, CString& tmp);
  void crossoverImprovement(CString& first, CString& second, CString& tmp);

  void mutation(double mutationProbability);
  #ifdef consoleOut
  void printGeneration(CString** co);
  #endif
  void eliteRoulette();
  void evolution(double crossoverProbability, double mutationProbability, int selectionMethod, int crossoverMethod, int tournamentSize=2);

  void statistics(int& solutionFound, int& solutionIndex);
  int random(int max);

  #ifdef consoleOut
  friend ostream& operator<<(ostream& out, const CGeneration& cgen);
  #endif

  #ifdef graphicOut
  void setQMessage(QTextEdit *messageedit, QLineEdit *lineEdit9);
  void setPaintPane(PaintPane *paintPane);
  #endif

  int getBestValue();
  int getGenerationsEvolved();

  protected:

  int numElite; //pocet jedincu, kteri prejdou do dalsi generace bez krizeni
  int numGen; //pocet jedincu v generaci
  int strlen; //delka geneticke informace jednoho jedince
  int fitnessSelected; //ktera z mnoha moznych fitness funkci byla vybrana
  int generationsCount; //pocet generaci, dokud se ma algoritmus provadet
  CString **generation; //vlastni generace
  CString **tempGen; //docasna generace

  double *probability; //tabulka pravdepodobnosti pro ruletu
  InnerForm * inner; //ukazatel na objekt reprezentujici vnitrni formu zadane klauzule

  int bestValue;    //nejlepsi hodnota v dane populaci
  int worstValue;   //nejhorsi hodnota v dane populaci
  int averageValue; //prumerna hodnota v dane populaci
  int generationsEvolved; //pocet vyvinutych generaci, nez nalezeno reseni

  int *varImpTable; //alokovane pole pro metodu Improvement
  int maxGenBestSolutionUnchanged; //ukonci prohledavani, pokud po dany pocet generaci nedojde ke zmene nejlepsiho reseni

  int sumOfWeights; //celkovy soucet vah vsech promennych

  #ifdef graphicOut
  QTextEdit *messageEdit;
  QLineEdit* lineEdit9;
  PaintPane *paintPane;
  #endif

};

#endif
