#pragma interface

#ifndef _incl_hpg
#define _incl_hpg

#include "parameters.h"
#include "module.h"

#include <vector>
#include "indiv.h"

using namespace std;

void error( const char* str1 );
double myrand();


class hpg {

  parameters params;

 public:

  unsigned int kmin,kmax,mmin,mmax, n, level, nextuid, nodims, nosettings, arity;
  bool fixedfitnesscontribution, randomorder;

  vector<vector<module*> > mods;//for each level: collection of modules 
  vector<module*> todo, modules, maxmods;
  vector<int> vals;

  void appendvector(vector<int> &a,vector<int> &b);
  void appendvector(vector<module*> &a,vector<module*> &b);
  void printvector(vector<int> &vals);
  void print_module(module *mod);
  void printvector(vector<module*> &mods);
  void printvector(vector<vector<module*> > &mods);
  void printvector(vector<vector<int> > &vals);

  double fitness(vector<int> &vars);
  bool equals(vector<int> &v1,vector<int> &v2);
  void get_values(vector<int> &vars, vector<int> positions, vector<int> &vals);
  void vectorize(int *values, vector<int> &v, int n);
  void add_options(vector<vector<int> > &options, vector<vector<int> > &vals);
  void assign_fitness();
  void init_prims(); 
  void load_parameters(int argc, char **argv);
  module *create_module();
  void generate_problem();
  void choose_parts(module *mc);
  void use_prev_layer_settings(module *mc, unsigned int m);
  void create_remaining_settings(module *mc, unsigned int m);
  void create_options(vector<vector<int> > &options, module *mc);
  void select_options(vector<vector<int> > &options, module *mc, unsigned int m);
  void initialize(int argc, char **argv);

  void initialize_modules();
  indiv *draw_indiv();

  hpg(int argc, char **argv);

};

#endif

