
#include <iostream>
#include <exception>
#include <stdlib.h>
#include "Interficie_Terra.h"
#include "Servidor_Xmlrpc_Terra.h"
#include "Flying_Team_Terra.h"

Control_Comandament_Terra *control_terra;
Comunicacio_Interficie_Grafica *comunicacio_interficie;
Logica_Interficie_Grafica *logica_interficie;
Thread_Servidor_Terra* servidor;

// METODE TEMPORAL MENTRE NO HI HAGI INTERFICIE GRAFICA
void mostrar_Menu()
{
   std::cout << "Menu de opcions de la terra:\n";
   std::cout << "   1) Iniciar comunicacio amb Mart (Premer tecla 'i')\n"; 
   std::cout << "   2) Activar moviment Robot (Premer tecla 'a')\n";
   std::cout << "   3) Parar moviment Robot (Premer tecla 'p')\n";
   std::cout << "   4) Girar Robot (Premer tecla 'g' i angle entre -180 i 180)\n";
   std::cout << "   5) Girar cameres Robot (Premer tecla 'c' i angle entre -180 i 180))\n";
   std::cout << "   6) Obtenir fotografia (Premer tecla 'o' i numero de camera)\n";
   std::cout << "   7) Finalitzar la comunicacio amb Mart (Premer tecla 'f')\n";
   std::cout << "   8) Mostrar aquest menu (Premer tecla 'm')\n";
   std::cout << "   9) Sortir (Premer tecla 's')\n\n";
   std::cout << "   10) Canviar camara activa (Premer tecla 'r')\n\n";
}
void mostrar_inici()
{
   std::cout << "\n\n *** Sistemes Informatics I ***\n\n";
   std::cout << "Mars Rover - Flying Team Terra\n\n";
}

Interficie_Grafica::Interficie_Grafica(int numargs, char **args)
{
   argc = numargs;
   argv = args;
}   

void Interficie_Grafica::iniciar()
{
   logica_interficie = new Logica_Interficie_Grafica();
   comunicacio_interficie = new Comunicacio_Interficie_Grafica(logica_interficie);
   control_terra = new Control_Comandament_Terra();
   if (argc != 5) {
      std::cerr << "\nUs: SI1_MarsRovers_Terra <ip_servidor_mart> <port_servidor_mart> <port_servidor_terra> <fitxer_informes>\n\n";
      exit(1);
   }
   // ----------------------------------------------------
   // EL CODI AFEGIT A CONTINUACIO ES EL CONTROL
   // TEMPORAL DE L'EXECUCIO DE LA INTERACCIO AMB L'USUARI
   // A FALTA DE IMPLEMENTAR LA INTERFICIE GRAFICA:
   // (S'IMPLEMENTARA A LA CLASSE LOGICA_INTERFICIE)     
   // ----------------------------------------------------
   mostrar_inici();
   char *ip_mart = (char *)malloc(sizeof(char) * strlen(argv[1]));
   strcpy(ip_mart,argv[1]);
   int port_mart = atoi(argv[2]);
   int port_terra = atoi(argv[3]);
   char *fitxer_informe = (char *)malloc(sizeof(char) * strlen(argv[4]));
   strcpy(fitxer_informe,argv[4]);   
   int err = comunicacio_interficie -> establir_Parametres_Inicials(ip_mart,port_mart,port_terra,fitxer_informe);
   if (err) {
      std::cerr << "Error en l'establiment dels parametres!";
      exit(1);
   }   
   mostrar_Menu();
   std::cout << "Iniciant servidor de la terra... Introduir opcio del menu... " << std::endl;   
   control_terra -> iniciar_servidor();
   char entrada[80];
   std::cin >> entrada;
   int num_graus, camera;
   while (entrada[0] != 's') {
      switch (entrada[0]) {
         case 'i':
            control_terra -> activar_Comunicacio_Terra(); break;
         case 'f':
            control_terra -> desactivar_Comunicacio_Terra(); break;            
         case 'a':
            control_terra -> iniciar_Moviment_Robot(); break;
         case 'p':
            control_terra -> finalitzar_Moviment_Robot(); break;
         case 'g':
            std::cout << "Indicar els graus: ";
            std::cin >> num_graus;
            control_terra -> girar_Robot(num_graus); break;
         case 'c':
            std::cout << "Indicar els graus: ";
            std::cin >> num_graus;
            control_terra -> girar_Cameres_Robot(num_graus); break;
         case 'o':
            std::cout << "Indicar el numero de camera: ";
            std::cin >> camera;
            control_terra -> obtenir_Fotografia(camera); break;            
         case 'r':
            std::cout << "Indicar el numero de camera: ";
            std::cin >> camera;
            control_terra -> canviar_Camara_Activa(camera); break; 
         case 'm':
            mostrar_Menu(); break;
      }
      std::cout << "En espera de noves accions de la Terra... ";
      std::cin >> entrada;
   }   
   control_terra -> tancar_Fitxer_Informe();
   //servidor -> ~Thread_Servidor_Terra(); // Estudiar si es la millor forma de aturar el thread servidor !!
   delete servidor;
}

Comunicacio_Interficie_Grafica::Comunicacio_Interficie_Grafica(Logica_Interficie_Grafica *referencia_gui)
{
   logica = referencia_gui;
}

int Comunicacio_Interficie_Grafica::establir_Parametres_Inicials(char *ip_mart, int port_mart, 
                                                                  int port_terra, char *fitxer_informe)
{
   //Inicialitzar amb els parametres obtinguts de la logica interficie grafica:
   int problema = control_terra -> inicialitzar_Dades(ip_mart,port_mart,port_terra,fitxer_informe);   
   if (!problema) {
      // Execucio d'un thread per a manegar el servidor XML-RPC de la Terra
      // que ofereix procediments remots al Mars Rovers de Mart.
      servidor = new Thread_Servidor_Terra(port_terra);
      servidor -> start();
      return 0;
   }
   else {
      return 1;
   }   
}   

void Comunicacio_Interficie_Grafica::set_Posicio_Robot(float x, float y, float z, int angleOrientacio, int angleAltura)
{
   // IMPLEMENTAR LA CRIDA AL CORRESPONENT WIDGET PER MOSTRAR LA INFORMACIO
   std::cout << "Obtencio de posicio: x=" << x << " y=" << y << " z=" << z
             << " angleOrientacio=" << angleOrientacio << " angleAltura=" << angleAltura << "\n";
}   
void Comunicacio_Interficie_Grafica::set_Material(int material)
{
   // IMPLEMENTAR LA CRIDA AL CORRESPONENT WIDGET PER MOSTRAR LA INFORMACIO
   std::cout << "Obtencio de material: " << material << "\n";         
}   
void Comunicacio_Interficie_Grafica::set_Nivell_Ferro(float ferro)
{
   // IMPLEMENTAR LA CRIDA AL CORRESPONENT WIDGET PER MOSTRAR LA INFORMACIO
   std::cout << "Obtencio de nivell de ferro: " << ferro << "\n";
}   

void Comunicacio_Interficie_Grafica::set_Nivell_Llum(float llum)
{
   // IMPLEMENTAR LA CRIDA AL CORRESPONENT WIDGET PER MOSTRAR LA INFORMACIO
   std::cout << "Obtencio de nivell de llum: " << llum << "\n";         
}   

void Comunicacio_Interficie_Grafica::set_Temperatura(int temperatura)
{
   // IMPLEMENTAR LA CRIDA AL CORRESPONENT WIDGET PER MOSTRAR LA INFORMACIO
   std::cout << "Obtencio de la temperatura: " << temperatura << "\n";      
}   

void Comunicacio_Interficie_Grafica::set_Nivell_Bateria(int bateria)
{
   // IMPLEMENTAR LA CRIDA AL CORRESPONENT WIDGET PER MOSTRAR LA INFORMACIO
   std::cout << "Obtencio de nivell de bateria: " << bateria << "\n";      
}

void Comunicacio_Interficie_Grafica::set_Nivell_XRay(float xray)
{
   // IMPLEMENTAR LA CRIDA AL CORRESPONENT WIDGET PER MOSTRAR LA INFORMACIO
   std::cout << "Obtencio de nivell de xray: " << xray << "\n";   
}   

void Comunicacio_Interficie_Grafica::set_Fotografia(char *fitxer_imatge)
{
   // IMPLEMENTAR LA CRIDA AL CORRESPONENT WIDGET PER MOSTRAR LA INFORMACIO
   std::cout << "Obtencio de fotografia correcta\n";
}   

void Comunicacio_Interficie_Grafica::indicar_Operacio_Fallida(char *operacio)
{
   // --------------------------------------------------------------------------
   // SEGONS CADA CAS S'INVOCARA AL WIDGET CORRESPONENT DE LA INTERFICIE GRAFICA
   // Es mostra temporalment per sortida estandard mentre no hi ha GUI
   // --------------------------------------------------------------------------
   if(strcmp(operacio,"posicio_robot") == 0) {
      std::cout << "Operacio de posicionament de robot fallida\n";
   }
   else if (strcmp(operacio,"material") == 0) {
      std::cout << "Operacio d'obtencio de material fallida\n";   
   }
   else if (strcmp(operacio,"ferro") == 0) {
      std::cout << "Operacio d'obtencio de ferro fallida\n";      
   }
   else if (strcmp(operacio,"temperatura") == 0) {
      std::cout << "Operacio d'obtencio de temperatura fallida\n";      
   }
   else if (strcmp(operacio,"llum") == 0) {
      std::cout << "Operacio d'obtencio de llum fallida\n";      
   }
   else if (strcmp(operacio,"bateria") == 0) {
      std::cout << "Operacio d'obtencio de nivell de bateria del robot fallida\n";      
   }   
   else if (strcmp(operacio,"xray") == 0) {
      std::cout << "Operacio d'obtencio de raigs X fallida\n";      
   }
   else if (strcmp(operacio,"obtenir_fotografia") == 0) {
      std::cout << "Operacio d'obtencio de fotografia fallida\n";      
   }
   else if (strcmp(operacio,"girar_robot") == 0) {
      std::cout << "Operacio de gir del robot fallida\n";      
   }
   else if (strcmp(operacio,"girar_cameres_robot") == 0) {
      std::cout << "Operacio de gir de cameres del robot fallida\n";      
   }
   else if (strcmp(operacio,"activar_comunicacio_terra") == 0) {
      std::cout << "Operacio d'activacio de funcionament del robot fallida\n";      
   }
   else if (strcmp(operacio,"desactivar_comunicacio_terra") == 0) {
      std::cout << "Operacio de desactivacio de funcionament del robot fallida\n";      
   }
   else if (strcmp(operacio,"inici_moviment_robot") == 0) {
      std::cout << "Operacio d'inici de moviment del robot fallida\n";    
   }
   else if (strcmp(operacio,"fi_moviment_robot") == 0) {
      std::cout << "Operacio de finalitzacio de moviment del robot fallida\n";      
   }
   else if (strcmp(operacio,"dades_completes") == 0) {
      std::cout << "Operacio de obtencio de dades completes fallida\n";
   }   
   else if (strcmp(operacio,"canviar_camara_activa") == 0) {
      std::cout << "Operacio de modificacio de camara activa fallida\n";
   } 
}   

void Comunicacio_Interficie_Grafica::indicar_Parada_Emergencia(std::string motiu)
{
   // IMPLEMENTAR LA CRIDA AL CORRESPONENT WIDGET PER MOSTRAR LA INFORMACIO
   std::cout << "Parada de emergencia del robot per la causa: " + motiu + "\n";   
}   

Logica_Interficie_Grafica::Logica_Interficie_Grafica()
{
   // IMPLEMENTAR INTERFICIE GRAFICA I AFEGIR ELS METODES I CLASSES NECESSARIS
}   


