/* LICENSE:
  =========================================================================
    CMPack'04 Source Code Release for OPEN-R SDK 1.1.5-r2 for ERS7
    Copyright (C) 2004 Multirobot Lab [Project Head: Manuela Veloso]
    School of Computer Science, Carnegie Mellon University
    All rights reserved.
  ========================================================================= */

#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

#include <pthread.h>
#include <semaphore.h>

#include <string>

// pthread_create start routine
typedef void *(*pthread_start)(void *);

#include <stdio.h>

#include <gtk/gtk.h>

#include "gui/callbacks.h"
#include "gui/interface.h"
#include "gui/support.h"

#include "gui/GuiState.h"
#include "gui/UI.h"

#include "State.h"

#include "StreamProcessor.h"
#include "WaveServer.h"

pthread_t SerialProcessorThread;
pthread_t SocketServerThread;
sem_t GuiDataSemaphore;

sem_t RunSemaphore;
bool Run=true;

int guiReadFd=-1;
int streamWriteFd=-1;

void usage(const char * pn) {
  fprintf(stderr,"Usage: %s <dog IP address\n",pn);
}

int
main(int argc, char *argv[]) {

  // setup stuff
  DataControl = new DataInterface;

  if(sem_init(&GuiDataSemaphore,0,1)!=0) {
    perror("unable to create semaphore for GUI\n");
    exit(4);
  }

  if(sem_init(&RunSemaphore,0,1)!=0) {
    perror("unable to create semaphore for run var\n");
    exit(4);
  }

  int pipe_fds[2];
  if(pipe(pipe_fds)!=0) {
    perror("couldn't create pipe to talk to gui\n");
    exit(2);
  }
  guiReadFd     = pipe_fds[0];
  streamWriteFd = pipe_fds[1];

  if(fcntl(guiReadFd,F_SETFL,O_NONBLOCK)!=0) {
    perror("couldn't make gui read fd nonblocking\n");
    exit(3);
  }

  if(pthread_create(&SerialProcessorThread,NULL,SerialProcessor,NULL)!=0) {
    perror("error creating serial thread\n");
    exit(1);
  }

  WaveServerConfig wave_server_config;
#if 1
  StartServer(&SocketServerThread,&wave_server_config,&RunSemaphore,&Run);
#else
  StartServer2(&SocketServerThread,
	       &wave_server_config,
	       &RunSemaphore,
	       &Run,
	       doghost.c_str());
#endif

  gtk_set_locale ();
  gtk_init (&argc, &argv);

  gdk_input_add(guiReadFd, GDK_INPUT_READ, cb_Process_GUI_Pipe, NULL);

  //add_pixmap_directory (PACKAGE_DATA_DIR "/pixmaps");
  //add_pixmap_directory (PACKAGE_SOURCE_DIR "/pixmaps");

  ui=new UI;
  
  GdkColormap *gcm;
  gcm=gdk_colormap_get_system();
  Colors = new GdkColor[NumColors];
  InitializeColors();
  for(int color_idx=0; color_idx<NumColors; color_idx++)
    gdk_colormap_alloc_color(gcm,&Colors[color_idx],false,true);

  // show main window
  ChokeChainWin = create_Gchoke_chain();
  gtk_widget_show (ChokeChainWin);
  if(WorldViewWin==NULL) {
    WorldViewWin = create_Gworld_view();
    gtk_widget_show(WorldViewWin);
  }
  if(EgoViewWin==NULL) {
    EgoViewWin = create_Gego_view();
    gtk_widget_show(EgoViewWin);
  }
  if(VisRLEWin==NULL) {
    VisRLEWin = create_Gvis_rle();
    gtk_widget_show(VisRLEWin);
  }

  gtk_main ();

  sem_wait(&RunSemaphore);
  Run = false;
  sem_post(&RunSemaphore);

  void *return_val;
  if((errno=pthread_join(SocketServerThread,&return_val))!=0) {
    perror("Problem joining with socket thread");
  }
  if((errno=pthread_join(SerialProcessorThread,&return_val))!=0) {
    perror("Problem joining with serial thread");
  }

  return 0;
}
