/**
 * Author: Saravana Krishnan Kannan
 * Date: Sometime around 24-April-2004!
 * Description: This file contains the functions to check the various signal
 * files periodically.
 **/

#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "support.h"
#include "filecheck.h"
#include "plot.h"
#include "conf.h"

extern GtkWidget *w_main;
extern int curr_page;

int initialized = FALSE;

/* Set up the signal handler for the ALARM signal - SIGALRM. */
int chk_init()
{
 struct sigaction handler;
 
 handler.sa_handler=alarm_handler;
 if (sigfillset(&handler.sa_mask) < 0)
  return (-1);
 handler.sa_flags = 0;
 if (sigaction(SIGALRM, &handler, 0) < 0)
  return (-1);

 initialized = TRUE;
}

/* Signal handler function that will be called every time a SIGALRM signal is
 * generated. */
void alarm_handler(int signal)
{
 chk_file();
}

/* Checks the various data files and reads in a window's worth of data for each
 * signal. */
void chk_file()
{
 struct stat finfo;
 long pos;
 GtkWidget *drawarea, *textarea, *hscale;
 int cfgcnt, fhandle, curr_cfg, tmptrack, tmpscalemin;
 char tmp[100];

 if(!initialized) return;

 /* Read file and update internal buffer for each signal. */
 for(cfgcnt=0; cfgcnt<CFG_CNT; cfgcnt++)
 {
  /* Read the file size. */
  stat(sigcfg[cfgcnt].fname,&finfo);
  fhandle=open(sigcfg[cfgcnt].fname,O_RDONLY);
  if(fhandle==-1) continue;
  sigcfg[cfgcnt].fsize=finfo.st_size;
  /* Decide which part of the file to read into the buffer depending on the
   * position of the scrollbar and the mode of operation. */
  if(sigcfg[cfgcnt].track)
   pos=sigcfg[cfgcnt].fsize-(sigcfg[cfgcnt].size * sizeof(ushort));
  else
   pos=(sigcfg[cfgcnt].disppos-sigcfg[cfgcnt].size) * sizeof(ushort);
  if(pos<0) pos=0;
  lseek(fhandle,pos,SEEK_SET);
  /* Read the data from the file. */
  sigcfg[cfgcnt].cnt = read(fhandle, (void *) sigcfg[cfgcnt].val,
			    sigcfg[cfgcnt].size * sizeof(ushort))
			    / sizeof(ushort);
  close(fhandle);
 }

 curr_cfg=curr_page-1;
 /* Find out the objects that are currently viewed by the user. */
 switch(curr_cfg)
 {
  case IC_CFG:
  	drawarea = lookup_widget(GTK_WIDGET(w_main), "draw_ic");
  	textarea = lookup_widget(GTK_WIDGET(w_main), "t_licval");
  	hscale = lookup_widget(GTK_WIDGET(w_main), "hscale_ic");

	break;
  case IV_CFG:
  	drawarea = lookup_widget(GTK_WIDGET(w_main), "draw_iv");
  	textarea = lookup_widget(GTK_WIDGET(w_main), "t_livval");
  	hscale = lookup_widget(GTK_WIDGET(w_main), "hscale_iv");

	break;
  case OC_CFG:
  	drawarea = lookup_widget(GTK_WIDGET(w_main), "draw_oc");
  	textarea = lookup_widget(GTK_WIDGET(w_main), "t_locval");
  	hscale = lookup_widget(GTK_WIDGET(w_main), "hscale_oc");

	break;
  case OV_CFG:
  	drawarea = lookup_widget(GTK_WIDGET(w_main), "draw_ov");
  	textarea = lookup_widget(GTK_WIDGET(w_main), "t_lovval");
  	hscale = lookup_widget(GTK_WIDGET(w_main), "hscale_ov");

	break;
  case PRESSURE_CFG:
  	drawarea = lookup_widget(GTK_WIDGET(w_main), "draw_pressure");
  	textarea = lookup_widget(GTK_WIDGET(w_main), "t_lpressureval");
  	hscale = lookup_widget(GTK_WIDGET(w_main), "hscale_pressure");

	break;
  case SPEED_CFG:
  	drawarea = lookup_widget(GTK_WIDGET(w_main), "draw_speed");
  	textarea = lookup_widget(GTK_WIDGET(w_main), "t_lspeedval");
  	hscale = lookup_widget(GTK_WIDGET(w_main), "hscale_speed");

	break;
  default:
  	/* This code is executed when the user is in the "General" tab. */
	textarea = lookup_widget(GTK_WIDGET(w_main), "t_g_ic_val");
	sprintf(tmp,sigcfg[IC_CFG].format,
		( sigcfg[IC_CFG].rawmax
		  * sigcfg[IC_CFG].val[sigcfg[IC_CFG].cnt-1] )
		/ 0xFFFF );
	gtk_entry_set_text(GTK_ENTRY(textarea),tmp);
	
	textarea = lookup_widget(GTK_WIDGET(w_main), "t_g_iv_val");
	sprintf(tmp,sigcfg[IV_CFG].format,
		( sigcfg[IV_CFG].rawmax
		  * sigcfg[IV_CFG].val[sigcfg[IV_CFG].cnt-1] )
		/ 0xFFFF );
	gtk_entry_set_text(GTK_ENTRY(textarea),tmp);
	
	textarea = lookup_widget(GTK_WIDGET(w_main), "t_g_oc_val");
	sprintf(tmp,sigcfg[OC_CFG].format,
		( sigcfg[OC_CFG].rawmax
		  * sigcfg[OC_CFG].val[sigcfg[OC_CFG].cnt-1] )
		/ 0xFFFF );
	gtk_entry_set_text(GTK_ENTRY(textarea),tmp);
	
	textarea = lookup_widget(GTK_WIDGET(w_main), "t_g_ov_val");
	sprintf(tmp,sigcfg[OV_CFG].format,
		( sigcfg[OV_CFG].rawmax
		  * sigcfg[OV_CFG].val[sigcfg[OV_CFG].cnt-1] )
		/ 0xFFFF );
	gtk_entry_set_text(GTK_ENTRY(textarea),tmp);
	
	textarea = lookup_widget(GTK_WIDGET(w_main), "t_g_pressure_val");
	sprintf(tmp,sigcfg[PRESSURE_CFG].format,
		( sigcfg[PRESSURE_CFG].rawmax
		  * sigcfg[PRESSURE_CFG].val[sigcfg[PRESSURE_CFG].cnt-1] )
		/ 0xFFFF );
	gtk_entry_set_text(GTK_ENTRY(textarea),tmp);
	
	textarea = lookup_widget(GTK_WIDGET(w_main), "t_g_speed_val");
	sprintf(tmp,sigcfg[SPEED_CFG].format,
		( sigcfg[SPEED_CFG].rawmax
		  * sigcfg[SPEED_CFG].val[sigcfg[SPEED_CFG].cnt-1] )
		/ 0xFFFF );
	gtk_entry_set_text(GTK_ENTRY(textarea),tmp);
	
	alarm(1);
	return;
 }
 
 /* Update the currently viewed objects. */

 /* Draw the graph. */
 plotgraph(drawarea, sigcfg[curr_cfg]);
 refresh(drawarea);
 
 /* Set the text in the "Latest Reading" text box. */
 sprintf(tmp,sigcfg[curr_cfg].format,
	 ( sigcfg[curr_cfg].rawmax
	   * sigcfg[curr_cfg].val[sigcfg[curr_cfg].cnt-1] )
	 / 0xFFFF );
 gtk_entry_set_text(GTK_ENTRY(textarea),tmp);

 /* Adjust the Horizontal Scrollbar */

 tmptrack=sigcfg[curr_cfg].track;
 /* Decide the allowed minimum value in the Scrollbar. */
 tmpscalemin = ((sigcfg[curr_cfg].fsize / sizeof(ushort)) 
			< sigcfg[curr_cfg].size)
		? sigcfg[curr_cfg].fsize / sizeof(ushort)
		: sigcfg[curr_cfg].size;
 /* Set the range for the Scrollbar. */
 gtk_range_set_range(GTK_RANGE(hscale), tmpscalemin, 
			sigcfg[curr_cfg].fsize / sizeof(ushort) + 1);
 sigcfg[curr_cfg].track = tmptrack;
 /* Set the current value in the Scrollbar. */
 if(sigcfg[curr_cfg].track)
  gtk_range_set_value(GTK_RANGE(hscale),
			sigcfg[curr_cfg].fsize / sizeof(ushort));
 sigcfg[curr_cfg].track = tmptrack;
 
 /* Set up to alarm so that this function is called after 1 second */
 alarm(1);
}

