//###################################################################################
//#						                  Definition Of Class Epoc								            #
//#						          Used To Handle an Emotiv EPOC headset                       #
//#						                          Author : 							                      #
//#						                      Aymeric SUTEAU									                #
//#						                       LISA - ANGERS									                #
//###################################################################################


// Emotiv Development Kit includes
#include "..\edk\edk.h"
#include "..\edk\edkErrorCode.h"
#include "..\edk\EmoStateDLL.h"

// Other includes
#include <stdio.h>
#include <conio.h>
#include <list>

// Thread includes
#include "..\lib\ou_thread.h"

// Profile handler
#include "Profile.h"

// Used namespaces
using namespace openutils;

// Class definition
class MyThread;
class Epoc : public Thread 
{
  public:
    Epoc();
    ~Epoc();
    bool Connect();
    bool Disconnect();
    void ReadData();

    // Handle new events related to Headset setup and Expressiv / Affective / Cognitive suite
    void HandleHeadsetSetupEvent(EmoStateHandle);
    void HandleExpressivSuiteEvent(EmoStateHandle);
    void HandleAffectiveSuiteEvent(EmoStateHandle);
    void HandleCognitivSuiteEvent(EmoStateHandle);

    // Handle new events related to Expressiv and Cognitiv training actions
    void HandleExpressivTrainingEvent(EmoEngineEventHandle);
    void HandleCognitivTrainingEvent(EmoEngineEventHandle);
    bool StartExpressivSuiteTraining(EE_ExpressivAlgo_t);
    bool StartCognitivSuiteTraining(EE_CognitivAction_t);
    bool EraseExpressivSuiteTraining(EE_ExpressivAlgo_t);
    bool EraseCognitivSuiteTraining(EE_CognitivAction_t);

    // Getters and setters
    unsigned int GetUserID();
    float GetSystemUpTime();                        // Related to "Headset Setup"
    int GetDongleStatus();
    int GetHeadsetStatus();
    float GetWirelessSignal();
    float GetBatteryPower();
    float GetEngagementBoredom();                   // Related to "Affectiv Suite"
    float GetFrustration();
    float GetMeditation();
    float GetInstantaneousExcitement();
    float GetLongTermExcitement();
    unsigned int GetEyeExpressionType();            // Related to "Expressiv Suite"
    unsigned int GetUpperFaceExpressionType();
    unsigned int GetLowerFaceExpressionType();
    float GetUpperFaceExpressionPower();
    float GetLowerFaceExpressionPower();
    unsigned int GetActionType();                   // Related to "Cognitiv Suite"
    float GetActionPower();

    void SetUserID(unsigned int);
    void SetSystemUpTime(float);                    // Related to "Headset Setup"
    void SetDongleStatus(int);
    void SetHeadsetStatus(int);
    void SetWirelessSignal(float);
    void SetBatteryPower();
    void SetEngagementBoredom(float);               // Related to "Affectiv Suite"
    void SetFrustration(float);
    void SetMeditation(float);
    void SetInstantaneousExcitement(float);
    void SetLongTermExcitement(float);
    void SetEyeExpressionType(unsigned int);        // Related to "Expressiv Suite"
    void SetUpperFaceExpressionType(unsigned int);
    void SetLowerFaceExpressionType(unsigned int);
    void SetUpperFaceExpressionPower(float);
    void SetLowerFaceExpressionPower(float);
    void SetActionType(unsigned int);               // Related to "Cognitiv Suite"
    void SetActionPower(float);

    // Handle user profiles
    void SetUserProfileFileName(char*);
    char* GetUserProfileFileName();
    bool GetProfileLoadingDone();
    bool GetProfileSavingDone();
    void SetProfileLoadingDone(bool);
    void SetProfileSavingDone(bool);
    bool ProfileToByteArray(EmoEngineEventHandle, unsigned char**, unsigned int*);    // Get profile byte stream
    bool LoadProfile(char*);          // Load profile from file
    void SaveProfile(char*);          // Save profile to file

    // Handle headset gyro position
    bool UpdateGyroPosition();
    float GetGyroX();
    float GetGyroY();
    void SetGyroX(float);
    void SetGyroY(float);

    // Attributes
    int* iContactQuality;   // Contact quality for the 16 pads of the headset (0 = NO SIGNAL to 4 = GOOD)
    float fEEGData[14];     // Raw EEG data

    // Thread Handling
    void run();
    bool bIsRunning;

  private:
    EmoEngineEventHandle eEvent;
    EmoEngineEventHandle eProfile;
	  EmoStateHandle eState;
    unsigned int uUserID;
    bool bStatus;

    // Attributes related to "Headset Setup"
    float fSystemUpTime;
    int iDongleStatus;
    int iHeadsetStatus;
    float fWirelessSignal;
    float fBatteryPower;

    // Attributes related to "Affectiv Suite"
    float fEngagementBoredom;
    float fFrustration;
    float fMeditation;
    float fInstantaneousExcitement;
    float fLongTermExcitement;

    // Attributes related to "Expressiv Suite"
    unsigned int uEyeExpressionType;
    unsigned int uUpperFaceExpressionType;
    unsigned int uLowerFaceExpressionType;
    float fUpperFaceExpressionPower;
    float fLowerFaceExpressionPower;
    
    // Attributes related to "Cognitiv Suite"
    unsigned int uActionType;
    float fActionPower;    

    // Gyro position
    float fXGyro;
    float fYGyro;

    // User profiles
    char* cUserProfileFileName;   // User profile filename
    bool bLoadProfileDone;        // Status of user profile loading
    bool bSaveProfileDone;        // Status of user profile saving

    // Raw EEG data acquisition
	  bool readyToCollect;
};
