// writeMission.c
//  constructs a mission file
//

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <conio.h>
#include <string.h>
#include "wp2m_user_if.h"
#include "calcs.h"
#include "wptList.h"

extern int yoyoMinAltitude;
extern double missionSpeed;
extern double missionSpeedSlow;
extern int missionYoyoMinDepth;
extern int missionYoyoMaxDepth;
extern double minDepth;
extern double maxDepth;
extern double abortDepth;
extern double abortAltitude;
extern double abortLockoutDepth;
extern double missionTime;
extern int gpsHits;
extern int gulperMission;
extern int yoyoMission;
extern double wayPointDepth;
extern int abortOnTimeout; // 1 TRUE, 0 FALSE

int missionTimeInt;
int legSecsInt;
int headingInt;

extern double surveyLineMeters;  // added 28 Sept 14

// vars used in co - ordinate conversion
//  decimal degrees format to degrees and decimal minutes format
  double degreeOnly;
  double degreeDecFraction;
  double decMin;


int writeMission()
{
  struct node *currNodePtr;

  FILE *ofp; // mission output file pointer
  char *missionFileName;
  missionFileName = fileName();
  strcat ( missionFileName, "cfg" );

//  printf("\n\n **** begin writing file %s **** \n", missionFileName);
//  getch();
//  missionFilePtr = fopen(missionFileName, "w");
  if((ofp = fopen(missionFileName, "w"))==NULL)
    {
      printf("cannot open mission output file %s ", missionFileName);
      exit(1);
    }

  fprintf(ofp,"# Mission Filename: %s\n", missionFileName);
  fprintf(ofp,"#\n");
  fprintf(ofp,"#\n");
  fprintf(ofp,"#                   *** CAUTION *** \n");
  fprintf(ofp,"#   *** THIS MISSION GENERATED WITH UTILITY wp2mc ***\n");
  fprintf(ofp,"#               *** UNPROVEN CODE ***\n");
  fprintf(ofp,"#\n");
  fprintf(ofp,"#               *** LAUNCH WAYPOINT ***\n");
  fprintf(ofp,"#               LAT/LON: %3.4f %3.4f\n", headNodePtr->Lat, headNodePtr->Lon);
  fprintf(ofp,"#\n");
  fprintf(ofp,"#               *** INITIAL HEADING *** \n");
  fprintf(ofp,"#                        %3.1f  \n", headNodePtr->heading);
  fprintf(ofp,"#\n");

  if (abortOnTimeout == 1)
  {
    fprintf(ofp,"#             *** abortOnTimeout is True ***\n");
  }
  else
  {
    fprintf(ofp,"#             *** abortOnTimeout is False ***\n");
  }
  fprintf(ofp,"#\n");

  if (gulperMission==1)
  {
  fprintf(ofp,"#   *** GULPERS ARMED AT START OF MISSION ***\n");
  fprintf(ofp,"# *** MOVE THE ARMING BEHAVIOR IF NECESSARY ***\n");
  fprintf(ofp,"#\n");
  }

  if ( yoyoMission == 1 )
  {
  fprintf(ofp,"#define MISSION_YOYO_MIN_DEPTH %d\n", missionYoyoMinDepth);
  fprintf(ofp,"#define MISSION_YOYO_MAX_DEPTH %d\n", missionYoyoMaxDepth);
  fprintf(ofp,"#define YOYO_MIN_ALTITUDE %d\n", yoyoMinAltitude);
  }
  fprintf(ofp,"#define MISSION_SPEED %.3f\n", missionSpeed);
  fprintf(ofp,"#define MISSION_SPEED_SLOW %.3f\n", missionSpeedSlow);
  // added 28 Sept 14 expected survey line total distance in meters
  fprintf(ofp,"\n# Expected survey line distance: %.1f meters\n", surveyLineMeters);  // added 28 Sept 14 );
  fprintf(ofp,"# Expected mission time: %.1f seconds\n",  missionTime );   // added 27 Sept 14
  fprintf(ofp,"#    %.0f hours\n", trunc ( ( missionTime / 3600 ) ) );
  fprintf(ofp,"#    %d minutes\n", ( (int) missionTime % 3600 ) / 60 );

// convert double var missionTime to int missionTimeInt
  missionTimeInt =  ( missionTime  * 1.2 );

  fprintf(ofp,"\n# mission timer set to 120%% of estimated time of mission\n");
  fprintf(ofp,"behavior missionTimer {\n");
  fprintf(ofp,"timeOut = %d;\n", missionTimeInt);
  fprintf(ofp,"}\n");

  fprintf(ofp,"\n# depth envelope set to commanded + 5 m, abort at commanded + 10\n");
  fprintf(ofp,"behavior depthEnvelope {\n");
  fprintf(ofp," minDepth          = %.1f;\n", minDepth);
  fprintf(ofp," maxDepth          = %.1f;\n", maxDepth);
  fprintf(ofp," abortDepth        = %.1f;\n", abortDepth);
  fprintf(ofp," abortAltitude     = %.1f;\n", abortAltitude);
  fprintf(ofp," abortLockoutDepth = %.1f;\n", abortLockoutDepth);
  fprintf(ofp,"}\n");

  fprintf(ofp,"\nbehavior getgps {\n");
  fprintf(ofp,"duration       = 1800;\n");
  fprintf(ofp,"minHits        = 300;\n");

  if (abortOnTimeout == 1)
  {
    fprintf(ofp,"abortOnTimeout = True;\n");
  }
  else
  {
    fprintf(ofp,"abortOnTimeout = False;\n");
  }
  fprintf(ofp,"}\n");

  fprintf(ofp,"\n# ***** Mission Ends ^ *****\n");


// START writing final waypoint
//  spiral ascent
//
  currNodePtr=tailNodePtr;
  fprintf(ofp,"\nbehavior ascend {\n");
  fprintf(ofp,"duration         = 1200;\n");
  fprintf(ofp,"horizontalMode   = rudder;\n");  // ascend in a spiral
  fprintf(ofp,"horizontal       = 5;\n");
  fprintf(ofp,"pitch            = 20;\n");
  fprintf(ofp,"speed            = 1.5;\n");
  fprintf(ofp,"endDepth         = 2;\n");
  fprintf(ofp,"}\n");

  if ( yoyoMission == 1 )
  {
  fprintf(ofp,"\nbehavior waypoint_yoyo  {\n");
  fprintf(ofp,"# leg distance = %.1f;\n", currNodePtr->prevPtr->legMeters);
  // print comment line for lat / lon in degrees and decimal minutes format
    degreeOnly = trunc ( currNodePtr->Lat );              // lat
    degreeDecFraction = currNodePtr->Lat - degreeOnly;
    if ( degreeDecFraction < 0.0 )
      {
      degreeDecFraction = degreeDecFraction * -1.0;
      };
    decMin = degreeDecFraction * 60.0;
    fprintf(ofp, "# N%.0f %.4f",degreeOnly, decMin);

    degreeOnly = trunc ( currNodePtr->Lon );              // lon
    degreeDecFraction = currNodePtr->Lon - degreeOnly;
    if ( degreeDecFraction < 0.0 )
      {
      degreeDecFraction = degreeDecFraction * -1.0;
      };
    decMin = degreeDecFraction * 60.0;
    fprintf(ofp, " W%d %.4f\n", abs(rint(degreeOnly)), decMin);

  fprintf(ofp,"latitude      = %.4f;\n", currNodePtr->Lat);
  fprintf(ofp,"longitude     = %.4f;\n", currNodePtr->Lon);
  fprintf(ofp,"captureRadius = 10;\n");

  legSecsInt = rint ( currNodePtr->prevPtr->legSecs );  // convert double legSecs to int legSecsInt

  fprintf(ofp,"duration      = %d;\n", legSecsInt);
  fprintf(ofp,"speed         = MISSION_SPEED;\n");
  fprintf(ofp,"minDepth      = MISSION_YOYO_MIN_DEPTH;\n");
  fprintf(ofp,"maxDepth      = MISSION_YOYO_MAX_DEPTH;\n");
  fprintf(ofp,"minAltitude   = YOYO_MIN_ALTITUDE;\n");
  fprintf(ofp,"maxCycles     = 2000;\n");
  fprintf(ofp,"}\n");
  }
  else
  {
  fprintf(ofp,"\n# waypoint behavior\n");
  fprintf(ofp,"behavior waypoint {\n");
  fprintf(ofp,"# leg distance = %.1f;\n", currNodePtr->prevPtr->legMeters);

    // print comment line for lat / lon in degrees and decimal minutes format
    degreeOnly = trunc ( currNodePtr->Lat );              // lat
    degreeDecFraction = currNodePtr->Lat - degreeOnly;
    if ( degreeDecFraction < 0.0 )
      {
      degreeDecFraction = degreeDecFraction * -1.0;
      };
    decMin = degreeDecFraction * 60.0;
    fprintf(ofp, "# N%.0f %.4f",degreeOnly, decMin);

    degreeOnly = trunc ( currNodePtr->Lon );              // lon
    degreeDecFraction = currNodePtr->Lon - degreeOnly;
    if ( degreeDecFraction < 0.0 )
      {
      degreeDecFraction = degreeDecFraction * -1.0;
      };
    decMin = degreeDecFraction * 60.0;
    fprintf(ofp, " W%d %.4f\n", abs(rint(degreeOnly)), decMin);


  fprintf(ofp,"latitude      = %.4f;\n", currNodePtr->Lat);
  fprintf(ofp,"longitude     = %.4f;\n", currNodePtr->Lon);
  fprintf(ofp,"captureRadius = 10; \n");
  fprintf(ofp,"duration      = %.1f;\n", currNodePtr->prevPtr->legSecs);
  fprintf(ofp,"speed         = MISSION_SPEED; \n");
  fprintf(ofp,"depth         = %.1f; \n", wayPointDepth);
  fprintf(ofp,"}\n");
  }

  fprintf(ofp,"\n# Descend behavior to 5 meters\n");
  fprintf(ofp,"behavior descend {\n");
  fprintf(ofp,"horizontalMode  = heading;\n");

  headingInt = rint ( currNodePtr->prevPtr->heading );

  fprintf(ofp,"horizontal      = %d;\n", headingInt );
  fprintf(ofp,"pitch           = -30;\n");
  fprintf(ofp,"speed           = 1.5;\n");
  fprintf(ofp,"maxDepth        = 5;\n");
  fprintf(ofp,"minAltitude     = 9;\n");
  fprintf(ofp,"duration        = 60;\n");
  fprintf(ofp,"}\n");

  fprintf(ofp,"\n# setpoint on surface to gather momentum\n");
  fprintf(ofp,"behavior setpoint {\n");
  fprintf(ofp,"duration     = 30;\n");

  headingInt = rint ( currNodePtr->prevPtr->heading );

  fprintf(ofp,"heading      = %d;\n", headingInt );
  fprintf(ofp,"speed        = 1.5;\n");
  fprintf(ofp,"verticalMode = pitch;\n");
  fprintf(ofp,"pitch        = 0;\n");
  fprintf(ofp,"}\n");

  fprintf(ofp,"\nbehavior getgps {\n");
  fprintf(ofp,"duration       = 300;\n");
  fprintf(ofp,"minHits        = %d;\n", gpsHits);

  if (abortOnTimeout == 1)
  {
    fprintf(ofp,"abortOnTimeout = True;\n");
  }
  else
  {
    fprintf(ofp,"abortOnTimeout = False;\n");
  }


  fprintf(ofp,"}\n");

  fprintf(ofp,"\n# ***** FINAL WAYPOINT NUMBER: %d ^ *****\n", currNodePtr->wptNumber);

// END writing final waypoint


//  START Main waypoint - writing loop
//   start writing segments at one segment before tail of list
//   stop writing segments when at the head
//
  currNodePtr=tailNodePtr->prevPtr;
  while(currNodePtr->prevPtr!=NULL)  // need to stop the loop one node before the head of the list
  {
  fprintf(ofp,"\nbehavior ascend {\n");
  fprintf(ofp,"duration         = 1200;\n");

// ascend behavior -- three possibilities
//  final waypoint: ascend spiral  *** need to implement ***
//  heading change: ascend spiral
//  no heading change: ascend straight ahead

  if ( fabs( ( currNodePtr->heading ) - ( currNodePtr->prevPtr->heading ) ) > 70.0 ) // || ( currNodePtr->prevPtr == NULL )
  {
    fprintf(ofp,"horizontalMode   = rudder;\n");  // ascend in a spiral
    fprintf(ofp,"horizontal       = 5;\n");
  }
  else
  {
    fprintf(ofp,"horizontalMode   = heading;\n"); // ascend straight ahead
    headingInt = rint ( currNodePtr->prevPtr->heading );
    fprintf(ofp,"horizontal       = %d;\n", headingInt);
  }

  fprintf(ofp,"pitch            = 20;\n");
  fprintf(ofp,"speed            = 1.5;\n");
  fprintf(ofp,"endDepth         = 2;\n");
  fprintf(ofp,"}\n");

  if ( yoyoMission == 1 )
  {
  fprintf(ofp,"\nbehavior waypoint_yoyo  {\n");
  fprintf(ofp,"# leg distance = %.1f;\n", currNodePtr->prevPtr->legMeters);  //

    // print comment line for lat / lon in degrees and decimal minutes format
    degreeOnly = trunc ( currNodePtr->Lat );              // lat
    degreeDecFraction = currNodePtr->Lat - degreeOnly;
    if ( degreeDecFraction < 0.0 )
      {
      degreeDecFraction = degreeDecFraction * -1.0;
      };
    decMin = degreeDecFraction * 60.0;
    fprintf(ofp, "# N%.0f %.4f",degreeOnly, decMin);

    degreeOnly = trunc ( currNodePtr->Lon );              // lon
    degreeDecFraction = currNodePtr->Lon - degreeOnly;
    if ( degreeDecFraction < 0.0 )
      {
      degreeDecFraction = degreeDecFraction * -1.0;
      };
    decMin = degreeDecFraction * 60.0;
    fprintf(ofp, " W%d %.4f\n", abs(rint(degreeOnly)), decMin);


  fprintf(ofp,"latitude      = %.4f;\n", currNodePtr->Lat);
  fprintf(ofp,"longitude     = %.4f;\n", currNodePtr->Lon);
  fprintf(ofp,"captureRadius = 10;\n");

  legSecsInt = rint ( currNodePtr->prevPtr->legSecs );  // convert double legSecs to int legSecsInt

  fprintf(ofp,"duration      = %d;\n", legSecsInt);
  fprintf(ofp,"speed         = MISSION_SPEED;\n");
  fprintf(ofp,"minDepth      = MISSION_YOYO_MIN_DEPTH;\n");
  fprintf(ofp,"maxDepth      = MISSION_YOYO_MAX_DEPTH;\n");
  fprintf(ofp,"minAltitude   = YOYO_MIN_ALTITUDE;\n");
  fprintf(ofp,"maxCycles     = 2000;\n");
  fprintf(ofp,"}\n");
  }
  else
  {
  fprintf(ofp,"\n# waypoint behavior\n");
  fprintf(ofp,"behavior waypoint {\n");
  fprintf(ofp,"# leg distance = %.1f;\n", currNodePtr->prevPtr->legMeters);

    // print comment line for lat / lon in degrees and decimal minutes format
    degreeOnly = trunc ( currNodePtr->Lat );              // lat
    degreeDecFraction = currNodePtr->Lat - degreeOnly;
    if ( degreeDecFraction < 0.0 )
      {
      degreeDecFraction = degreeDecFraction * -1.0;
      };
    decMin = degreeDecFraction * 60.0;
    fprintf(ofp, "# N%.0f %.4f",degreeOnly, decMin);

    degreeOnly = trunc ( currNodePtr->Lon );              // lon
    degreeDecFraction = currNodePtr->Lon - degreeOnly;
    if ( degreeDecFraction < 0.0 )
      {
      degreeDecFraction = degreeDecFraction * -1.0;
      };
    decMin = degreeDecFraction * 60.0;
    fprintf(ofp, " W%d %.4f\n", abs(rint(degreeOnly)), decMin);


  fprintf(ofp,"latitude      = %.4f;\n", currNodePtr->Lat);
  fprintf(ofp,"longitude     = %.4f;\n", currNodePtr->Lon);
  fprintf(ofp,"captureRadius = 10; \n");
  fprintf(ofp,"duration      = %.1f;\n", currNodePtr->prevPtr->legSecs);
  fprintf(ofp,"speed         = MISSION_SPEED; \n");
  fprintf(ofp,"depth         = %.1f; \n", wayPointDepth);
  fprintf(ofp,"}\n");
  }

  fprintf(ofp,"\n# Descend behavior to 5 meters\n");
  fprintf(ofp,"behavior descend {\n");
  fprintf(ofp,"horizontalMode  = heading;\n");

  headingInt = rint ( currNodePtr->prevPtr->heading );

  fprintf(ofp,"horizontal      = %d;\n", headingInt );
  fprintf(ofp,"pitch           = -30;\n");
  fprintf(ofp,"speed           = 1.5;\n");
  fprintf(ofp,"maxDepth        = 5;\n");
  fprintf(ofp,"minAltitude     = 9;\n");
  fprintf(ofp,"duration        = 60;\n");
  fprintf(ofp,"}\n");

  fprintf(ofp,"\n# setpoint on surface to gather momentum\n");
  fprintf(ofp,"behavior setpoint {\n");
  fprintf(ofp,"duration     = 30;\n");

  headingInt = rint ( currNodePtr->prevPtr->heading );

  fprintf(ofp,"heading      = %d;\n", headingInt );
  fprintf(ofp,"speed        = 1.5;\n");
  fprintf(ofp,"verticalMode = pitch;\n");
  fprintf(ofp,"pitch        = 0;\n");
  fprintf(ofp,"}\n");

  fprintf(ofp,"\nbehavior getgps {\n");
  fprintf(ofp,"duration       = 300;\n");
  fprintf(ofp,"minHits        = %d;\n", gpsHits);

  if (abortOnTimeout == 1)
  {
    fprintf(ofp,"abortOnTimeout = True;\n");
  }
  else
  {
    fprintf(ofp,"abortOnTimeout = False;\n");
  }


  fprintf(ofp,"}\n");

  fprintf(ofp,"\n# ***** WAYPOINT NUMBER: %d ^ *****\n", currNodePtr->wptNumber);

  currNodePtr=currNodePtr->prevPtr;
  }
//  END Main waypoint - writing loop


  if (gulperMission==1)
  {
  fprintf(ofp,"\n#Arm UNFIRED gulpers for adaptive firing#\n");
  fprintf(ofp,"behavior ArmTheGulper{\n");
  fprintf(ofp,"duration = 5;\n");
  fprintf(ofp,"gulper0 = 1;\n");
  fprintf(ofp,"gulper1 = 1;\n");
  fprintf(ofp,"gulper2 = 1;\n");
  fprintf(ofp,"gulper3 = 1;\n");
  fprintf(ofp,"gulper4 = 1;\n");
  fprintf(ofp,"gulper5 = 1;\n");
  fprintf(ofp,"gulper6 = 1;\n");
  fprintf(ofp,"gulper7 = 1;\n");
  fprintf(ofp,"gulper8 = 1;\n");
  fprintf(ofp,"gulper9 = 1;\n");
  fprintf(ofp,"gulper10 = 1;\n");
  fprintf(ofp,"gulper11 = 1;\n");
  fprintf(ofp,"gulper12 = 1;\n");
  fprintf(ofp,"gulper13 = 1;\n");
  fprintf(ofp,"gulper14 = 1;\n");
  fprintf(ofp,"gulper15 = 1;\n");
  fprintf(ofp,"gulper16 = 1;\n");
  fprintf(ofp,"gulper17 = 1;\n");
  fprintf(ofp,"gulper18 = 1;\n");
  fprintf(ofp,"gulper19 = 1;\n");
  fprintf(ofp,"}\n");
  }

  fprintf(ofp,"\n# ***** LAUNCH WAYPOINT 0 *****\n");
  fprintf(ofp,"# LAT/LON: %.4f %.4f\n", headNodePtr->Lat, headNodePtr->Lon);

    // print comment line for lat / lon in degrees and decimal minutes format
    degreeOnly = trunc ( headNodePtr->Lat );              // lat
    degreeDecFraction = headNodePtr->Lat - degreeOnly;
    if ( degreeDecFraction < 0.0 )
      {
      degreeDecFraction = degreeDecFraction * -1.0;
      };
    decMin = degreeDecFraction * 60.0;
    fprintf(ofp, "# N%.0f %.4f",degreeOnly, decMin);

    degreeOnly = trunc ( headNodePtr->Lon );              // lon
    degreeDecFraction = headNodePtr->Lon - degreeOnly;
    if ( degreeDecFraction < 0.0 )
      {
      degreeDecFraction = degreeDecFraction * -1.0;
      };
    decMin = degreeDecFraction * 60.0;
    fprintf(ofp, " W%d %.4f\n", abs(rint(degreeOnly)), decMin);


  fprintf(ofp,"# INITIAL HEADING:  %.1f  \n", headNodePtr->heading);

  fclose(ofp);

  printf(" **** Wrote mission script: %s **** \n", missionFileName);

  return(0);
}

int writeWaypoints()
{
  FILE *wofp; // waypoints output file pointer

//  printf("\n\n ------writeWaypoints()------\n\n");

  char *waypointFileName;
  waypointFileName = malloc(25);
  waypointFileName = fileName();
  strcat ( waypointFileName, "wpt" );

//  strcat ( waypointFileName, "\0" );
//  printf("\n %s \n", waypointFileName);

  if((wofp = fopen(waypointFileName, "w"))==NULL)
  {
    printf("cannot open waypoint output file %s ", waypointFileName);
    exit(1);
  }
  struct node *currNodePtr;
  currNodePtr=headNodePtr;
  while(currNodePtr->nextPtr!=NULL)
  {
//    printf("Waypoint: %d\n", currNodePtr->wptNumber);

    fprintf(wofp,"%d,N%.4f,%.4f,5,250.000,0.0,0.0,255,0.000  \n", currNodePtr->wptNumber, currNodePtr->Lat, currNodePtr->Lon );

    currNodePtr=currNodePtr->nextPtr;
  }

  currNodePtr=tailNodePtr;
  fprintf(wofp,"%d,N%.4f,%.4f,5,250.000,0.0,0.0,255,0.000  \n", currNodePtr->wptNumber, currNodePtr->Lat, currNodePtr->Lon );

 printf("\n **** Wrote waypoints file : %s ****\n", waypointFileName);
 fclose(wofp);
  return ( 0 );
}


int writeSurLine(void)
{

  FILE *sofp; // surveyline output file pointer

  char *surLineFileName;
  surLineFileName = malloc(25);
  surLineFileName = fileName();
  strcat ( surLineFileName, "pts" );

//  strcat ( waypointFileName, "\0" );
//  printf("\n %s \n", surLineFileName);

  if((sofp = fopen(surLineFileName, "w"))==NULL)
  {
    printf("cannot open surveyline output file %s ", surLineFileName);
    exit(1);
  }

  fprintf(sofp,"0,%s,0,0.000,0.000,1,3,255,0,0.200,0,0,1.000 \n",surLineFileName);
  struct node *currNodePtr;
  currNodePtr=headNodePtr;
  while(currNodePtr->nextPtr!=NULL)
  {
//    printf("Waypoint: %d\n", currNodePtr->wptNumber);

    fprintf(sofp,"1,%.4f,%.4f,0.00m,0.00m,0.0,0.0,0.0  \n", currNodePtr->Lat, currNodePtr->Lon );

    currNodePtr=currNodePtr->nextPtr;
  }
  currNodePtr=tailNodePtr;
  fprintf(sofp,"1,%.4f,%.4f,0.00m,0.00m,0.0,0.0,0.0  \n", currNodePtr->Lat, currNodePtr->Lon );

  printf("\n **** Wrote survey line : %s ****\n", surLineFileName);
  fclose(sofp);
  return (0);
}



// write_csvFwd()
//  writes DLL as a comma separated file for Excel import
//  added 6 Aug 14
//
int write_csvFwd(void)
{


  FILE *csvofp; // comma separated value output file pointer

  char *csvFileName;
  csvFileName = malloc(25);
  csvFileName = fileName();
  strcat ( csvFileName, "csv" );

//  strcat ( waypointFileName, "\0" );
//  printf("\n %s \n", surLineFileName);

  if((csvofp = fopen(csvFileName, "w"))==NULL)
  {
    printf("cannot open csv output file %s ", csvFileName);
    exit(1);
  }

  struct node *currNodePtr;
  if(headNodePtr==NULL)
  {
    printf("dll is empty\n");
    return 1;
  }
  currNodePtr=headNodePtr;

  fprintf(csvofp, "\nWpt #, Lat, Lon, Hdg, Mtrs, Secs");  // header line

  while(currNodePtr!=NULL)
  {
    fprintf(csvofp, "\n\n%d,", currNodePtr->wptNumber);   // waypoint data line, decimal degrees format
    fprintf(csvofp, "%.4f,", currNodePtr->Lat);          // was %.4f
    fprintf(csvofp, "%.4f,", currNodePtr->Lon);          // was %.4f
    fprintf(csvofp, "%.1f,", rint(currNodePtr->heading));
    fprintf(csvofp, "%.1f,", rint(currNodePtr->legMeters));
    fprintf(csvofp, "%.1f,", rint(currNodePtr->legSecs));
                                                          // waypoints in degrees and decimal minute format
    degreeOnly = trunc ( currNodePtr->Lat );              // lat
    degreeDecFraction = currNodePtr->Lat - degreeOnly;
    if ( degreeDecFraction < 0.0 )
      {
      degreeDecFraction = degreeDecFraction * -1.0;
      };
    decMin = degreeDecFraction * 60.0;
    fprintf(csvofp, "\n, %.0f %.4f",degreeOnly, decMin);  // decMin format was %.4f

    degreeOnly = trunc ( currNodePtr->Lon );              // lon
    degreeDecFraction = currNodePtr->Lon - degreeOnly;
    if ( degreeDecFraction < 0.0 )
      {
      degreeDecFraction = degreeDecFraction * -1.0;
      };
    decMin = degreeDecFraction * 60.0;
    fprintf(csvofp, ", %.0f %.4f",degreeOnly, decMin);  // decMin format was %.4f

    currNodePtr=currNodePtr->nextPtr;
  }

  fprintf(csvofp, "\n\nExpected survey line %.1f meters", surveyLineMeters);  // summary lines
  fprintf(csvofp, "\n\nExpected mission time %.1f seconds\n", missionTime);
  fprintf(csvofp,"    %.0f hours\n", trunc ( ( missionTime / 3600 ) ) );
  fprintf(csvofp,"    %d minutes\n", ( (int) missionTime % 3600 ) / 60 );



    printf("\n **** Wrote csv file : %s ****\n", csvFileName);
  fclose(csvofp);
  return 0;

}


