// convert NMEA Longitude string to decimal
int process_longitude(char *line, double *decimal)
{
 // example string: "00833.9120"
 // => 8 degree, 33.9120 minutes
 int deg;
 int min1;
 int min2;
 double min;
 char format[]="%03d%02d.%04d";

 if ( sscanf (line,format, &deg,&min1,&min2) != 3)
   return 1;
 min = min1 + ( ((double)(min2))/10000 );
 *decimal = deg + ( ((double)min)/60 ) ;
 return 0;
}


// convert NMEA Latitude string to decimal
int process_latitude(char *line, double *decimal)
{
 // example string: "4717.1150"
 // => 47 degree, 17.781150 minutes
 int deg;
 int min1;
 int min2;
 double min;
 char format[]="%02d%02d.%04d";
 if ( sscanf (line,format, &deg,&min1,&min2) != 3)
   return 1;
 min=min1+( ((double)(min2))/10000 );
 *decimal=deg + ( ((double)min)/60 );
 return 0;
}


int process_nmea_rmc(char *line, double *longitude, double *latitude)
{
 // see:
 // http://users.on.net/~merrifield/gps/user/nmea.c
 // http://csourcesearch.net/package/gpsutil/0.10/gpsutil/nmea.c
 // http://de.wikipedia.org/wiki/NMEA


 char tmpline[255];
 char *strzgr;
 int i=0;
 char *field[30]; // max. characters per field

 strcpy(tmpline,line);
 strzgr=strtok(tmpline,",");
 while( strzgr != NULL )
 {
   field[i] = strzgr;
   strzgr=strtok(NULL,",");
   i++;
 }

 if ( strcmp(field[0],"$GPRMC") != 0 ) {
   return 1; // falsche Zeile
 }

 // field[3] should contain latitude

 if ( process_latitude(field[3],&(*latitude)) != 0 )
   return 1;

 if ( process_longitude(field[5],&(*longitude)) != 0 )
   return 1;

 return 0;
}




// Fetches exactly one line of the gpspipe
int readgpsfifo(char *line)
{
 // how to read from a pipe?
 // http://www-personal.washtenaw.cc.mi.us/~chasselb/linux275/ClassNotes/ipc/pipe_named.htm
 int pipe_fd;
 int res;
 int open_mode = O_RDONLY;
 char buffer[FIFO_BUFFER_SIZE + 1];
 int bytes_read = 0;
 char *start;
 char *end;


 memset(buffer, '\0', sizeof(buffer));
 
 pipe_fd = open(gpsfifo_name, open_mode);

 if (pipe_fd != -1) {
     {
         res = read(pipe_fd, buffer, FIFO_BUFFER_SIZE);
         bytes_read += res;
     } 
     (void)close(pipe_fd);
 }
 else 
 {
   strcpy(line,"");
   return 1;
 }
 
 buffer[strlen(buffer)-1]='\0';

 // printf("BUFFER: ***** %s *****\n\n",buffer);

 if ( strchr(buffer,'\n') != NULL )
 {
   start=strchr(buffer,'\n');
   start++;

   if ( strchr(start,'\n') )
   {
    // nach \n suchen und durch \0 ersetzen
    for ( end=start; *end!='\n'; *end++  )
     { ; }
    *end='\0';
   }
   else // only one \n found in buffer
     return 2;
 }
 else
 {
  // no \n found in buffer
  return 1;
 }

 strcpy(line,start);
 return 0;
}


double meanvalue(double data[], int n)
// n = number of values
{
 int i;
 double sum;

 sum = 0.0;
 for ( i=0 ; i<n ; i++ ) {
   sum += data[i];
 }
 return (sum/(double)n);
}


// function reads "number" NMEA-RMC lines. The outcome (
// "longitude" and "latitude") are averaged.
int avggps(int number,double *longitude,double *latitude)
{
 int i=0;
 int j=0;
 int outcome;
 char gpsline[FIFO_BUFFER_SIZE+1];
 char *p;
 double longitudearray[10];
 double latitudearray[10];
 int okcounter=0; // only calculate the meanvalue on lat/long values which 
                  // are ok. NMEA data record gives 0 if there is no reception.

 if ( number > 10)
   return 1;

 p=gpsline;

 for (i=0; i<number; i++ ) {
    do {
      outcome=readgpsfifo(p);
      j++;
    }
    while ( outcome != 0 );
    if (debug)
      fprintf(stderr,"NMEA: %s\n",p);
    process_nmea_rmc(p,&longitudearray[okcounter],&latitudearray[okcounter]);
    // ignoriering bad GPS values
    if (debug)
      fprintf(stderr,"Lat/Long: %f/%f \n",
              longitudearray[okcounter],latitudearray[okcounter]);
    if (debug == 2)
    {
      char debugline1[255];
      sprintf( debugline1, "Long/Lat: %f/%f",
               longitudearray[okcounter],latitudearray[okcounter] );
      FbRender_BlitText(20,10*(i+1), BLACK, WHITE, debugline1);
      FbRender_Flush();
      sleep (1);
    }
    

    if ( (longitudearray[okcounter]>0.05) && (latitudearray[okcounter]>0.05) )
     okcounter++; 
 }
    
 *longitude=meanvalue(longitudearray,okcounter);
 *latitude=meanvalue(latitudearray,okcounter);
 fprintf(stderr,"%d of %d evaluations are ok",okcounter,number);
 fprintf(stderr,"\nLONGITUDE: %f\n",*longitude);
 fprintf(stderr,"LATITUDE: %f\n",*latitude);

 return 0;
}

