/*
*/

#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include"uart.c"

#define data_file_path  "./DATA/data.dat"
#define SprintIR  4    //co2 sensor
#define COAF      1    //co sensor
#define LOX_O2    2    //o2

#define Rep_Dev_ID      "Y\r\n"
#define Pulling_Mode    "K 2\r\n"
#define OX_P_Mode       "M 1\r\n"
#define FILnUNFIL       "M 6\r\n"
#define unf_gas_con     "z\r\n"
#define fil_gas_con     "Z\r\n"
#define Temperature     "T\r\n"
#define get_readigns    "Q\r\n"
#define percent_oxigen  "%\r\n"
#define ppm_oxigen      "O\r\n"
#define M_zZTHBD        "M 14406\r\n"
#define M_zZTHB         "M 12358\r\n"
#define Readings_OX     "A\r\n"

int sensConf(unsigned char uartNumber, int baudRate, unsigned char mode[], unsigned char response[], int tries);
int measure(unsigned char uartNumber, unsigned char command[], int multiplier, int excess);
char *getMeasures(char src[], char fval, int nchar);
int str2int(unsigned char *ptr);
int DAQ(int t_hrs, int sp_s);

int main(int argc, char *argv[]){

    int T_acq, t_samp;

    if(argc!=3){
        printf("Invalid number of arguments,\n"\
        "Usage: daq <time(h)> <sampling period(s)>\nexiting!\n");
        return -2;
    }

    //configuración de sensores
    printf("Configuring CO2 sensor\n");
    sensConf(SprintIR, B9600, Pulling_Mode, " K 00002\r\n", 5);
    sensConf(SprintIR, B9600, FILnUNFIL, " M 00006\r\n", 5);
    printf("Configuring CO sensor\n");
    sensConf(COAF, B9600, Pulling_Mode, "K 00002\r\n", 5);
    sensConf(COAF, B9600, M_zZTHB, "M 14406\r\n", 5);
    printf("Configuring O2 sensor\n");
    sensConf(LOX_O2, B9600, OX_P_Mode, "M 01\r\n", 5);

    //adquisición
    T_acq = atoi(argv[1]);//str to int
    t_samp = atoi(argv[2]);
    printf("Starting data acquisition with duration of %dh every %ds\n", T_acq, t_samp);
    DAQ(T, t);

    //deinit uart
    uartClose(SprintIR);
    uartClose(COAF);
    uartClose(LOX_O2);
    //finalización
    printf("Exiting of the program...\n");
    return 0;
}

int sensConf(unsigned char uartNumber, int baudRate, unsigned char mode[], unsigned char response[], int tries)
{
    int count;

    uartConf(uartNumber, baudRate);
    while(tries){
        uartTransmit(uartNumber, mode);
        tcdrain(uartFile[uartNumber]);  //wait all data has been sent
        printf("Command sended.\n");
        //usleep(100000);                  //give the sensor a chance to respond
        count = uartReceive(uartNumber);
        if (count == 0) printf("There was no data available to read!\n");
        else if (strcmp(receive[uartNumber], response) == 0) {
                printf("Sensor configurated.\n");
                return 0;
        } else {
            printf("The following was read in [%d]: %s\n",count,receive[uartNumber]);
            //char *c = receive[uartNumber];
            //while (*c != '\0'){
            //    printf("%d = '%c'\n",*c, *c);
            //    c++;
            //}
        }
        tries --;
    }
    printf("Sensor configuration failed.\n");
    return -1;
}

int DAQ(int t_hrs, int sp_s)
{
  FILE* dfp;                                    // create a file pointer
  const char colums[200] = "t(s)\tCO2 uf(ppm)\tCO2(ppm)\tCO uf(ppm)\t"\
                           "CO(ppm)\tppO2(mbar)\tO2(%%)\tT C0(ºC*10)\t"\
                           "T 02(ºC)\tP C0(.mBar)\tP 02(mBar)\tRH(.)\n";
  unsigned char co2_uf[10]="",   co2_f[10]="",
                co_uf[10]="",    co_f[10]="",
                o2_ppm[10]="",   o2_xcent[10]="",
                co_temp[10]="",  o2_temp[10]="",
                co_press[10]="", o2_press[10]="",
                co_relH[10]="",  DATA[100]="";    //measurements varirables
  time_t curtime;                               //current time (date)
  clock_t start_t, end_t;                       //processing time measurements variables
  time_t next_samp_time, t0;                    //time control variables
	double iteration_time_ms = sp_s*1e6 - 0.2e6;  //cicle iteration maximum time
	double inactivity_time = 1;                   //time to sleep

  time(&curtime);                               //saving date in curtime
  //registro datos de inicio
  dfp = fopen(data_file_path, "w");             // open file for writing
  // send the value to the file
  fprintf(dfp, "Starting DAQ at %s\n", ctime(&curtime);
  fclose(dfp);                                  // close the file using the file pointer
  printf("%s", colums);                         //display variables colums
  //ciclo
  next_samp_time = time(NULL)+1;              //setting next sampling time
  t0 = next_samp_time;                          //saving initial time
  for(time_t t = 0; t < (t_hrs*3600); t+=sp_s){    //cycle from 0 to adquisition time (seconds), incrementing sampling period
    //checking inactivity time
    if (inactivity_time <= 1){
      usleep((int)inactivity_time);             //inactivity
    }
    else{
      printf("Ejecution time exceded.\n%s", colums);
      next_samp_time = time(NULL)+1;              //updating time values
      t = next_samp_time-t0;
    }
    while(next_samp_time != time(NULL));      //synchronizing/waiting to start measurements

    start_t = clock();                          //saving start time
      uartTransmit(COAF, get_readigns);         //transmiting commands to sensors
      uartTransmit(LOX_O2, Readings_OX);
      uartTransmit(SprintIR, get_readigns
      uartReceive(COAF);                        //receiving replys from
      uartReceive(LOX_O2);
      uartReceive(SprintIR);
      //interpreting and spliting measurements in variables
      memcpy(co2_uf,   getMeasures(receive[SprintIR],'z', 5), 5);
      memcpy(co2_f,    getMeasures(receive[SprintIR],'Z', 5), 5);
      memcpy(co_uf,    getMeasures(receive[COAF],    'z', 5), 5);
      memcpy(co_f,     getMeasures(receive[COAF],    'Z', 5), 5);
      memcpy(o2_ppm,   getMeasures(receive[LOX_O2], 'O', 6), 6);
      memcpy(o2_xcent, getMeasures(receive[LOX_O2], '%', 6), 6);
      memcpy(co_temp,  getMeasures(receive[COAF],    'T', 5), 5);
      memcpy(o2_temp,  getMeasures(receive[LOX_O2], 'T', 5), 5);
      memcpy(co_press, getMeasures(receive[COAF],    'B', 5), 5);
      memcpy(o2_press, getMeasures(receive[LOX_O2], 'P', 4), 4);
      memcpy(co_relH,  getMeasures(receive[COAF],    'H', 5), 5);
      //saving formated measurements in string DATA
      sprintf(DATA,
              "%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s",
              (int)t, co2_uf, co2_f, co_uf, co_f, o2_ppm, o2_xcent,
              co_temp, o2_temp, co_press, o2_press, co_relH);
      printf("\r%s", DATA);                     //showing measurements on display

      dfp = fopen(data_file_path, "a");         // open file for writing
      fprintf(dfp, "%s\n", DATA);               // saving measurements string to data file
      fclose(dfp);                              // close the file using the file pointer
      next_samp_time += sp_s;                   //adding sampling period to next_samp_time
    end_t = clock();                            //saving end time
    //calculate time to sleep
    inactivity_time =  iteration_time_ms - ((double)(end_t - start_t)*1e6 / CLOCKS_PER_SEC);
  }

  return 0;
}

char *getMeasures(char src[], char fval, int nchar)
{
	char * ptr = &src[0];
	static char s[10]="";

	while(*ptr != fval) ptr++;
	ptr += 2;
	memcpy(s, ptr, nchar);
	return s;
}