#include "../const.h"
#include "Emotion.h"

#ifdef AIBO_YES
#include <OPENR/OSyslog.h>
#endif


// This functions reads from a .INI file the basic emotions 
// configuration and save them in an appropriate data structure
bool
InitEmotions(Emotion*& em)
{

int i, j, code, au_name;
double points;
char filename[MAX_LENGTH_FILE];
FILE* f;

#ifdef FUNC_TRACK
PRN(("Starting InitEmotions\n"));
#endif

em = (Emotion*) calloc(EM_NUM, sizeof(Emotion));
if (em == NULL)
   return false;

sprintf(filename, "%s%s", INIT_FOLDER, EMO_FILE);
f = fopen(filename, "r+");
if (f == 0) {
   PRN(("can't open %s\n", filename));
   return false;
}

i = 0;
while(fscanf(f, "#EMOTION_CODE %d::%*s\n", &code)) {
   em[i] = Emotion(code);
   j = 0;
   while (fscanf(f, "AU %d::%lf\n", &au_name, &points)) {
       em[i].points[j] = Au_score(au_name, points);
       j++;
   }

   i++;
   fscanf(f, "#####\n");

}

fclose(f);


#ifdef FUNC_TRACK
PRN(("Ending InitEmotions\n"));
#endif

return true;

}

// This function determines which emotion is displayed by the user
// according to which AUs were detected.
bool
RecognizeEmotion(int* rec_aus, Emotion& rec_emo, const Init_para& parameters)
{

int i, j, n, rec_emo_idx;
double max_points;
double* emotion_points;
Emotion* em;


#ifdef FUNC_TRACK
PRN(("Starting RecognizeEmotion\n"));
#endif


// Initializing...
emotion_points = (double*) calloc(EM_NUM + 1, sizeof(double));
if (emotion_points == NULL)
   return false;

if (!InitEmotions(em))
   return false;
   

// Computing scores for each emotion
for (i = 0; i < EM_NUM; i++) {
    for (j = 0; j < AU_NUM; j++) {
        n = 0;
        while (rec_aus[n]) {
              if (rec_aus[n] == em[i].points[j].au_name) {
                 emotion_points[em[i].name] += em[i].points[j].score;
              }
              n++;
        }
    }
}

max_points = 0.0;
for (i = 1; i < EM_NUM + 1; i++)  {
    if (parameters.debug_emo)
       PRN(("Emotion %d: score %lf\n", i, emotion_points[i]));
    if (emotion_points[i] > max_points) {
       max_points = emotion_points[i];
       rec_emo_idx = i;
    }
}


if (emotion_points[rec_emo_idx] > parameters.emo_thres) {
    PRN(("Emotion %d recognized!\n", rec_emo_idx));
}
else {
    PRN(("No emotion was recognized.\n"));
    rec_emo_idx = 0;
}

if (!rec_emo_idx) {
   rec_emo = Emotion(0);
}
else  {
   i = 0;
   while (rec_emo_idx != em[i].name)
         i++;
   CopyEmotion(em[i], rec_emo);
}



// Freeing memory...
free(emotion_points);
for (i = 0; i < EM_NUM; i++)
    FreeEmotion(em[i]);
free(em);

#ifdef FUNC_TRACK
PRN(("Ending RecognizeEmotion\n"));
#endif

return true;

}

// Copying emotion_from to emotion_to
void
CopyEmotion(Emotion& em_from, Emotion& em_to)
{

int i;

em_to = Emotion(em_from.name);
for(i = 0; i < AU_NUM; i++)
      em_to.points[i] = Au_score(em_from.points[i].au_name, em_from.points[i].score);


return;

}


// Freeing Emotion memory...
void
FreeEmotion(Emotion& em)
{

if (em.points != NULL)
   free(em.points);
em.points = NULL;

return;

}

