/*
 * $Id: add.c,v 2.5 89/11/11 19:09:43 tynor Exp $
 *----------------------------------------------------------------------------
 *	FPLAN - Flight Planner
 *	Steve Tynor
 *	tynor@prism.gatech.edu
 *
 *	This program is in the public domain. Permission to copy,
 * distribute, modify this program is hearby given as long as this header
 * remains. If you redistribute this program after modifying it, please
 * document your changes so that I do not take the blame (or credit) for
 * those changes.  If you fix bugs or add features, please send me a
 * patch so that I can keep the 'official' version up-to-date.
 *
 *	Bug reports are welcome and I'll make an attempt to fix those
 * that are reported.
 *
 *	USE AT YOUR OWN RISK! I assume no responsibility for any
 * errors in this program, its database or documentation. I will make an
 * effort to fix bugs, but if you crash and burn because, for example,
 * fuel estimates in this program were inaccurate, it's your own fault
 * for trusting somebody else's code! Remember, as PIC, it's _your_
 * responsibility to do complete preflight planning. Use this program as
 * a flight planning aid, but verify its results before using them.
 *----------------------------------------------------------------------------
 */

static char rcsid[] = "$Id: add.c,v 2.5 89/11/11 19:09:43 tynor Exp $";

#include "wp_info.h"

extern char *malloc();
extern BOOLEAN lookup_desig ();

static BOOLEAN brief_mode = FALSE;

#if 0
/*----------------------------------------------------------------------------*/
static void find_intersection (desig1, radial1, desig2, radial2,
			       latitude, longitude)
     double  radial1, radial2;
     char    *desig1, *desig2;
     double  *latitude, *longitude;
{
   yyerror ("don't know how to find intersection yet");
}
#endif

/*----------------------------------------------------------------------------*/
static void init_db (db)
DATABASE_INFO *db;
{
   if (db) {
      db->freq.valid = FALSE;
      db->desig = (char*)0;
      db->name = (char*)0;
      db->city = (char*)0;
      db->comment = (char*)0;
      db->altitude.valid = FALSE;
   }
}

/*----------------------------------------------------------------------------*/
static void new_waypoint ()
{
   extern yyerror();

   if (num_waypoints >= MAX_NUM_WAYPOINTS)
      yyerror ("too many waypoints");
   
   if (num_waypoints > 0) {
      waypoints[num_waypoints] = waypoints[num_waypoints-1]; 
      waypoints[num_waypoints].refuel = FALSE;
      waypoints[num_waypoints].extra_fuel_burn.valid = FALSE;
   }
   
   num_waypoints++;
}

/*----------------------------------------------------------------------------*/
void add_named_waypoint (kind, desig)
     WAYPOINT_KIND kind;
     char *desig;
{
   DATABASE_INFO *db;

   if (lookup_desig (kind, desig, &db)) {
      new_waypoint ();   
      waypoints[num_waypoints-1].wp_kind = kind;
      waypoints[num_waypoints-1].db = db;
   }
}

/*----------------------------------------------------------------------------*/
void add_inc_waypoint (dist_since_last_wp, 
		       name_str, city_str, comment_str)
     double dist_since_last_wp;
     char   *name_str;
     char   *city_str;
     char   *comment_str;
{
   if (brief_mode)
      return;

   new_waypoint ();

   waypoints[num_waypoints-1].db = 
      (DATABASE_INFO*) malloc (sizeof (DATABASE_INFO));
   if (! waypoints[num_waypoints-1].db)
      yyerror ("unable to allocate space for waypoint");

   init_db (waypoints[num_waypoints-1].db);

   waypoints[num_waypoints-1].db->mode = WP_INCREMENTAL;
   waypoints[num_waypoints-1].wp_kind = WP_VIA;
   waypoints[num_waypoints-1].db->name = name_str;
   waypoints[num_waypoints-1].db->city = city_str;
   waypoints[num_waypoints-1].db->comment = comment_str;

   /*
    * NOTE: we can't compute lat/long since we don't know the true course
    * yet. So, just store the distance until print time.
    */
   waypoints[num_waypoints-1].db->u.dist_since_last_wp = dist_since_last_wp;
}

#if 0
/*----------------------------------------------------------------------------*/
void add_int_waypoint (kind, desig1, radial1, desig2, radial2, 
		       name_str, city_str, comment_str)
     WAYPOINT_KIND kind;
     double  radial1, radial2;
     char    *desig1, *desig2, *name_str, *city_str, *comment_str;
{
   new_waypoint ();
   waypoints[num_waypoints-1].db = 
      (DATABASE_INFO*) malloc (sizeof (DATABASE_INFO));
   if (! waypoints[num_waypoints-1].db)
      yyerror ("unable to allocate space for waypoint");

   init_db (waypoints[num_waypoints-1].db);

   find_intersection (desig1, radial1, desig2, radial2, 
		      &waypoints[num_waypoints-1].db->latitude, 
		      &waypoints[num_waypoints-1].db->longitude);
   waypoints[num_waypoints-1].db->mode = WP_INTERSECTION;
   waypoints[num_waypoints-1].wp_kind = kind;
   waypoints[num_waypoints-1].db->name = name_str;
   waypoints[num_waypoints-1].db->city = city_str;
   waypoints[num_waypoints-1].db->comment = comment_str;
}
#endif

/*----------------------------------------------------------------------------*/
void add_lat_waypoint (kind, latitude, longitude, 
		       name_str, city_str, comment_str)
     WAYPOINT_KIND kind;
     double  latitude, longitude;
     char    *name_str;
     char    *city_str;
     char    *comment_str;
{
   new_waypoint ();
   waypoints[num_waypoints-1].db = 
      (DATABASE_INFO*) malloc (sizeof (DATABASE_INFO));
   if (! waypoints[num_waypoints-1].db)
      yyerror ("unable to allocate space for waypoint");

   init_db (waypoints[num_waypoints-1].db);

   waypoints[num_waypoints-1].db->mode = WP_LAT_LONG;
   waypoints[num_waypoints-1].wp_kind = kind;
   waypoints[num_waypoints-1].db->latitude = latitude;
   waypoints[num_waypoints-1].db->longitude = longitude;
   waypoints[num_waypoints-1].db->name = name_str;
   waypoints[num_waypoints-1].db->city = city_str;
   waypoints[num_waypoints-1].db->comment = comment_str;
}

/*----------------------------------------------------------------------------*/
void set_xfix (vor_num, vor_desig)
int vor_num;
char *vor_desig;
{
   char buffer[80];
   int i = MAX (0, num_waypoints-1);

   if ((vor_num < 1) || (vor_num > MAX_NUM_VOR_FIXES)) {
      sprintf (buffer, "Invalid NAV number. Must be between 1 and %d", 
	       MAX_NUM_VOR_FIXES);
      yyerror (buffer);
   }
   if (lookup_desig (WP_VIA, vor_desig, &waypoints[i].vor_fix[vor_num-1].db)) {
      waypoints[i].vor_fix[vor_num-1].valid = TRUE;
      max_nav = MAX (max_nav, vor_num-1);
   }
}

/*----------------------------------------------------------------------------*/
void set_tas (tas)
     double tas;
{
   int i = MAX (0, num_waypoints-1);

   waypoints[i].tas.valid = TRUE;
   waypoints[i].tas.value = tas;
}

/*----------------------------------------------------------------------------*/
void set_wind (heading, speed)
     double heading, speed;
{
   int i = MAX (0, num_waypoints-1);

   waypoints[i].wind_speed.valid = TRUE;
   waypoints[i].wind_speed.value = speed;
   waypoints[i].wind_direction.valid = TRUE;
   waypoints[i].wind_direction.value = heading;
}

/*----------------------------------------------------------------------------*/
void set_fuel_amt (amt)
     double amt;
{
   int i = MAX (0, num_waypoints-1);

   waypoints[i].refuel         = TRUE;
   waypoints[i].fuel_amt.valid = TRUE;
   waypoints[i].fuel_amt.value = amt;
}

/*----------------------------------------------------------------------------*/
void set_extra_fuel_burn (amt)
     double amt;
{
   int i = MAX (0, num_waypoints-1);

   waypoints[i].extra_fuel_burn.valid = TRUE;
   waypoints[i].extra_fuel_burn.value = amt;
}

/*----------------------------------------------------------------------------*/
void set_fuel_rate (rate)
     double rate;
{
   int i = MAX (0, num_waypoints-1);

   waypoints[i].fuel_rate.valid = TRUE;
   waypoints[i].fuel_rate.value = rate;
}

/*----------------------------------------------------------------------------*/
void set_altitude (feet)
     double feet;
{
   int i = MAX (0, num_waypoints-1);

   waypoints[i].altitude.valid = TRUE;
   waypoints[i].altitude.value = feet;
}

/*----------------------------------------------------------------------------*/
void set_brief (on_off)
     BOOLEAN on_off;
{
   brief_mode = on_off;
}


