#ifndef ORIENTAMENTO_H_DEFINED
#define ORIENTAMENTO_H_DEFINED

using namespace std;

#include <OPENR/OObject.h>
#include <OPENR/OSubject.h>
#include <OPENR/OObserver.h>
#include <OPENR/ODataFormats.h>
#include <OPENR/OFbkImage.h>
#include "../Ocipitale/OccipitalInfo.h"

class Orientamento : public OObject {
public:
    Orientamento();
    virtual ~Orientamento() {}

    OSubject*  subject[numOfSubject];
    OObserver* observer[numOfObserver];
    

    /** Invocata al ricevimento di un messaggio di locazione da parte
	di Ocipital.*/
    void ObjectLocation(const ONotifyEvent& event);

    /** Timer utilizzato per la gestione dell'allineamento del corpo
	con la palla.*/
    void TimerEnd(void* msg);
    
    void TimerWalk(void* msg);  //usato per stoppare la camminata
    
    void TimerDist(void* msg);  //usato per il polling da sensore


    virtual OStatus DoInit   (const OSystemEvent& event);
    virtual OStatus DoStart  (const OSystemEvent& event);
    virtual OStatus DoStop   (const OSystemEvent& event);
    virtual OStatus DoDestroy(const OSystemEvent& event);

 private:
    /** Gestisce i cambiamenti di stato di orientamento.*/
    void manageState();
    
    /** Il valore dell'ora del marker rosso */
    double RedMarkerHour;		// Posizione in ore del marker rosso trovato
    int    TimerDuration;		// Durata dell'operazione di movimento
    double AcceptHourVal;		// Range in ore per considerarsi allineato al Dosso
    double AlignmentHour;		// Posizione del Dosso in ore
    bool   AlignmentFlag;		// Semaforo necessario per allineamento e ricerca GIALLO
    int    ForceScanFlag;		// Flag per forzare lo HEAD_SCAN_BALL_NEAR
    bool   onBump;			// Flag che segnala lo stato sopra il dosso
    bool   GG;
    
    /** 
    *** Procedure di movimento per l'Aibo;
    *** la prima fa muovere il cane in avanti usando come angolo di rotazione RedMarkerHour 
    *** la seconda fa muove il cane sul lato (asse y) 
    ***/
    void MoveAhead();
    void MoveSide();

 private:
    enum
      {
	IDLE, /**< Non far nulla */
	CHECK, /**< Controllo.*/
	GIALLO,
	BLU,
	ROSSO,
	VERDE,
      }mState;
    
    double derPlus;
    double derMinus;
    
    OccipitalInfo::ObjLocation* locationInfo;


    OSensorValue sensorValue;	//valore sensore infrarossi

    OPrimitiveID sensorID;      //ID del sensore della distanza


    static const slongword DMIN = 180000;     //distanza minima per il controllo distanza dal goal (espresso in micrometri)

    bool testTimer;


};

#endif 
