/****************************************************************************
*  XARXES DE COMPUTADORS II                                                 
*
*  Practica VoIP
*
*  Realizado por: 
*     Francisco Jose Aguilar Celdran
*     Sergio Blanco Cuaresma
*
*  interface.c: 
*     Implementación de funciones que modifican el estado de la interfaz o
*     piden datos/informa al usuario.
****************************************************************************/
#include <gtk/gtk.h>
#include <glade/glade.h>
#include "cola.h"
#include "libclient.h"
#include "callbacks.h"
#include "phone.h"
   
// Variables globales a nivel de programa
GladeXML *xml;
GladeXML *xmlDialog;
GtkWindow *mainWin;
GtkButton *registrar_btn;
GtkButton *deregistrar_btn;
GtkButton *buscar_btn;
GtkButton *listar_btn;
GtkButton *salir_btn;
GtkButton *llamar_btn;
GtkButton *colgar_btn;
GtkLabel *estado_label;
GtkTreeView *listado;
GtkDialog *buscarDialog;
GtkEntry *usuarioEntry;
GtkLabel *infoBuscar;

/**
   COLUMNAS del listado (GtkTreeView)
**/
enum columns {
   USER_COLUMN,
   MACHINE_COLUMN,
   PORT_COLUMN,
   N_COLUMNS
};


/**
   Establece las variables globales de interficie para poder acceder a los
   elementos de la pantalla.
**/
void asignar_elementos() {
   mainWin = GTK_WINDOW(glade_xml_get_widget(xml, "mainWin"));
   registrar_btn = GTK_BUTTON(glade_xml_get_widget(xml, "registrar_btn"));
   deregistrar_btn = GTK_BUTTON(glade_xml_get_widget(xml, "deregistrar_btn"));
   buscar_btn = GTK_BUTTON(glade_xml_get_widget(xml, "buscar_btn"));
   listar_btn = GTK_BUTTON(glade_xml_get_widget(xml, "listar_btn"));
   salir_btn = GTK_BUTTON(glade_xml_get_widget(xml, "salir_btn"));
   llamar_btn = GTK_BUTTON(glade_xml_get_widget(xml, "llamar_btn"));
   colgar_btn = GTK_BUTTON(glade_xml_get_widget(xml, "colgar_btn"));
   estado_label = GTK_LABEL(glade_xml_get_widget(xml, "estado_label"));
   listado = GTK_TREE_VIEW(glade_xml_get_widget(xml, "listado"));
   buscarDialog = GTK_DIALOG(glade_xml_get_widget(xmlDialog, "buscarDialog"));
   usuarioEntry = GTK_ENTRY(glade_xml_get_widget(xmlDialog, "usuarioEntry"));
   infoBuscar = GTK_LABEL(glade_xml_get_widget(xmlDialog, "infoBuscar"));
}

/**
   Lista los elementos de la cola en el listado (GtkTreeView)
**/
void listar (Cola *cola) {
   GtkListStore *store;
   GtkTreeIter   iter;
   int i;
   char usuario[TAM_USER], maquina[255];
   UserPort *usuario_ptr;
   
   // Crear Modelo y asignarlo al listado
   store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
   gtk_tree_view_set_model(listado, GTK_TREE_MODEL(store));
   
   // Por cada elemento
   reiniciar_PDI(cola);
   for (i=0; i<cola->total; i++) {
      usuario_ptr = (UserPort *)obtener_elemento_PDI(cola);
      tratar_direccion(usuario_ptr->user, usuario, maquina);

      // Añadir fila al modelo
      gtk_list_store_append (GTK_LIST_STORE(store), &iter);  /* Acquire an iterator */
      gtk_list_store_set (store, &iter, USER_COLUMN, usuario, 
                        MACHINE_COLUMN, maquina, PORT_COLUMN, usuario_ptr->port, -1);
      
      avanzar_PDI(cola);
   }
   vaciar_cola(cola);
}

/**
   Deja el listado (GtkTreeView) en blanco
**/
void vaciar_listado () {
   GtkListStore *store;
   
   store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
   gtk_tree_view_set_model(listado, GTK_TREE_MODEL(store));
   
}


/**
   Configura el listado (GtkTreeView) indicando las columnas que tendrá y de
   donde obtendra los valores del modelo.
**/
void preparar_listado() {
   GtkCellRenderer *renderer;
   GtkTreeViewColumn *column;

   renderer = gtk_cell_renderer_text_new (); // Renderizador tipo texto
   
   // Columna Usuario
   column = gtk_tree_view_column_new_with_attributes ("Usuario", renderer, "text", USER_COLUMN, NULL);
   gtk_tree_view_append_column (GTK_TREE_VIEW (listado), column);
   
   // Columna Maquina
   column = gtk_tree_view_column_new_with_attributes ("Maquina", renderer, "text", MACHINE_COLUMN, NULL);
   gtk_tree_view_append_column (GTK_TREE_VIEW (listado), column);
   
   // Columna Puerto
   column = gtk_tree_view_column_new_with_attributes ("Puerto", renderer, "text", PORT_COLUMN, NULL);
   gtk_tree_view_append_column (GTK_TREE_VIEW (listado), column);
   
   /* Setup the selection handler */
   GtkTreeSelection *select;

   select = gtk_tree_view_get_selection (GTK_TREE_VIEW (listado));
   gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
   g_signal_connect (G_OBJECT (select), "changed",
                  G_CALLBACK (on_listado_selection_change),
                  NULL);
}

/**
   Cambia la etiqueta de estado estableciendo el texto indicado
**/
void establecer_etiqueta_estado(char *info) {
   gtk_label_set_text(estado_label, info);
}


/**
   Habilita/Deshabilita los elementos de la interfaz segun el estado
   indicado.
**/
void visualizar_estado(int estado) {
   if (estado == DEREGISTRADO) {
      gtk_widget_set_sensitive(GTK_WIDGET(registrar_btn), TRUE);
      gtk_widget_set_sensitive(GTK_WIDGET(deregistrar_btn), FALSE);
      gtk_widget_set_sensitive(GTK_WIDGET(buscar_btn), FALSE);
      gtk_widget_set_sensitive(GTK_WIDGET(listar_btn), FALSE);
      gtk_widget_set_sensitive(GTK_WIDGET(salir_btn), TRUE);
      
      gtk_widget_set_sensitive(GTK_WIDGET(listado), FALSE);
      
      gtk_widget_set_sensitive(GTK_WIDGET(llamar_btn), FALSE);
      gtk_widget_set_sensitive(GTK_WIDGET(colgar_btn), FALSE);
      
      establecer_etiqueta_estado("Estado: Deregistrado.");
   } else if (estado == REGISTRADO) {
      gtk_widget_set_sensitive(GTK_WIDGET(registrar_btn), FALSE);
      gtk_widget_set_sensitive(GTK_WIDGET(deregistrar_btn), TRUE);
      gtk_widget_set_sensitive(GTK_WIDGET(buscar_btn), TRUE);
      gtk_widget_set_sensitive(GTK_WIDGET(listar_btn), TRUE);
      gtk_widget_set_sensitive(GTK_WIDGET(salir_btn), TRUE);
      
      gtk_widget_set_sensitive(GTK_WIDGET(listado), TRUE);
      
      gtk_widget_set_sensitive(GTK_WIDGET(llamar_btn), FALSE);
      gtk_widget_set_sensitive(GTK_WIDGET(colgar_btn), FALSE);
      
      establecer_etiqueta_estado("Estado: Registrado.");
   } else if (estado == LLAMANDO) {
      gtk_widget_set_sensitive(GTK_WIDGET(registrar_btn), FALSE);
      gtk_widget_set_sensitive(GTK_WIDGET(deregistrar_btn), TRUE);
      gtk_widget_set_sensitive(GTK_WIDGET(buscar_btn), TRUE);
      gtk_widget_set_sensitive(GTK_WIDGET(listar_btn), TRUE);
      gtk_widget_set_sensitive(GTK_WIDGET(salir_btn), TRUE);
      
      gtk_widget_set_sensitive(GTK_WIDGET(listado), TRUE);
      
      gtk_widget_set_sensitive(GTK_WIDGET(llamar_btn), FALSE);
      gtk_widget_set_sensitive(GTK_WIDGET(colgar_btn), FALSE);
      
      establecer_etiqueta_estado("Estado: Llamando.");
      
   } else if (estado == HABLANDO) {
      vaciar_listado ();   // Para evitar incoherencias entre el usuario selecionado
                           // y las variables globales maquina_actual/usuario_actual
      gtk_widget_set_sensitive(GTK_WIDGET(registrar_btn), FALSE);
      gtk_widget_set_sensitive(GTK_WIDGET(deregistrar_btn), FALSE);
      gtk_widget_set_sensitive(GTK_WIDGET(buscar_btn), FALSE);
      gtk_widget_set_sensitive(GTK_WIDGET(listar_btn), FALSE);
      gtk_widget_set_sensitive(GTK_WIDGET(salir_btn), TRUE);
      
      gtk_widget_set_sensitive(GTK_WIDGET(listado), FALSE);
      
      gtk_widget_set_sensitive(GTK_WIDGET(llamar_btn), FALSE);
      gtk_widget_set_sensitive(GTK_WIDGET(colgar_btn), TRUE);
      
      establecer_etiqueta_estado("Estado: Hablando.");
   }
   
}


/**
   Realiza una pregunta al usuario con un dialogo con posibles respuestas SI o NO.
   Devuelve 0 si pulsa SI.
   Devuelve 1 si pulsa NO.
**/
int preguntar (gchar *message) {
   GtkWidget *dialog;
   
   dialog = gtk_message_dialog_new (mainWin, GTK_DIALOG_DESTROY_WITH_PARENT|GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION,
                                  GTK_BUTTONS_YES_NO, message, NULL);
                                     
   gint result = gtk_dialog_run (GTK_DIALOG (dialog));
   gtk_widget_destroy (dialog);
   
   switch (result) {
      case GTK_RESPONSE_YES:
         return 0;
         break;
      default:
         return 1;
         break;
   }
   return 1;
}


/**
   Pide algun dato al usuario mediante un dialogo con un campo de texto.
   Devuelve el valor del campo de texto.
**/
char *pedir (gchar *message) {
   char *buscarUsuario = malloc(TAM_USER * sizeof(char));
   
   gtk_label_set_text(infoBuscar, message);
   gtk_dialog_run (GTK_DIALOG (buscarDialog));
   strncpy(buscarUsuario, gtk_entry_get_text(usuarioEntry), TAM_USER);
   gtk_entry_set_text(usuarioEntry, "");
   
   return buscarUsuario;
}
 

/**
   Informa al usuario del texto indicado.
**/
void avisar (gchar *message) {
   GtkWidget *dialog;
   
   dialog = gtk_message_dialog_new (mainWin, GTK_DIALOG_DESTROY_WITH_PARENT|GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING,
                                  GTK_BUTTONS_OK, message, NULL);
                                     
   gtk_dialog_run (GTK_DIALOG (dialog));
   gtk_widget_destroy (dialog);
}


/**
   Convierte un string null terminated (\0) del formato local a UTF8
   GTK internamente trabaja con UTF8 y por tanto esta función puede resultar
   útil en algunas circumstancias.
**/
gchar *_(gchar *text) {
   return g_locale_to_utf8(text, -1, NULL,NULL,NULL);
}

