
#include <iostream>
#include <fstream>
#include "XmlRpc.h"
#include "Flying_Team_Terra.h"
#include "Client_Xmlrpc_Terra.h"
#include "Servidor_Xmlrpc_Terra.h"
#include "Interficie_Terra.h"

//#define NUM_CLIENTS_TERRA 7
#define NUM_CLIENTS_TERRA 1

using namespace XmlRpc;
USING_PTYPES

Thread_Client_Terra *thread_client[NUM_CLIENTS_TERRA];
Thread_Servidor_Terra *thread_servidor;
Thread_Servidor_Imatges *thread_imatges;
//mutex mutex_comunicacio;
extern Comunicacio_Interficie_Grafica *comunicacio_interficie;

Control_Comandament_Terra::Control_Comandament_Terra() {}
Control_Comandament_Terra::~Control_Comandament_Terra() {}

int Control_Comandament_Terra::inicialitzar_Dades(char *ipMarsRover, int portMarsRover, 
                                                  int portNasa, char *nom_fitxer)
{
   ipMart = ipMarsRover;
   portMart = portMarsRover;
   portTerra = portNasa;
   nom_fitxer_informe = nom_fitxer;
   comunicacio_activa = 0;
   fitxer_informe = new std::ofstream(nom_fitxer,std::ios::app|std::ios::out);
   if (!fitxer_informe) {
      return 1;
   }   
   else {
      return 0;
   }   
}

void Control_Comandament_Terra::iniciar_servidor()
{
   thread_servidor = new Thread_Servidor_Terra(portTerra);
   thread_servidor -> start();
   int port_imatge = 10000;
   thread_imatges = new Thread_Servidor_Imatges(port_imatge);
   thread_imatges -> start();
}
 
void Control_Comandament_Terra::activar_Comunicacio_Terra()
{
   XmlRpcClient mart(ipMart,portMart);
   XmlRpcValue resultat;
   comunicacio_activa = 1;
   XmlRpcValue accio;
   accio[0] = "activar";
   if (mart.execute("activacio", accio, resultat))
   {
      std::string strResult = std::string(resultat);
      std::string strOK = "activat";
      if (strResult.compare(strOK) == 0)
      {
         thread_client[0] = new Thread_Client_Terra(ipMart,portMart,"dades_completes");
         for(int i = 0; i < NUM_CLIENTS_TERRA; i++) {
             thread_client[i] -> start();
         }
      }   
      else {
         comunicacio_interficie -> indicar_Operacio_Fallida("activar_comunicacio_terra");
      }   
   }    
}   

void Control_Comandament_Terra::desactivar_Comunicacio_Terra()
{
   std::cout << "DESACTIVAR_COMUNICACIO_TERRA\n";
   //mutex_comunicacio.lock();
   comunicacio_activa = 0;
   //mutex_comunicacio.unlock();
   XmlRpcClient mart(ipMart,portMart);
   XmlRpcValue resultat;
   XmlRpcValue accio;
   std::string cadena = "desactivar";
   accio[0] = cadena;
   bool ok = mart.execute("activacio", accio, resultat);
   if(!ok) {
      comunicacio_interficie -> indicar_Operacio_Fallida("desactivar_comunicacio_terra");
   }   
}   

void Control_Comandament_Terra::iniciar_Moviment_Robot()
{
   XmlRpcClient client(ipMart,portMart);
   XmlRpcValue resultat, param;
   bool ok = client.execute("inici_moviment_robot", param, resultat);
   if (!ok) {
      comunicacio_interficie -> indicar_Operacio_Fallida("inici_moviment_robot");
   }   
}   

void Control_Comandament_Terra::finalitzar_Moviment_Robot()
{
   XmlRpcClient client(ipMart,portMart);
   XmlRpcValue resultat, param;
   bool ok = client.execute("fi_moviment_robot", param, resultat);
   if (!ok) {
      comunicacio_interficie -> indicar_Operacio_Fallida("fi_moviment_robot");
   }     
}   

void Control_Comandament_Terra::canviar_Camara_Activa(int num_camara)
{
   XmlRpcClient client(ipMart,portMart);
   XmlRpcValue resultat, camara;
   camara = num_camara;
   bool ok = client.execute("canviar_camara_activa", camara, resultat);
   if (!ok) {
      comunicacio_interficie -> indicar_Operacio_Fallida("canviar_camara_activa");
   }   
}

void Control_Comandament_Terra::girar_Robot(int graus)
{
   XmlRpcClient client(ipMart,portMart);
   XmlRpcValue resultat, num_graus;
   num_graus = graus;
   bool ok = client.execute("girar_robot", graus, resultat);
   if (!ok) {
      comunicacio_interficie -> indicar_Operacio_Fallida("girar_robot");
   }   
}
   
void Control_Comandament_Terra::girar_Cameres_Robot(int graus)
{
   XmlRpcClient client(ipMart,portMart);
   XmlRpcValue resultat, num_graus;
   num_graus = graus;
   bool ok = client.execute("girar_cameres_robot", num_graus, resultat);
   if (!ok) {
      comunicacio_interficie -> indicar_Operacio_Fallida("girar_cameres_robot");
   }    
}

void Control_Comandament_Terra::obtenir_Fotografia(int camera)
{
   XmlRpcClient client_imatge(ipMart,portMart);
   XmlRpcValue resultat, num_camera;
   num_camera = camera;
   bool ok = client_imatge.execute("obtenir_fotografia", num_camera, resultat);
   if (!ok) {
      comunicacio_interficie -> indicar_Operacio_Fallida("obtenir_fotografia");
   }
      /*int tamany_fotografia = resultat[0];
      int amplada = resultat[1];
      int altura = resultat[2];
      
      // Obertura del fitxer 
      FILE *fptr;
      char nom_fitxer[11] = "imatge.tga";
      if ((fptr = fopen("imatge.tga","w")) != NULL) {

         // Escriptura de la capçalera del fitxer Targa
         fputc(0,fptr);
         fputc(0,fptr);
         fputc(2,fptr);
         for(int i=3;i<12;i++) fputc(0,fptr);
         fputc(amplada&0xff,fptr);
         fputc(amplada/256,fptr);
         fputc(altura&0xff,fptr);
         fputc(altura/256,fptr);
         fputc(24,fptr);
         fputc(32,fptr);
         
         // Escriptura de la imatge  
         for (int i = 0; i < tamany_fotografia; i++) {
           fputc(resultat[i],fptr);
         }
         fclose(fptr);
        
         
      } */  
}

void Control_Comandament_Terra::parada_Emergencia_Robot()
{
   comunicacio_activa = 0;
}   

int Control_Comandament_Terra::comprovar_Activat()
{
   int canal_obert = comunicacio_activa;
   return canal_obert;
}

char *Control_Comandament_Terra::get_Nom_Fitxer_Informe()
{
   return nom_fitxer_informe;
}   

std::ofstream *Control_Comandament_Terra::get_Fitxer_Informe()
{
   return fitxer_informe;
}  

void Control_Comandament_Terra::tancar_Fitxer_Informe()
{
   fitxer_informe -> close();
}   


