#include 
#include "vrpn_Connection.h"
#include "nmm_Microscope_Simulator.h"
#include "BCGrid.h"
#include "BCPlane.h"
#include "Topo.h" // added 4/19/99
// #include "BCString.h"
#include 
#include 
#include 
#include 
#include 

TopoFile GTF;  // added 4/19/99





/****************************************************************************
 *  Steve's PARSER CODE DON'T TOUCH
 ****************************************************************************/
// helped find examples of how to do: JuanM

int num_x, num_y;
char * image_name;


//        crib the text directly from there for familiarity's sake.

void usage (const char * argv0) {
  fprintf(stderr, "Usage:  %s -image picture [-grid  ]\n", argv0);
  fprintf(stderr, "    -image:  Use picture specified (no default;  mandatory).\n");
  fprintf(stderr, "    -grid:  Take x by y samples for the grid.\n");
}

void open_image (char * image_name) {
  fprintf(stderr, "working with a function -open_image\n");
  cout << "image_name -> " << image_name << endl;
}

void get_grid_info( int num_x, int num_y) {
  fprintf(stderr, "working with a function get_grid_info\n");
  cout << "num_x -> " << num_x << endl;
  cout << "num_y -> " << num_y << endl;
}
// Parse argv and write the values into s.
// Return nonzero on failure.
// TODO:  add more command-line options from microscape.
      
int parse (int argc, char ** argv) {
    
        int ret = 0;
        int i;
      
        i = 1;
while (i < argc) {
  fprintf(stderr, "parse:  arg %d %s\n", i, argv[i]);

  if (!strcmp(argv[i], "-image")) {
    if (++i >= argc) { 
      ret = 1; 
      continue; 
    }
    
    image_name = argv[i];
    open_image ( image_name );

  }

  else if (strcmp(argv[i], "-grid") == 0) {
      
    if (++i >= argc) 
      usage(argv[0]);
    num_x = atoi(argv[i]);

    if (++i >= argc) 
      usage(argv[0]);
    num_y = atoi(argv[i]);

    get_grid_info(num_x, num_y);
  }

  //  else if (strcmp(argv[i], "-func")) {
  //  if (i++ >= argc)

  /*  else if (strcmp(argv[i], "-region") == 0) {
      
    if (++i >= argc) 
      usage(argv[0]);
    s->x_min = atof(argv[i]);  
      
    if (++i >= argc) 
      usage(argv[0]);
    s->y_min = atof(argv[i]);
      
    if (++i >= argc) 
      usage(argv[0]);
    s->x_max = atof(argv[i]);
      
    if (++i >= argc) 
      usage(argv[0]);
    s->y_max = atof(argv[i]);

//    printf("Will set scan region (%g,%g) to (%g,%g)\n",s->x_min, s->y_min, s->x_max, s->y_max);
  } 

  else if (strcmp(argv[i], "-color") == 0) {
      
    if (++i >= argc) 
      usage(argv[0]);
    s->maxColor[0] = atoi(argv[i]);
      
    if (++i >= argc) 
      usage(argv[0]);
    s->maxColor[1] = atoi(argv[i]);
      
    if (++i >= argc) 
      usage(argv[0]);
    s->maxColor[2] = atoi(argv[i]);
      
    if (++i >= argc) 
      usage(argv[0]);
    s->minColor[0] = atoi(argv[i]);
      
    if (++i >= argc) 
      usage(argv[0]);
    s->minColor[1] = atoi(argv[i]);
      
    if (++i >= argc) 
      usage(argv[0]);
    s->minColor[2] = atoi(argv[i]);
  } 
  */
  else
    ret = 1;

  i++;
}

  // check for mandatory arguments
//if (!s->microscopeName) 
//  ret = 1;

  return ret;
}


/******************************************************************
 End Steve's Parser code
 *****************************************************************/








int handle_quit (void * userdata, vrpn_HANDLERPARAM) 
{
  int * quitNow = (int *) userdata;
  printf("Quitting now...\n");
  *quitNow = 1;

  return 0;  // non-error completion
}

int handle_any_print (void * userdata, vrpn_HANDLERPARAM p) 
{
  vrpn_Connection * c = (vrpn_Connection *) userdata;

  fprintf(stderr, "Got message \"%s\" from \"%s\".\n",
          c->message_type_name(p.type), c->sender_name(p.sender));

  return 0;  // non-error completion
}








int main (int argc, char ** argv) 
{
  long quitType;
  int quitNow = 0;

  int retval;
  retval = parse(argc, argv);
  if (retval) {
      usage(argv[0]);
      exit(0);
  }

  // **************** code added 4/11/99 Steve Silence begin *****************
  // **************** assisted in coding Juan Maturino
  // last changed 4/11/99
  // This is on of 3 constructors in BCGrid, this one reads in pictures
  // loads an actuall picture, soom_z.zfp.
  // READ_FILE is a const in BCGrid.
  //  BCGrid mygrid;
  //  BCPlane *myPlane;
  if(image_name)        // CODE USED IF IMAGE IS TO BE USED
    {
      BCGrid mygrid(num_x,num_y,0,300,0,300, READ_FILE, image_name); // creates new grid
      BCPlane *myPlane = mygrid.getPlaneByName("Z");    // adds plane for Z data
      myPlane = mygrid.getPlaneByName(image_name);      // sets data in Z grid
      FILE* outputfile = fopen("testfile.out", "w");    // write testfile
      mygrid.writeTextFile(outputfile, myPlane);        
      int currentline = 0;                              // intitializes the line to be scanned
      StartServer((num_x), (num_y));                    // starts new sim_server
      set_Surface_Data(myPlane);                        // loads surface into nmm_Microscope_Simulator
      quitType = connection->register_message_type("Server Quit Type");
      connection->register_handler(quitType, handle_quit, &quitNow);
      connection->register_handler(vrpn_ANY_TYPE, handle_any_print,connection);
      float scan_time_diff = .5000000;                  // Time between scanning new line
      float diff_time;                                  // diff b/w begin of prog & check curr time
      struct timeval  t_start, t_now;
      gettimeofday(&t_start, NULL);                     // can access the sec and usec
      while (!quitNow)
        {
          connection->mainloop();
          gettimeofday(&t_now, NULL);
          diff_time = (t_now.tv_sec - t_start.tv_sec) + (t_now.tv_usec - t_start.tv_usec)/1000000.0;
          if((diff_time >= scan_time_diff)&&(mic_Started()==1)) // Checks to see if its time to send another line
            {
              AFMSimulator->spm_report_window_line_data(currentline);   //Sends line data
              gettimeofday(&t_start, NULL);                             //resets timer
              currentline = ((currentline+1)%(num_y-1));                //increments linecount
            }
        }
    }
  else                  // CODE USED IF MATH SURFACE TO BE USED
    {                   // ALMOST THE SAME AS CODE ABOVE
      BCGrid mygrid(num_x,num_y,0,300,0,300);  
      mygrid.addNewPlane("Z","nm", 0);
      BCPlane *myPlane = mygrid.getPlaneByName("Z");
      float point;
      for(int x=0; xsetValue(x, y, (float)(point));
            }
        } 
      FILE* outputfile = fopen("testfile.out", "w");
      mygrid.writeTextFile(outputfile, myPlane);
      int currentline = 0;
      StartServer((num_x), (num_y));
      set_Surface_Data(myPlane);
      quitType = connection->register_message_type("Server Quit Type");
      connection->register_handler(quitType, handle_quit, &quitNow);
      connection->register_handler(vrpn_ANY_TYPE, handle_any_print,connection);
      float scan_time_diff = .5000000;  // Time between scanning new line
      float diff_time;  // diff b/w begin of prog & check curr time
      struct timeval  t_start, t_now;
      gettimeofday(&t_start, NULL);   // can access the sec and usec
      while (!quitNow)
        {
          connection->mainloop();
          gettimeofday(&t_now, NULL);
          diff_time = (t_now.tv_sec - t_start.tv_sec) + (t_now.tv_usec - t_start.tv_usec)/1000000.0;
          if((diff_time >= scan_time_diff)&&(mic_Started()==1))
            {
              AFMSimulator->spm_report_window_line_data(currentline);
              gettimeofday(&t_start, NULL);
              currentline = ((currentline+1)%(num_y-1));
            }
        } 
    }
}