#include <iostream>
#include <vector>
#include "bcap.h"
using namespace std;

BottleCap::BottleCap(int codelength, int nchars, vector <int> rw)
{
  // Copy arguments to private data.

  length = codelength;
  numchars = nchars;
  rewards = rw;

  // Do error checking 

  if (length <= 0) {
    cout << "BottleCap constructor - bad length\n";
    exit(1);
  }
  if (nchars <= 0) {
    cout << "BottleCap constructor - bad nchars\n";
    exit(1);
  }
  if (rw.size() != nchars) {
    cout << "BottleCap constructor - Rewards vector is not the proper size.\n";
    exit(1);
  }

}
  
int BottleCap::EvalFxn(string code)
{
  int i;
  const char *s;
  int c;

  // Calculate the function of the code and return it.

  s = code.c_str();
  c = 0;
  for (i = 0; i < code.length(); i++) {
    c += ((i+1) * (s[i] - 'A'));
  }
  c = (c % numchars);
  return c;
}

int BottleCap::Evaluate(string code)
{
  int c;
  int i;
  const char *s;

  // Do error checking first.

  if (code.length() != length) return -1;
  s = code.c_str();
  
  for (i = 0; i < code.length(); i++) {
    if (s[i] - 'A' < 0 || s[i] - 'A' >= numchars) return -1;
  }

  // Otherwise, use EvalFxn() to calculate the function, and 
  // the rewards vector to define how much the code is worth.

  return rewards[EvalFxn(code)];
}

string BottleCap::Generate(int value)
{
  char *s;
  int i;
  string str;

  // Error check

  if (value < 0 || value >= numchars) {
    cout << "Bad call to Generate().\n";
    exit(1);
  }

  // Allocate a string. 

  s = new char[length+1];

  // Randomly create the string, and return it when 
  // it has the proper value.

  while (1) {
    for (i = 0; i < length; i++) s[i] = 'A' + rand()%numchars;
    s[length] = '\0';
    if (EvalFxn(s) == value) {
      str = s;
      delete s;
      return str;
    }
  }
}

