#include "generic_individual.h"
#include "generic_fitness.h"

/**
 * sets up a table of available cell rules
 */
int generic_fitness::read_rule_table(int *p_rules, int p_size) {
  // check the parameters
  if((p_rules == 0) || (p_size < 1)) return 0;

  // set the block variables
  block_variants = p_size;
  int max_num = block_variants - 1;
  int bits = 0;

  while(max_num > 0) {
    max_num /= GENE_COUNT;
    bits++;
  }

  block_bitsize = bits;

  // free the table if it already exists
  if(rule_tbl != 0) delete_rule_table();

  // calculate the space needed for a table row
  int rule_bits = 0;

  for(int i = 0; i < p_size; i++) {
    int tmp_rule = p_rules[i];
    int b = 0;

    while(tmp_rule > 0) {
      tmp_rule /= GENE_COUNT;
      b++;
    }

    if(b > rule_bits) rule_bits = b;
  }

  // create the table
  rule_tbl = new GENE * [p_size + 1];

  // copy in the rules
  for(int i = 0; i < p_size; i++) {
    int tmp_rule = p_rules[i];
    rule_tbl[i] = new GENE [rule_bits];
    int j = 0;

    // transcribe the rule into the row
    while((tmp_rule > 0) && (j < rule_bits)) {
      rule_tbl[i][j] = tmp_rule % GENE_COUNT;
      tmp_rule /= GENE_COUNT;
      j++;
    }

    // clean up the rest of the row
    for( ; j < rule_bits; j++)
      rule_tbl[i][j] = 0;
  }

  // secure the end of the table
  rule_tbl[p_size] = 0;

  return p_size;
}

/**
 * deletes the rule table
 */
void generic_fitness::delete_rule_table() {
  if(rule_tbl == 0) return;

  int i = 0;

  while(rule_tbl[i] != 0)
    delete [] rule_tbl[i++];

  delete [] rule_tbl;
  rule_tbl = 0;  
}

