#ifndef LOGICA_ROBOT_H
#define LOGICA_ROBOT_H

#include <math.h>
#include <stdlib.h>
#include "cua.h"
#include "Parcela_Mart.h"
#include "Simulador_Mart.h"
#include "Tipus_Globals.h"
#include <ptypes.h>
#include <ptime.h>
#include <pasync.h>
#include <vector>

#define PERIODE_CONTROL_TEMPERATURA 2000
#define PERIODE_CONTROL_BATERIA 2000

USING_PTYPES

// Casse Logica_Robot: Classe que simula la part operativa del robot. 
class Logica_Robot
{
   private:
      // Dades i / o classes de la logica del robot.
      // Dades del robot incorporades en camps o en una classe apart:
      // (nivell bateria; x,y,z,angleOrientacio i angleAltura actuals;
      // i altres dades que siguin necessaries (p. ex. distancia total
      // recorreguda, si s'escau)
      
      #define PendentMaxima 45             // 30 graus en radiants.
      #define PI            3.141592654    // valor de PI.
      #define AlsadaCap     2              // alsada en centimetres.
      #define AlsadaRod     1            // Alsada en centimetres
      
      #define Robot_A       2.0            // distancia en cm.
      #define Robot_F       2.0            // distancia en cm.
      
      #define distPancam     0.6           // distancia en cm.
      #define distNavcam     0.9           // distancia en cm.
      #define distNavPan     0.4           // distancia en cm.
      
      #define OberturaHazcam 120           // angle obertura camara Hazcam
      #define Hazcam_H       1.0           // distancia en cm.
      #define Hazcam_F       1.0           // distancia en cm.
      
      #define ProfPlanif     10        // profunditat de planificaciķ de traj.
      
      std::vector<TPosicio> pos_visitades;  // llista de posicions visitades

      float Rcoord_x;     // Posiciķ en x del robot.
      float Rcoord_y;     // Posiciķ en y del robot.
      float Rcoord_z;     // Posiciķ en z del robot.   

      int Rorientacio;  // Orientaciķ del robot.
      int Rhoritzo;     // Inclinacio sobre l'horitzo.  
        
      int Radiadors;    // valor de funcionament 0..1
      int Escalfadors;  // valor de funcionament 0..1
      int NivellBateria;// valor de funcionament 0..100
      int DegradaBat;   // La bateria es degrada amb el pas dels dies,
                        // disminuint en aquest valor el maxim nivell
                        
      int Moviment;     // determina si el robot estā o no en moviment '0'/'1'.
        
      int Cap_H;        // Posiciķ horitzontal (angle 0..360) del cap del robot.
      int Cap_V;        // Posiciķ vertical (angle 90..-90) del cap del robot.
      
      // comprova si el punt es troba dins l'ārea de visiķ.
      int puntValid(int x, int z, int i, int j, int orientacio);
      
      // Retorna una llista amb possibles veins del punt (x,y,z).
      void CalcularVeins(int x, float y, int z, int orientacio, cua *veins);
               
    public:
      Logica_Robot();
      ~Logica_Robot();
          
      // Metodes de consulta i establiment de les dades del robot
      // Metodes de moviment del robot
      // Es reben les crides de Comunicacio_Robot, i des de la logica
      // del robot es cridara a metodes del simulador quan es requereixi
      // informacio del mapa.

      // Retorna llista caselles a recorre.
      int calcular_seguent_posicio(cua *resultat);
      
      // Estableix la posiciķ on es troba el robot.
      void set_posicio_actual(struct TPosicio *posicio_actual);

      // Retorna la posiciķ on es troba el robot.
      void get_posicio_actual(struct TPosicio *posicio_actual);

      // retorna l'estat de cārrega de la bateria.
      int get_nivell_bateria();

      // Permet modificar l'orientaciķ del robot.
      void girar_robot(int graus);

      // Permet posicionar el cap del robot segons els angles de gir vertical
      // i horitzontal. En cas de no poder assolir la posiciķ dessitjada re- 
      // torna -1.
      //int posicionar_cap(int Pos_H, int Pos_V);        
      int posicionar_cap(int Pos_H);

      // Metode per llegir la posiciķ de una camara.
      int get_posicio_camera(int numCam, struct TPosicio *posicio_actual);  
                 
      // Permet consultar si el robot es troba en moviment, retorna 0 o 1.
      int get_moviment();

      // Activa el moviment del robot.
      void activar_moviment();

      // Desactiva el moviment del robot.
      void desactivar_moviment();
        
      void activar_radiadors();   
      void activar_escalfadors();  
      
      void desactivar_radiadors();   
      void desactivar_escalfadors(); 
      
      int radiadors_activats();
      int escalfadors_activats();
      
      int get_DegradaBat();
      void set_DegradaBat(int valor);
      
      int get_NivellBateria();
      void set_NivellBateria(int valor);
      
      void esborrar_posicions();
      
      // Resta pendent decidir format de l'imatge.        
      //int capturar_fotos(int numCam); (EN PRINCIPI NO HO FAREM DES DE AQUI)
                  
};

//*****************************************************************************
// Classe Thread_Moviment_Robot: Gestiona la simulacciķ del moviment del robot.
//*****************************************************************************
class Thread_Moviment_Robot : public thread
{
   protected:
      Logica_Robot *probot;
      virtual void execute();
      
   public:    
      Thread_Moviment_Robot(Logica_Robot *Robot) : thread(true), probot(Robot) {}
      ~Thread_Moviment_Robot() { }
};

//*****************************************************************************
// Classe Thread_Control_Termic: Gestiona la temperatura del robot interactuant
// tant amb el simulador de Mart com amb el robot.
//*****************************************************************************
class Thread_Control_Termic : public thread
{
   protected:
      Logica_Robot *probot;
      virtual void execute();
   public:
      Thread_Control_Termic(Logica_Robot *Robot) : thread(false), probot(Robot) {}
      ~Thread_Control_Termic() { }
};

//*****************************************************************************
// Classe Thread_Control_Bateries: Gestiona la cārrega de les bateries del 
// robot.
//*****************************************************************************
class Thread_Control_Bateries : public thread
{
   protected:
      Logica_Robot *probot;
      virtual void execute();
   public:
      Thread_Control_Bateries(Logica_Robot *Robot) : thread(false), probot(Robot) {}
      ~Thread_Control_Bateries() { }
};

#endif
