//********************************************************************
// Programa para mostrar el estado de de 4 interruptores de entrada	*
// enviados por un PIC via serie al ordenador por un solo byte			*
//********************************************************************

#include <gtk/gtk.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <unistd.h>
#include  <glib.h>
#include <time.h>

//-------PROTOTIPOS---------------
void pinta();
int inicia_Puerto();
void lee_Puerto();
//--------------------------------

//-----------PIC--------------
#define BAUDRATE B9600
#define MODEMDEVICE "/dev/ttyS0"
#define _POSIX_SOURCE 1 /* fuentes cumple POSIX  */
int fd,res;
char buf[4]={0};
char cht[5],chh[5],chv[5],chp[5];
GtkWidget *img_bit1,*img_bit2,*img_bit3,*img_bit4;
int testIO;
struct termios oldtio,newtio;
//-----------------------------


void clik_off( GtkWidget *widget, gpointer   data ){	
	gdk_input_remove( testIO );
	puts("Parada la captura");
}

void destroy( GtkWidget *widget, gpointer   data ){
   gtk_main_quit ();
}

gint delete_event( GtkWidget *widget,GdkEvent  *event, gpointer   data ){
	g_print ("Cerrando puerto\n");
	//cierro puerto
	close(fd);
	//	restaura la anterior configuracion del puerto  
	// tcsetattr(fd,TCSANOW,&oldtio);
	puts("Puerto cerrado");
	return 0;
}

int main( int   argc, char *argv[] ){
	GtkWidget *ventana;
	GtkWidget *btn_Off;//,*btn_On;
	//GtkWidget *img_bit1,*img_bit2,*img_bit3,*img_bit4;
	GtkWidget *lbl1,*lbl2,*lbl3,*lbl4;
	GtkWidget *tabla;
	
	gtk_init (&argc, &argv);

   //abro el puerto y lo inicializa
	fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
	if (fd <0) {  perror(MODEMDEVICE); exit(-1);  }
	inicia_Puerto();

	//creamos la ventana
	ventana = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	g_signal_connect (G_OBJECT (ventana), "delete_event",G_CALLBACK (delete_event), NULL);
	g_signal_connect (G_OBJECT (ventana), "destroy",G_CALLBACK (destroy), NULL);
	gtk_window_set_default_size(GTK_WINDOW(ventana), 300, 250);
	gtk_window_set_title(GTK_WINDOW(ventana),"Comunicacion con PIC");
	//gtk_window_set_resizable(GTK_WINDOW(ventana),FALSE);
	
	// Creamos una tabla de 3x4 de widgets
	tabla = gtk_table_new (3, 4, TRUE);
	
   //Añadimos la tabla a la ventana
	gtk_container_add (GTK_CONTAINER (ventana), tabla);

	//creo las labels
	lbl1 = gtk_label_new("1");
	lbl2 = gtk_label_new("2");
	lbl3 = gtk_label_new("3");
	lbl4 = gtk_label_new("4");
	
	//creo las images
	img_bit1 = gtk_image_new_from_file("bitNegro.png");
	img_bit2 = gtk_image_new_from_file("bitNegro.png");
	img_bit3 = gtk_image_new_from_file("bitNegro.png");
	img_bit4 = gtk_image_new_from_file("bitNegro.png");

	//creamos los botones
  	btn_Off = gtk_button_new_with_label("Parar");
	g_signal_connect (G_OBJECT (btn_Off), "clicked",G_CALLBACK (clik_off), NULL);

   //añadimos widgets a la tabla
	gtk_table_attach (GTK_TABLE (tabla),btn_Off,1,3,0,1,GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,1,1);

	gtk_table_attach (GTK_TABLE (tabla),lbl1, 3,4,1,2,GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,1,1);
	gtk_table_attach (GTK_TABLE (tabla),lbl2, 2,3,1,2,GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,1,1);
	gtk_table_attach (GTK_TABLE (tabla),lbl3, 1,2,1,2,GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,1,1);
	gtk_table_attach (GTK_TABLE (tabla),lbl4, 0,1,1,2,GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,1,1);

	gtk_table_attach (GTK_TABLE (tabla),img_bit1, 3,4,2,3,GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,1,1);
	gtk_table_attach (GTK_TABLE (tabla),img_bit2, 2,3,2,3,GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,1,1);
	gtk_table_attach (GTK_TABLE (tabla),img_bit3, 1,2,2,3,GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,1,1);
	gtk_table_attach (GTK_TABLE (tabla),img_bit4, 0,1,2,3,GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,1,1);
	
	//los hacemos visibles
	gtk_widget_show_all(ventana);

	//-----------funcion que teste las IO ------------
	testIO = gdk_input_add( fd, GDK_INPUT_READ, (GdkInputFunction)lee_Puerto, NULL );  //ok
	//-------------------------------------------------

	gtk_main ();

	return 0;
}

//----------------- Inicializa parametros del puerto serie ---------------------
int inicia_Puerto(){
   tcgetattr(fd,&oldtio); /* almacenamos la configuracion actual del puerto */
   bzero(&newtio, sizeof(newtio)); /* limpiamos struct para recibir los  nuevos parametros del puerto */

   newtio.c_cflag = BAUDRATE | CS8 | CSTOPB | CLOCAL | CREAD;   //ok
	
   newtio.c_iflag = IGNPAR;// | ICRNL;
	newtio.c_oflag &= ~ OPOST; //0;
	newtio.c_lflag = 0;  //ICANON;

//   newtio.c_cc[VINTR]    = 0;     // Ctrl-c 
//   newtio.c_cc[VQUIT]    = 0;     // Ctrl- 
//   newtio.c_cc[VERASE]   = 0;     // del
//   newtio.c_cc[VKILL]    = 0;     // @ 
//   newtio.c_cc[VEOF]     = 4;     // Ctrl-d 
   newtio.c_cc[VTIME]    = 0;     // temporizador entre caracter, no usado 
   newtio.c_cc[VMIN]     = 1;     // 1=bloquea lectura hasta llegada de caracter. 1 
//   newtio.c_cc[VSWTC]    = 0;     // '\0' 
//   newtio.c_cc[VSTART]   = 0;     // Ctrl-q 
//   newtio.c_cc[VSTOP]    = 0;     // Ctrl-s 
//   newtio.c_cc[VSUSP]    = 0;     // Ctrl-z 
//   newtio.c_cc[VEOL]     = 0;     // '\0' 
//   newtio.c_cc[VREPRINT] = 0;     // Ctrl-r 
//   newtio.c_cc[VDISCARD] = 0;     // Ctrl-u 
//   newtio.c_cc[VWERASE]  = 0;     // Ctrl-w 
//   newtio.c_cc[VLNEXT]   = 0;     // Ctrl-v 
//   newtio.c_cc[VEOL2]    = 0;     // '\0' 

	tcflush(fd,TCIFLUSH);
   tcsetattr(fd,TCSANOW,&newtio);

	puts("Puerto inicializado");
	return 0;
}



//-----------------Funcion que lee el puerto serie --------------------
void lee_Puerto(){
char test=0;

	res = read(fd,buf,1);		//lee 1 byte y lo mete en el buf

	test = buf[0]&15;				//hace un AND 15 para analizar los 4 bits de menos peso
	printf("test=%d\n",test);	//lo pinto en pantalla para ver si lo va aciendo bien

	// segun los bits activos cambio de color los cuadritos (imagenes)
	switch (test){

		case 0:
			gtk_image_set_from_file (GTK_IMAGE (img_bit1),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit2),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit3),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit4),"bitNegro.png");
			break;

		case 1:
			gtk_image_set_from_file (GTK_IMAGE (img_bit1),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit2),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit3),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit4),"bitNegro.png");
			break;

		case 2:
			gtk_image_set_from_file (GTK_IMAGE (img_bit1),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit2),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit3),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit4),"bitNegro.png");
			break;

		case 3:
			gtk_image_set_from_file (GTK_IMAGE (img_bit1),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit2),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit3),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit4),"bitNegro.png");
			break;

		case 4:
			gtk_image_set_from_file (GTK_IMAGE (img_bit1),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit2),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit3),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit4),"bitNegro.png");
			break;

		case 5:
			gtk_image_set_from_file (GTK_IMAGE (img_bit1),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit2),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit3),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit4),"bitNegro.png");
			break;

		case 6:
			gtk_image_set_from_file (GTK_IMAGE (img_bit1),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit2),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit3),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit4),"bitNegro.png");
			break;

		case 7:
			gtk_image_set_from_file (GTK_IMAGE (img_bit1),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit2),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit3),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit4),"bitNegro.png");
			break;

		case 8:
			gtk_image_set_from_file (GTK_IMAGE (img_bit1),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit2),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit3),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit4),"bitRojo.png");
			break;

		case 9:
			gtk_image_set_from_file (GTK_IMAGE (img_bit1),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit2),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit3),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit4),"bitRojo.png");
			break;

		case 10:
			gtk_image_set_from_file (GTK_IMAGE (img_bit1),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit2),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit3),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit4),"bitRojo.png");
			break;

		case 11:
			gtk_image_set_from_file (GTK_IMAGE (img_bit1),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit2),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit3),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit4),"bitRojo.png");
			break;

		case 12:
			gtk_image_set_from_file (GTK_IMAGE (img_bit1),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit2),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit3),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit4),"bitRojo.png");
			break;

		case 13:
			gtk_image_set_from_file (GTK_IMAGE (img_bit1),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit2),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit3),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit4),"bitRojo.png");
			break;

		case 14:
			gtk_image_set_from_file (GTK_IMAGE (img_bit1),"bitNegro.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit2),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit3),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit4),"bitRojo.png");
			break;

		case 15:
			gtk_image_set_from_file (GTK_IMAGE (img_bit1),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit2),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit3),"bitRojo.png");
			gtk_image_set_from_file (GTK_IMAGE (img_bit4),"bitRojo.png");
			break;
	}

	//--- pausa GTK junto con la siguiente linea-----
	// sin esta pausa lo hace tan deprisa que no se aprecian los cambios de los colores
	usleep(600000); //ok 1000000=1sg
	gtk_main_iteration();
	//------------------------------------------------

}


