/* procedure to compare rReceive methods with read
   parameters include read 1 character at a time and as many as can be read at once

   rReceiveA:  original version of rReceive, use read, up to 1 byte at a time
   rReceiveB:  use read, read as many bytes as available until all obtained

   for accurate timings, mutex semaphores not used in this program
*/

#include <MyroC.h>
#include "../MyroC-utilities.h"
#include <unistd.h>      // for read
#include <sys/socket.h>  // for recv
#include <errno.h>       // for errno
#include <stdio.h>       // for printf
#include <time.h>
#include <stdlib.h>      // for time

int socket_num;

/* variables to count number of loop iterations in each receive version */
int iterA;
int iterB;

/**
 * Receives data via bluetooth
 * @param message       a pointer to allocated space, where the data will be stored
 * @param numberOfEchoBytes  number of bytes to be received from the Scribbler 
 * @pew                 space pointed to by message >= numberOfEchoBytes
 */
void rReceiveA (unsigned char * message, int numberOfBytes)
{ int total_read;
  iterA = 0;
  for (total_read=0; total_read<numberOfBytes; )
    {
      if (read (socket_num, message+total_read, 1) > 0)
        {
          // printf("received '%u'\n", message[total_read]&255);
          total_read++;
        }
      iterA++;
    }  
}

void rReceiveB (unsigned char * message, int numberOfBytes)
{ int total_read = 0;
  iterB = 0;
  while (total_read < numberOfBytes)
    {
      total_read += read (socket_num, message+total_read, numberOfBytes-total_read);
      iterB++;
    }
}

/* test and compare all rReceive options
   @parm message:  the command to be issued
   @parm numberOfBytes:  number of response bytes expected
   @printResult:  0 - do not print returned data; 1 - print returned data
*/
void testMethods (char * message, int message_len,
		  int COMMAND_ECHO, int DATA_ECHO,
		  int numberOfBytes, int printResult)
{
  unsigned char * newNameA = malloc (sizeof(char) * numberOfBytes);
  unsigned char * newNameB = malloc (sizeof(char) * numberOfBytes);

  clock_t start_time, end_time;
  double elapsed_time;

  rSend (message, message_len, COMMAND_ECHO, DATA_ECHO, "Command");
  start_time = clock ();
  rReceiveA (newNameA, numberOfBytes);
  end_time = clock ();
  printf ("%3d", iterA);
  elapsed_time = (end_time - start_time) / (double) CLOCKS_PER_SEC;
  printf ("  %7.5lf  ", elapsed_time);

 if (printResult)
    {
      int i;
      for (i = 0; i < numberOfBytes; i++)
	printf ("%c", newNameA[i]);
    }

  rSend (message, message_len, COMMAND_ECHO, DATA_ECHO, "Command");
  start_time = clock ();
  rReceiveB (newNameB, numberOfBytes);
  end_time = clock ();
  printf ("%3d", iterB);
  elapsed_time = (end_time - start_time) / (double) CLOCKS_PER_SEC;
  printf ("  %7.5lf ", elapsed_time);

 if (printResult)
    {
      int i;
      for (i = 0; i < numberOfBytes; i++)
	printf ("%c", newNameB[i]);
    }

  int diffB = 0;

  int i;
  for (i = 0; i < numberOfBytes; i++)
    {
      if (newNameA[i] != newNameB[i])
	diffB++;
    }

  printf ("  %d\n", diffB);

  free (newNameA);
  free (newNameB);
}

int main ()
{

  printf ("program to test time and effort for different rReceive versions\n");
  //socket_num = rConnect ("/dev/tty.IPRE6-365877-DevB");
  socket_num = rConnect ("/dev/tty.IPRE6-365897-DevB");

  rSetName ("this is a test");

  char message[9];

  /* print heading of results */
  printf ("           rReceiveA             rReceiveB             Different\n");
  printf ("Command   iter.  time response  iter.  time response   from RecA\n");
  
  /* rGetName (bytes 0-7) */
  //Message 78 recieves 9 bytes of echo, and 8 bytes of message.
  message[0]= 78; // get first 8 bytes of the robot's 16-byte name
  message[1]= 0;  // not used
  message[2]= 0;  // not used
  message[3]= 0;  // not used
  message[4]= 0;  // not used
  message[5]= 0;  // not used
  message[6]= 0;  // not used
  message[7]= 0;  // not used
  message[8]= 0;  // not used

  printf ("getName1: "); 
  testMethods (message, 9, ECHO_COMMAND_ON, ECHO_SENSOR_OFF, 8, 1);

  /* rGetName (bytes 8-15) */
  message[0]= 64; // get last 8 bytes of the robot's 16-byte name
  message[1]= 0;  // not used
  message[2]= 0;  // not used
  message[3]= 0;  // not used
  message[4]= 0;  // not used
  message[5]= 0;  // not used
  message[6]= 0;  // not used
  message[7]= 0;  // not used
  message[8]= 0;  // not used
    
  printf ("getName2: "); 
  testMethods (message, 9, ECHO_COMMAND_ON, ECHO_SENSOR_OFF, 8, 1);

  /* rTakePicture) */
  message[0]= 64; // get last 8 bytes of the robot's 16-byte name
  message[1]= 0;  // not used
  message[2]= 0;  // not used
  message[3]= 0;  // not used
  message[4]= 0;  // not used
  message[5]= 0;  // not used
  message[6]= 0;  // not used
  message[7]= 0;  // not used
  message[8]= 0;  // not used
    
  printf ("rTakePic: "); 

  Picture pic1 = rTakePicture();
  rDisplayPicture (&pic1, 0, "pic1");
  Picture pic2 = rTakePicture();
  rDisplayPicture (&pic2, 0, "pic2");

  message[0] = 83;
  testMethods (message, 1, ECHO_COMMAND_OFF, ECHO_SENSOR_OFF, 192*256, 0);

  return 0;
}
