+ FlightPlan* fp = flightplanGhost(me);
+ if (!fp) {
+ naRuntimeError(c, "flightplan.appendWP called on non-flightplan object");
+ }
+
+ WayptRef wp = wayptGhost(args[0]);
+ int index = fp->numLegs();
+ fp->insertWayptAtIndex(wp.get(), index);
+ return naNum(index);
+}
+
+static naRef f_flightplan_insertWP(naContext c, naRef me, int argc, naRef* args)
+{
+ FlightPlan* fp = flightplanGhost(me);
+ if (!fp) {
+ naRuntimeError(c, "flightplan.insertWP called on non-flightplan object");
+ }
+
+ WayptRef wp = wayptGhost(args[0]);
+ int index = -1; // append
+ if ((argc > 1) && naIsNum(args[1])) {
+ index = (int) args[1].num;
+ }
+
+ fp->insertWayptAtIndex(wp.get(), index);
+ return naNil();
+}
+
+static naRef f_flightplan_insertWPAfter(naContext c, naRef me, int argc, naRef* args)
+{
+ FlightPlan* fp = flightplanGhost(me);
+ if (!fp) {
+ naRuntimeError(c, "flightplan.insertWPAfter called on non-flightplan object");
+ }
+
+ WayptRef wp = wayptGhost(args[0]);
+ int index = -1; // append
+ if ((argc > 1) && naIsNum(args[1])) {
+ index = (int) args[1].num;
+ }
+
+ fp->insertWayptAtIndex(wp.get(), index + 1);
+ return naNil();
+}
+
+static naRef f_flightplan_insertWaypoints(naContext c, naRef me, int argc, naRef* args)
+{
+ FlightPlan* fp = flightplanGhost(me);
+ if (!fp) {
+ naRuntimeError(c, "flightplan.insertWaypoints called on non-flightplan object");
+ }
+
+ WayptVec wps;
+ if (!naIsVector(args[0])) {
+ naRuntimeError(c, "flightplan.insertWaypoints expects vector as first arg");
+ }
+
+ int count = naVec_size(args[0]);
+ for (int i=0; i<count; ++i) {
+ Waypt* wp = wayptGhost(naVec_get(args[0], i));
+ if (wp) {
+ wps.push_back(wp);
+ }
+ }
+
+ int index = -1; // append
+ if ((argc > 1) && naIsNum(args[1])) {
+ index = (int) args[1].num;
+ }
+
+ fp->insertWayptsAtIndex(wps, index);
+ return naNil();
+}
+
+static naRef f_flightplan_deleteWP(naContext c, naRef me, int argc, naRef* args)
+{
+ FlightPlan* fp = flightplanGhost(me);
+ if (!fp) {
+ naRuntimeError(c, "flightplan.deleteWP called on non-flightplan object");
+ }
+
+ if ((argc < 1) || !naIsNum(args[0])) {
+ naRuntimeError(c, "bad argument to flightplan.deleteWP");
+ }
+
+ int index = (int) args[0].num;
+ fp->deleteIndex(index);
+ return naNil();
+}
+
+static naRef f_flightplan_clearPlan(naContext c, naRef me, int argc, naRef* args)
+{
+ FlightPlan* fp = flightplanGhost(me);
+ if (!fp) {
+ naRuntimeError(c, "flightplan.clearPlan called on non-flightplan object");
+ }
+
+ fp->clear();
+ return naNil();
+}
+
+static naRef f_flightplan_clearWPType(naContext c, naRef me, int argc, naRef* args)
+{
+ FlightPlan* fp = flightplanGhost(me);
+ if (!fp) {
+ naRuntimeError(c, "flightplan.clearWPType called on non-flightplan object");
+ }
+
+ if (argc < 1) {
+ naRuntimeError(c, "insufficent args to flightplan.clearWPType");
+ }
+
+ WayptFlag flag = wayptFlagFromString(naStr_data(args[0]));
+ fp->clearWayptsWithFlag(flag);
+ return naNil();
+}
+
+static naRef f_flightplan_clone(naContext c, naRef me, int argc, naRef* args)
+{
+ FlightPlan* fp = flightplanGhost(me);
+ if (!fp) {
+ naRuntimeError(c, "flightplan.clone called on non-flightplan object");
+ }
+
+ return ghostForFlightPlan(c, fp->clone());
+}
+
+static naRef f_flightplan_pathGeod(naContext c, naRef me, int argc, naRef* args)
+{
+ FlightPlan* fp = flightplanGhost(me);
+ if (!fp) {
+ naRuntimeError(c, "flightplan.clone called on non-flightplan object");
+ }
+
+ if ((argc < 1) || !naIsNum(args[0])) {
+ naRuntimeError(c, "bad argument to flightplan.pathGeod");
+ }
+
+ if ((argc > 1) && !naIsNum(args[1])) {
+ naRuntimeError(c, "bad argument to flightplan.pathGeod");
+ }
+
+ int index = (int) args[0].num;
+ double offset = (argc > 1) ? args[1].num : 0.0;
+ naRef result = naNewHash(c);
+ SGGeod g = fp->pointAlongRoute(index, offset);
+ hashset(c, result, "lat", naNum(g.getLatitudeDeg()));
+ hashset(c, result, "lon", naNum(g.getLongitudeDeg()));
+ return result;
+}
+
+
+static naRef f_leg_setSpeed(naContext c, naRef me, int argc, naRef* args)
+{
+ FlightPlan::Leg* leg = fpLegGhost(me);
+ if (!leg) {
+ naRuntimeError(c, "leg.setSpeed called on non-flightplan-leg object");
+ }
+
+ if (argc < 2) {
+ naRuntimeError(c, "bad arguments to leg.setSpeed");
+ }
+
+ RouteRestriction rr = routeRestrictionFromString(naStr_data(args[1]));
+ leg->setSpeed(rr, args[0].num);
+ return naNil();
+}
+
+static naRef f_leg_setAltitude(naContext c, naRef me, int argc, naRef* args)
+{
+ FlightPlan::Leg* leg = fpLegGhost(me);
+ if (!leg) {
+ naRuntimeError(c, "leg.setAltitude called on non-flightplan-leg object");
+ }
+
+ if (argc < 2) {
+ naRuntimeError(c, "bad arguments to leg.setAltitude");
+ }
+
+ RouteRestriction rr = routeRestrictionFromString(naStr_data(args[1]));
+ leg->setAltitude(rr, args[0].num);
+ return naNil();
+}
+
+static naRef f_leg_path(naContext c, naRef me, int argc, naRef* args)
+{
+ FlightPlan::Leg* leg = fpLegGhost(me);
+ if (!leg) {
+ naRuntimeError(c, "leg.setAltitude called on non-flightplan-leg object");
+ }
+
+ RoutePath path(leg->owner());
+ SGGeodVec gv(path.pathForIndex(leg->index()));
+
+ naRef result = naNewVector(c);
+ BOOST_FOREACH(SGGeod p, gv) {
+ // construct a geo.Coord!
+ naRef coord = naNewHash(c);
+ hashset(c, coord, "lat", naNum(p.getLatitudeDeg()));
+ hashset(c, coord, "lon", naNum(p.getLongitudeDeg()));
+ naVec_append(result, coord);
+ }
+
+ return result;
+}
+
+static naRef f_leg_courseAndDistanceFrom(naContext c, naRef me, int argc, naRef* args)
+{
+ FlightPlan::Leg* leg = fpLegGhost(me);
+ if (!leg) {
+ naRuntimeError(c, "leg.courseAndDistanceFrom called on non-flightplan-leg object");
+ }
+
+ SGGeod pos;
+ geodFromArgs(args, 0, argc, pos);
+
+ double courseDeg;
+ double distanceM;
+ boost::tie(courseDeg, distanceM) = leg->waypoint()->courseAndDistanceFrom(pos);
+
+ naRef result = naNewVector(c);
+ naVec_append(result, naNum(courseDeg));
+ naVec_append(result, naNum(distanceM * SG_METER_TO_NM));
+ return result;