// wp2mc.c
//
// use getopt_long to parse options for wp2mc utility
//

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include "wp2m_user_if.h"
#include "calcs.h"
#include "wptList.h"
#include "writeMission.h"


void help(void);
void show_params(void);
int i; //iterator
char userInput[101];              // input string from user
char* file_name;  // set to mission output filename in fileName() in file calcs.c
double surveyLineMeters = 0.0;
double missionTime = 0.0;
int LAUNCH_OFFSET = 500;

// Default Parameters
//
int abortOnTimeout = 1; // 1 if abortOnTimeout == True
int gulperMission = 1;  // 1 if Gulper mission
int yoyoMission = 1;    // 1 if Yoyo mission

// Mission Parameter Default Settings
double maxLegMeters = 3600.00;    // meters between AUV surfacings
double missionSpeed = 1.50;       // meters per second
double missionSpeedSlow = 1.25;
int gpsHits = 30;
double spd = 1.50;
double wayPointDepth = 50.0;
double minDepth = 10.0;
double maxDepth = 90.0;
double abortDepth = 100.0;
double abortAltitude = 2.5;
double abortLockoutDepth = 8.0;

// YoYo Mission Parameter Default Settings:
int yoyoMinAltitude = 15;  // meters
int missionYoyoMinDepth = 10;
int missionYoyoMaxDepth = 90;
int missionYoyoMaxDepthShallow = 20;
double diveAngle = 30.0;

// pointer to waypoints file which will be read in
FILE *waypointFilePtr;

/* Flag set by ‘--verbose’. */
static int verbose_flag;

int interactive_flag = 0;

int main (int argc, char **argv)
  {
    char line[50]= {'\0'};  // line read in from waypoint file
    double latIn = 0.0;     // vars read in from waypoint file
    double lonIn = 0.0;
    int c;

    while ( interactive_flag == 0 )
      {
        static struct option long_options[] =
          {
            {"verbose",     no_argument,   &verbose_flag,     1},
            {"brief",       no_argument,   &verbose_flag,     0},

            /* These options don't set a flag.
              We distinguish them by their indices. */
            {"gpsHits",                    required_argument, 0, 'a'},
            {"gulperMission",              required_argument, 0, 'b'},
            {"abortOnTimeout",             required_argument, 0, 'c'},
            {"yoyoMission",                required_argument, 0, 'd'},
            {"yoyoMinAltitude",            required_argument, 0, 'e'},
            {"missionYoyoMinDepth",               required_argument, 0, 'f'},
            {"missionYoyoMaxDepth",               required_argument, 0, 'g'},
            {"missionYoyoMaxDepthShallow",        required_argument, 0, 'h'},
            {"missionSpeed",               required_argument, 0, 'i'},
            {"missionSpeedSlow",           required_argument, 0, 'j'},
            {"maxLegMeters",               required_argument, 0, 'k'},
            {"minDepth",                   required_argument, 0, 'l'},
            {"maxDepth",                   required_argument, 0, 'm'},
            {"abortDepth",                 required_argument, 0, 'n'},
            {"abortAltitude",              required_argument, 0, 'o'},
            {"abortLockoutDepth",          required_argument, 0, 'p'},
            {"diveAngle",                  required_argument, 0, 'q'},
            {"wayPointDepth",              required_argument, 0, 'r'},
            {"interactive",                no_argument,       0, 'y'},
            {"help",                       no_argument,       0, 'z'},
            {"usage",                      no_argument,       0, 'z'},
            {0, 0, 0, 0}
          };


        /* getopt_long stores the option index here. */
        int option_index = 0;

        c = getopt_long (argc, argv, "abc:d:f:",
                            long_options, &option_index);

        /* Detect the end of the options. */
        if (c == -1)
          break;

        switch (c)
          {
          case 0:
            /* If this option set a flag, do nothing else now. */
            if (long_options[option_index].flag != 0)
              break;
              printf ("option %s", long_options[option_index].name);
            if (optarg)
              printf (" with arg %s", optarg);
              printf ("\n");
              break;


          case 'a':
            //printf ("option -a with value `%s'\n", optarg);
            gpsHits = atoi(optarg);
            break;

          case 'b':
            //printf ("option -b with value `%s'\n", optarg);
            gulperMission = atoi(optarg);
            break;

          case 'c':
            //printf ("option -c with value `%s'\n", optarg);
            abortOnTimeout = atoi(optarg);
            break;

          case 'd':
            //printf ("option -d with value `%s'\n", optarg);
            yoyoMission = atoi(optarg);
            break;

          case 'e':
            //printf ("option -e with value `%s'\n", optarg);
            yoyoMinAltitude = atoi(optarg);
            break;

          case 'f':
            //printf ("option -f with value `%s'\n", optarg);
            missionYoyoMinDepth = atoi(optarg);
            break;

          case 'g':
            //printf ("option -g with value `%s'\n", optarg);
            missionYoyoMaxDepth = atoi(optarg);
            break;

          case 'h':
            //printf ("option -h with value `%s'\n", optarg);
            missionYoyoMaxDepthShallow = atoi(optarg);
            break;

          case 'i':
            //printf ("option -i with value `%s'\n", optarg);
            missionSpeed = atof(optarg);
            break;

          case 'j':
            //printf ("option -j with value `%s'\n", optarg);
            missionSpeedSlow =  atof(optarg);
            break;

          case 'k':
            //printf ("option -k with value `%s'\n", optarg);
            maxLegMeters = atof(optarg);
            break;

          case 'l':
            //printf ("option -l with value `%s'\n", optarg);
            minDepth = atof(optarg);
            break;

          case 'm':
            //printf ("option -m with value `%s'\n", optarg);
            maxDepth = atof(optarg);
            break;

          case 'n':
            //printf ("option -n with value `%s'\n", optarg);
            abortDepth = atof(optarg);
            break;

          case 'o':
            //printf ("option -o with value `%s'\n", optarg);
            abortAltitude = atof(optarg);
            break;

          case 'p':
            //printf ("option -p with value `%s'\n", optarg);
            abortLockoutDepth = atof(optarg);
            break;

          case 'q':
            //printf ("option -q with value `%s'\n", optarg);
            diveAngle = atof(optarg);
            break;

          case 'r':
            //printf ("option -r with value `%s'\n", optarg);
            wayPointDepth = atof(optarg);
            break;

          case 'y':
            //printf("\nInteractive Mode\n");
            interactive_flag = 1;
            break;

          case 'z':
          case '?':
            //printf ("option -z\n");
            help();
            break;

          default:
            abort ();
          }
      }

  if (verbose_flag)
    {
    // display the parameters
    show_params();
    }


  if ( interactive_flag == 1 )
    {    //  printf("\n\n***** interactive_flag is set ***** \n\n");
    // prompt for waypoints filename and parameters
    //

    // Interactive section of code begins
    //

    // Prompt for filename

    printf("\n\nWelcome to Waypoints to CTD_AUV mission utility.\n");
    printf("Waypoint lat/lon's must be in decimal degree format.\n");
    printf("eg: 36.8167 -121.8170\n");
    printf("What's the name of the waypoint file ? \n");
    printf(" > ");
    fgets(userInput, 100, stdin);
    for ( i = 0; i < 100; i++ )  // strip the newline character
     {
      if(userInput[i]== '\n')
      userInput[i] = '\0';
     }
    if((waypointFilePtr=fopen(userInput, "r"))==NULL)
     {
      printf("cannot open file %s ", userInput);
      exit(1);
     }
    else
     {
      // display waypoints file contents
      char x;
      printf ("\n\nWaypoint filename: \n %s \n", userInput);
      printf("\n\nWaypoint List:\n\n");
      while ((x = getc(waypointFilePtr)) != EOF )
      printf("%c", x);
      rewind(waypointFilePtr);
     }

    // present default mission parameters, ask if change
    //
    queryMissionParameters();

    // inquire if this is a YOYO mission
    //
    yoyoMission = queryYoyo();

    // If yoyoMission ==1, present yoyo parameters, ask if change
    // if this is not a YOYO mission, present default waypoint behavior depth, ask if change
    //
    if ( yoyoMission ==1 )
      {
      queryYoYoParameters();
      }
    else
      {
      wayPointDepth = get_wayPointDepth();
      }

    // inquire if this is a Gulper mission, int gulperMission set to 1 if true
    //
    gulperMission = queryGulper();

    // Interactive section of code ends
    //
    }


    // command line waypoints file handling
    //
    if ( interactive_flag != 1 )
    {
      if (argv[optind] != NULL)
       {
        if((waypointFilePtr=fopen(argv[optind], "r"))==NULL)
           {
             printf("***CANNOT OPEN FILE %s ", argv[optind]);
             help();
             exit(1);
           }
        else  // we have a valid waypoints file
           {
             if (verbose_flag)
             {
               // display waypoints file contents
               //char x;
               //printf ("Waypoint filename: \n %s \n", argv[optind]);
               // while ((x = getc(waypointFilePtr)) != EOF )
               //printf("%c", x);

               // display the parameters
               //
               //show_params();


             }
             // process the waypoints file

           }
       }
      else
       {
        printf("\n\n*** WAYPOINTS FILENAME IS MISSING ***\n");
        help();
        exit(1);
       }
    }

  //*************************************
  // construct list, process, write output files
  //

  // read in the "waypoints" file, assign each lat/lon to a DLL node
  //
  while ( fgets(line, sizeof(line), waypointFilePtr) != NULL)
  {
    //printf("\n\n Read in waypoints file \n\n");
    //printf(" line: %s ", line);
    sscanf ( line, "%lf %lf", &latIn, &lonIn);
    //printf ( "line input: %s\n", line );
    //printf(" latIn %lf, lonIn %lf\n", latIn, lonIn);
    insertLatLonEnd(latIn, lonIn);
  }

  // uncomment to display the list:
  //displayFwd();

  struct node *currNodePtr;
  if(headNodePtr==NULL)
  {
    printf("list is empty\n");
    exit(1);
  }
  currNodePtr=headNodePtr;
  while(currNodePtr->nextPtr!=NULL)  // traverse list
  {
    currNodePtr->legMeters = dist(currNodePtr->Lat, currNodePtr->Lon, currNodePtr->nextPtr->Lat, currNodePtr->nextPtr->Lon);
    currNodePtr->heading = heading(currNodePtr->Lat, currNodePtr->Lon, currNodePtr->nextPtr->Lat, currNodePtr->nextPtr->Lon);
    currNodePtr=currNodePtr->nextPtr;
  }

  // add nodes if leg distances > maxLegMeters
  //
  insertIfBig_legMeters();

  // fill in blank waypoint locations
  //
  fillBlankLatLons();

  // fill in member wptNumber
  //
  itemizeList();

  // fill in member legSecs
  //
  calcWaypointTimes();

  // create launch waypoint 500 meters from start of line recip course
  //
  launch_waypoint();  // create launch waypoint 500 meters from start of line recip course

  //  *****  UNCOMMENT TO DISPLAY LINKED LIST  ***********
  //  displayFwd();
  //  displayRev();
  //  printf("\n\n<cr> to continue ");
  //  getch();

  // calculate expected mission time
  //
  missionTime = calcMissionTime();
  //  printf("\n\n missionTime = %g \n\n", missionTime);

  //  write out the mission script
  //
  writeMission();

  //  write out Winfrog waypoints list
  //
  writeWaypoints();

  //  writeout Winfrog survey line
  //
  writeSurLine();

  //  write csv file for Excel import
  //
  write_csvFwd();

  // clean up
  //
  fclose(waypointFilePtr);

  // free memory




    return(0);
  } // end of main()




void help(void)
  {
    printf("\nwp2mc Command Line Parameters:\n\n");
    printf("--verbose.......sets verbose mode\n");
    printf("--interactive...sets interactive mode\n");
    printf("                                    ( Default: )\n");
    printf("--gpsHits ..........................( 30 )\n");
    printf("--gulperMission.....................( 1 = true)\n");
    printf("--abortOnTimeout....................( 1 = true )\n");
    printf("--yoyoMission.......................( 1 = true )\n");
    printf("--yoyoMinAltitude...................( 15 )\n");
    printf("--missionYoyoMinDepth...............( 10 )\n");
    printf("--missionYoyoMaxDepth ..............( 90 )\n");
    printf("--missionYoyoMaxDepthShallow........( 20 )\n");
    printf("--missionSpeed......................( 1.5 )\n");
    printf("--missionSpeedSlow..................( 1.25)\n");
    printf("--maxLegMeters......................( 3600.0 )\n");
    printf("--minDepth..........................( 10.0 )\n");
    printf("--maxDepth..........................( 90.0 )\n");
    printf("--abortDepth........................( 100.0 )\n");
    printf("--abortAltitude.....................( 2.5 )\n");
    printf("--abortLockoutDepth.................( 8.0 )\n");
    printf("--diveAngle double..................( 30.0 )\n");
    printf("--wayPointDepth.....................( 50.0 )\n");
    printf("\nWaypoint filename must follow arguments:\n");
    printf("Latitude Longitude, Decimal Degrees format\n");
    printf("eg: \n");
    printf("36.8167 -121.8171\n");
    printf("36.8215 -121.7986\n\n");

    return;
  }

void show_params(void)
  {
    printf("\n\n Parameters Set:  \n");
    printf("gpsHits...........................%d\n", gpsHits);
    printf("gulperMission.....................%d\n", gulperMission);
    printf("abortOnTimeout....................%d\n", abortOnTimeout);
    printf("yoyoMission.......................%d\n", yoyoMission);
    printf("yoyoMinAltitude...................%d\n", yoyoMinAltitude);
    printf("missionYoyoMinDepth...............%d\n", missionYoyoMinDepth);
    printf("missionYoyoMaxDepth...............%d\n", missionYoyoMaxDepth);
    printf("missionYoyoMaxDepthShallow........%d\n", missionYoyoMaxDepthShallow);
    printf("missionSpeed......................%.3f\n", missionSpeed);
    printf("missionSpeedSlow..................%.3f\n", missionSpeedSlow);
    printf("maxLegMeters......................%.1f\n", maxLegMeters);
    printf("minDepth..........................%.1f\n", minDepth);
    printf("maxDepth..........................%.1f\n", maxDepth);
    printf("abortDepth........................%.1f\n", abortDepth);
    printf("abortAltitude.....................%.1f\n", abortAltitude);
    printf("abortLockoutDepth.................%.1f\n", abortLockoutDepth);
    printf("diveAngle.........................%.1f\n", diveAngle);
    printf("wayPointDepth.....................%.1f\n", wayPointDepth);

    return;
  }

