#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include "Sequence.h"
#include "DicodonScores.h"

DicodonScores 
createEmptyDicodonScores ()
{
  DicodonScores dicod=DicodonScoresCalloc (1, sizeof (DicodonScoresStruct));
  int i;
  double randProb = 1.0 / 4096;

  dicod->score = DicodonScoresCalloc (4097, sizeof (double));
  dicod->freq = DicodonScoresCalloc (4097, sizeof (double));
  for (i = 0; i < 4096; i++) {
    dicod->freq[i] = randProb;
  }
  dicod->score[4096]=0;
  dicod->minScore = 0;
  dicod->maxScore = 0;
  return dicod;
}

DicodonScores 
loadDicodonScores (FILE *file) 
{
  DicodonScores dicod=DicodonScoresCalloc (1, sizeof (DicodonScoresStruct));
  char dicodonString[7];
  double score, freq;
  int cn1, cn2;


  dicod->minScore=1000;
  dicod->maxScore=-1000;
  dicod->score = DicodonScoresCalloc (4097, sizeof (double));
  dicod->freq = DicodonScoresCalloc (4097, sizeof (double));
  while(!feof(file)) {
    fscanf(file,"%s %le %le\n",dicodonString,&score,&freq);
    cn1=codonNumber(dicodonString);
    cn2=codonNumber(&dicodonString[3]);
    if ((cn1>=0) && (cn2>=0)) {
      dicod->score[(64*cn1)+cn2]=score;
      dicod->freq[(64*cn1)+cn2]=freq;
      if (score>dicod->maxScore) dicod->maxScore=score;
      if (score<dicod->minScore) dicod->minScore=score;
    }
  }
  return dicod;
}

void freeDicodonScores(DicodonScores dicod) {
  free(dicod->score);
  free(dicod->freq);
  free(dicod);
}

int dicodonNum(char *dicodon) {
  int cn1, cn2; 
  
  cn1=codonNumber(dicodon);
  cn2=codonNumber(&dicodon[3]);
  
  if ((cn1>=0) && (cn2>=0)) 
    return 64*cn1+cn2;
  else
    return 4096;
}

double scoreDicodon(char *dicodon, DicodonScores dicod) {
  return dicod->score[dicodonNum(dicodon)];
}

/* wrapper around Calloc to allow error checking */

void *
DicodonScoresCalloc (size_t elements, size_t size)
{
  void *ptr;
  ptr = calloc (elements, size);
  if (ptr == NULL) {
    fprintf (stderr, "cannot allocate memory for DicodonScores\n");
    exit (1);
  }
  else
    return ptr;
}
