// To run this example do
// 1) start server using
//    % NCSdisplayserver {number windows}
//    This opens the specified number of windows where images will be displayed.
//    The packets ids determine to which window received each image will go.
// 2) test sending images to server using
//    % test_NCSsend ../../FastTrack/images/board.dib
// This sends to the server the same given image in 5 packets with ids 0,...,4


#include "FastTrack.h"
#include "NCS.h"

FT_16GrayImage_T buffer;

int main(int argc, char *argv[])
{
  int sockfd; 
  int rc; 
  int i,nWindows;
  unsigned short id;
  unsigned long packetseq,oldseq=0;
  struct timeval t0,time_stamp,time_sent,time_recv,timeout;

  char str[64];

  // decrease priority
  nice(5);

  ////// initialize gtk /////////////////////////////////////////////
  gtk_init(&argc, &argv);
  gdk_rgb_init();

  if (argc != 2) {
    fprintf(stderr,"%s: wrong number of arguments (%d found, 1 expected)\n",
	    argv[0],argc-1);
    exit(1);
  }
  
  nWindows=atoi(argv[1]);

  FT_8GrayImage_T *Image8=malloc(nWindows*sizeof(FT_8GrayImage_T));
  GtkWidget **window=malloc(nWindows*sizeof(GtkWidget*));

  // create windows
  for(i=0;i<nWindows;i++) {
    printf("Creating window #%d\n",i);
      
    // clear buffer and ask for redraw
    Image8[i].width=320; // FT_MAX_IMAGEWIDTH;
    Image8[i].height=200; //FT_MAX_IMAGEHEIGHT;
    memset(Image8[i].pixels,sizeof(Image8[i].pixels),0);

    sprintf(str,"Image stream #%d",i);
    window[i]=DisplayNewImage(&Image8[i],str);
  }
    
  // init socket
  sockfd=InitRecvUDPSocket(NCS_RECV_PORT); 

  gettimeofday(&t0,NULL);
  while(1) { 
    // process pending events
    ProcessXEvents();

    timeout.tv_sec=2; // used to be .5
    timeout.tv_usec=0;
    rc=RecvUDPSocket(sockfd,      // socket handle                      (input)
		     &id,         // packet sender id                   (output)
		     &packetseq,  // packet sequence number             (output)
		     &timeout,    // timeout for waiting for packet (inp/output)
		     &time_stamp, // data time stamp of packet received (output)
		     &time_sent,  // time packet sent                   (output)
		     &time_recv,  // time packet read from socket       (output)
		     (char*)&buffer,  // buffer where to place data     (output)
		     sizeof(buffer)); // length of data buffer          (output)


    if (rc>0) {
      if (packetseq!=oldseq+1) {
	printf("*** Frame missed: id=%d, oldseq=%lu seq=%lu, len=%d\n",
	       id,packetseq,oldseq,rc); 
      }
      oldseq=packetseq;

      /*
      printf("id=%d, seq=%lu, len=%d, tout=%.3f, stmp=%.3f, sen=%.3f, rec=%.3f, dly=%7.3fms\n",
	     id,packetseq,rc,
	     (float)timeout.tv_sec+.000001*timeout.tv_usec,
	     ((float)(time_stamp.tv_sec-t0.tv_sec))+.000001*(time_stamp.tv_usec-t0.tv_usec),
	     ((float)(time_sent.tv_sec-t0.tv_sec))+.000001*(time_sent.tv_usec-t0.tv_usec),
	     ((float)(time_recv.tv_sec-t0.tv_sec))+.000001*(time_recv.tv_usec-t0.tv_usec),
	     ((float)1000*(time_recv.tv_sec-time_sent.tv_sec))+.001*(time_recv.tv_usec-time_sent.tv_usec)
	     ); 
*/

      if(id<nWindows) {
//	if ((packetseq & 0x7) == 0) {
	  ConvertAnyto8(&buffer,Image8+id);
	  UpdateImageDisplay(window[id]);
//	}
      }
      else {
	printf("id exceeds maximum number of windows\n"); }
    } 
    else {
      //      printf("id=x, seq=xxx, len=%5d, tout=%7.3f\n",rc,(float)timeout.tv_sec+.000001*timeout.tv_usec); 
    }
    
    

  } 
  
  close(sockfd); 
  
  exit(0); 
}

