
#include <iostream>
#include <fstream>
#include <time.h>
#include <ptime.h>
#include <pasync.h>
#include <pinet.h>
#include <ptypes.h>
#include "XmlRpc.h"
#include "Servidor_Xmlrpc_Terra.h"
#include "Flying_Team_Terra.h"
#include "Interficie_Terra.h"

#define NUM_CAMPS_INFORME 11

USING_PTYPES

using namespace XmlRpc;

XmlRpcServer server_xmlrpc;
extern Comunicacio_Interficie_Grafica *comunicacio_interficie;
extern Control_Comandament_Terra *control_terra;

void Thread_Servidor_Terra::execute()
{
   XmlRpc::setVerbosity(5);

   // Crea el server socket al port especificat
   server_xmlrpc.bindAndListen(port);

   // Permet introspeccio: funcio que retorna al client els metodes
   //                      que el servidor ofereix.
   server_xmlrpc.enableIntrospection(true);

   // Esperar infefinidament peticions del client (Mars Rover).
   server_xmlrpc.work(-1.0);
}

void Thread_Servidor_Imatges::execute()
{
   ipstmserver svr;
   svr.bindall(port);
   ipstream client;
   while(true) {
      svr.serve(client);
      if (client.get_active()) {
         try {
            char tamany[4]; 
            client.read(tamany,4);
            int amplada = atoi(tamany);
            client.read(tamany,4);
            int altura = atoi(tamany);
            unsigned char buffer[amplada * altura * 3];
            client.read(buffer,amplada*altura*3);

            FILE *fptr;
            char nom_fitxer[11] = "imatge.tga";
            fptr = fopen(nom_fitxer,"w");

            // Escritura 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 del buffer al fitxer
            for (int j=altura-1;j>=0;j--) {
               for (int i=0; i < amplada; i++) {
                  fputc(buffer[3*j*amplada+3*i+2],fptr);
                  fputc(buffer[3*j*amplada+3*i+1],fptr);
                  fputc(buffer[3*j*amplada+3*i+0],fptr);
               }
            }
            fclose(fptr);
            client.close();
            system("convert imatge.tga imatge.bmp");
            char nom_fitxer_final[20] = "imatge.bmp";
            comunicacio_interficie -> set_Fotografia(nom_fitxer_final);
         }
         catch(estream* e) {
            perr.putf("Error: %s\n", pconst(e->get_message()));
            delete e;
         }
      }
   }
}

class Servei_Comunicacio_Activa : public XmlRpcServerMethod
{
   public:
      Servei_Comunicacio_Activa(XmlRpcServer* server_xmlrpc) : XmlRpcServerMethod("comunicacio_activa", server_xmlrpc) {}

      void execute(XmlRpcValue& params, XmlRpcValue& result)
      {
         result = "Canal de comunicacio Terra-Mart actiu";
      }

      std::string help() 
      { 
         return std::string("Verifica el comunicacio entre la Terra i Mart."); 
      }
} servei_Comunicacio_Activa(&server_xmlrpc);

class Servei_Informe_Dades_Mart : public XmlRpcServerMethod
{
   private:
      std::ofstream *fitxer;
      time_t temps_actual;
      int inici;
   public:
      Servei_Informe_Dades_Mart(XmlRpcServer* server_xmlrpc) : XmlRpcServerMethod("informe_mart", server_xmlrpc) 
      {
         inici = 1;
      }

      void execute(XmlRpcValue& params, XmlRpcValue& result)
      {
         if (inici) {
            fitxer = control_terra -> get_Fitxer_Informe();
            inici = 0;
         }
         //std::ofstream *fitxer_prova;
         int num_params = params.size();
         time(&temps_actual);
         std::ofstream fitxer_prova("prova_informe.txt",std::ios::app|std::ios::out);         
         fitxer_prova << "Terra reb inici informe...\n";
         fitxer_prova.close();

         *fitxer << "--Informe de Mart-- " << ctime(&temps_actual) << std::endl;
         *fitxer << "| X | Y | Z | Angle_Orientacio | Angle_Altura | Temperatura | " << 
                    "Llum | Material | Ferro | Temperatura | Xray |" << std::endl;
         // Obtenir tants registres com longitud del informe entre 
         // el numero de camps (x,y,z,temp,llum,material,hora,etc)
         // de cada registre de informe de mart, enviat periodicament
         for (int i = 0; i < num_params / NUM_CAMPS_INFORME; i++) {
            *fitxer <<  "| ";
            for(int j = 0; j < NUM_CAMPS_INFORME; j++) {
               *fitxer <<  result[(NUM_CAMPS_INFORME * i) + j] << " | ";
            }   
            *fitxer <<  std::endl;
         }
         *fitxer <<  std::endl;
         result = "OK";
      }

      std::string help() 
      { 
         return std::string("Rep un informe amb les dades recollides de mart."); 
      }
} servei_Informe_Dades_Mart(&server_xmlrpc);

// Si el robot no detecta comunicacio activa o esgotes la bateria
// (Aleshores el robot atura el moviment si esta movent-se i cancela la seva
//  execucio en espera de rebre nova activacio des de la Terra)
class Servei_Parada_Emergencia_Robot : public XmlRpcServerMethod
{
   public:
      Servei_Parada_Emergencia_Robot(XmlRpcServer* server_xmlrpc) : XmlRpcServerMethod("parada_emergencia", server_xmlrpc) {}

      void execute(XmlRpcValue& params, XmlRpcValue& result)
      {
         //Avisar a la interficie de la parada de emergencia i la causa
         std::string causa = (std::string)params;
         std::cout << "\nRebut_Missatge_Emergencia en servidor de Terra!?!?!?!?!?!?!?!\n";
         std::cout << "Causa: " << params;
         comunicacio_interficie -> indicar_Parada_Emergencia(causa);
         if (!causa.compare("moviment_impossible")) {
            control_terra -> parada_Emergencia_Robot();
         }   
         result = "OK";
      }

      std::string help() 
      { 
         return std::string("Informa de la parada del robot per la causa indicada."); 
      }
} servei_Parada_Emergencia_Robot(&server_xmlrpc);


