#include "../const.h"

#ifndef AIBO_YES

#include "Init_batch.h"
#include "Init_para.h"
#include "Image.h"
#include "ProcessFace.h"
#include "PrintResults.h"
#include "Blocks.h"
#include "MapOnExpanded.h"
#include "BlockMatching.h"
#include "ProcessExpression.h"
#include "AU.h"
#include "Emotion.h"
#include "Interaction.h"
#include "../Interaction/Init_per_para.h"

#ifdef TIME_REC
#include <time.h>
#endif

int
main(void)
{

    int counter = 0;
    Init_batch ib = Init_batch();
    Init_para parameters = Init_para();
    Init_per_para per_parameters = Init_per_para();

    int eyes_status;
    bool result;
    Image im_cr, im_cb, im_clust, im_expanded, 
          im_expr_clust, im_expression, im_expr_cb, im_expr_cr,
          mouth, eye_left, eye_right, mouth_exp, eye_left_exp,
          eye_right_exp, eyebrow_left, eyebrow_right;

    int* face_centroid;
    int* face_bb;
    int* rec_aus;

    Block* blocks;
    Emotion emotion;

    Personality per;

    #ifdef TIME_REC
    clock_t startUTime;
    time_t startRTime;
    double clocks_per_second = (double) CLOCKS_PER_SEC;
    double elapsedR;
    double elapsedU;
    #endif


    result = InitPersonality(per, per_parameters);
    if (!result)
        PRN(("Could not load AIBO's personality.\n"));
    else {

         while (counter < ib.num_files) {
                                         	
                // Initialization: setting pointers to NULL value
                face_centroid = face_bb = rec_aus = NULL;
                blocks = NULL;

                #ifdef TIME_REC
                       startUTime = clock();
                       startRTime = time(NULL);
                #endif
                                                                    // Reading Images
                im_cr         = Image(ib.filenameCr[counter], WIDTH_M, HEIGHT_M);
                im_cb         = Image(ib.filenameCb[counter], WIDTH_M, HEIGHT_M);
                im_clust      = Image(ib.filenameClust[counter], WIDTH_M, HEIGHT_M);
                im_expanded   = Image(ib.filenameExpanded[counter], WIDTH_EH, HEIGHT_EH);
                im_expr_clust = Image(ib.filenameExprClust[counter], WIDTH_M, HEIGHT_M);
                im_expr_cb    = Image(ib.filenameExprCb[counter], WIDTH_M, HEIGHT_M);
                im_expr_cr    = Image(ib.filenameExprCr[counter], WIDTH_M, HEIGHT_M);
                im_expression = Image(ib.filenameExpression[counter], WIDTH_EH, HEIGHT_EH);

                                                                   // Processing Face
                result = ProcessFace(counter, im_cr, im_cb, im_clust, parameters, mouth, eye_left, eye_right, face_bb, face_centroid);
                if (!result) {
                    PRN(("Could not correctly detect your face\n"));
                }
                else {
                                                           // Mapping found features on the expanded image
                    result = ExpandImages(mouth, eye_left, eye_right, mouth_exp, eye_left_exp, eye_right_exp, face_bb);
                    if (!result) {
                        PRN(("Mapping on expanded image failed.\n"));
                    }
                    else {
                                                                   // Getting Eyebrows
                        result = GetBothEyebrows(eye_left_exp, eye_right_exp, face_bb, im_expanded, eyebrow_left, eyebrow_right, parameters, counter);
                        if (!result) {
                            PRN(("Could not correctly detect your face\n"));
                        }
                        else {
                            
                            if (parameters.debug_face)             // Showing results
                               PrintResults(mouth_exp, eye_left_exp, eye_right_exp, eyebrow_left, eyebrow_right, im_expanded, counter);

             
                                                                        // Placing blocks
                            PlaceBlocks(im_expanded, mouth_exp, eyebrow_left, eyebrow_right, face_bb, blocks, parameters, counter);
                            if (!result)
                                PRN(("Could not correctly detect your face\n"));
                            else  {
                                  	
                                  	                                  // Processing Expression
                                result = ProcessExpression(im_expanded, im_expression, im_expr_clust, face_centroid, face_bb, im_expr_cr,
                                                           eye_left, eye_right, im_cr, blocks, eyes_status, parameters, counter);
                                if (!result)
                                   PRN(("Could not process expression.\n"));
      
      
                                else {
                                                                          // AU recognition
                                      result = RecognizeAU(blocks, eyes_status, face_bb, rec_aus, parameters);
                                      if (!result)
                                         PRN(("Could not recognize Action Units.\n"));
                                      else {
                                           	                        // Emotion recognition
                                            result = RecognizeEmotion(rec_aus, emotion, parameters);
                                            if (!result)
                                               PRN(("Could not recognize emotions.\n"));
                                            else {
                                                result = Interact(per, emotion, per_parameters);
                                                if (!result)
                                                   PRN(("Error\n"));
               
          
                                            #ifdef TIME_REC
                                                  elapsedR = difftime(time(NULL), startRTime);
                                                  elapsedU = (clock() - startUTime) / clocks_per_second;
                                  
                                                  PRN(("TIME: %f sec (User Time), %f sec (Real Time)\n", elapsedU, elapsedR));
                                            #endif
                                           }
                                      }
                                }
          
                            }
                        }
                    }
                }
                counter++; 
                
                // freeing memory....
                FreeImg(mouth);
                FreeImg(eye_left);
                FreeImg(eye_right);
                FreeImg(mouth_exp);
                FreeImg(eye_left_exp);
                FreeImg(eye_right_exp);
                FreeImg(eyebrow_left);
                FreeImg(eyebrow_right);
                FreeImg(im_cr);
                FreeImg(im_cb);
                FreeImg(im_clust);
                FreeImg(im_expanded);
                FreeImg(im_expression);
                FreeImg(im_expr_clust);
                FreeImg(im_expr_cb);
                FreeImg(im_expr_cr);
                FreeEmotion(emotion);
                free(face_centroid);
                free(face_bb);
                free(rec_aus);
                free(blocks);
      
      
      
      
      
          }




    }

FreeBatch(ib);
FreePersonality(per);


}

#endif

