+static void waypointGhostSetMember(naContext c, void* g, naRef field, naRef value)
+{
+ const char* fieldName = naStr_data(field);
+ Waypt* wpt = (Waypt*) g;
+ waypointCommonSetMember(c, wpt, fieldName, value);
+}
+
+static void legGhostSetMember(naContext c, void* g, naRef field, naRef value)
+{
+ const char* fieldName = naStr_data(field);
+ FlightPlan::Leg* leg = (FlightPlan::Leg*) g;
+
+ waypointCommonSetMember(c, leg->waypoint(), fieldName, value);
+}
+
+static const char* flightplanGhostGetMember(naContext c, void* g, naRef field, naRef* out)
+{
+ const char* fieldName = naStr_data(field);
+ FlightPlan* fp = (FlightPlan*) g;
+
+ if (!strcmp(fieldName, "parents")) {
+ *out = naNewVector(c);
+ naVec_append(*out, flightplanPrototype);
+ } else if (!strcmp(fieldName, "id")) *out = stringToNasal(c, fp->ident());
+ else if (!strcmp(fieldName, "departure")) *out = ghostForAirport(c, fp->departureAirport());
+ else if (!strcmp(fieldName, "destination")) *out = ghostForAirport(c, fp->destinationAirport());
+ else if (!strcmp(fieldName, "departure_runway")) *out = ghostForRunway(c, fp->departureRunway());
+ else if (!strcmp(fieldName, "destination_runway")) *out = ghostForRunway(c, fp->destinationRunway());
+ else if (!strcmp(fieldName, "sid")) *out = ghostForProcedure(c, fp->sid());
+ else if (!strcmp(fieldName, "sid_trans")) *out = ghostForProcedure(c, fp->sidTransition());
+ else if (!strcmp(fieldName, "star")) *out = ghostForProcedure(c, fp->star());
+ else if (!strcmp(fieldName, "star_trans")) *out = ghostForProcedure(c, fp->starTransition());
+ else if (!strcmp(fieldName, "approach")) *out = ghostForProcedure(c, fp->approach());
+ else if (!strcmp(fieldName, "current")) *out = naNum(fp->currentIndex());
+ else {
+ return 0;
+ }
+
+ return "";
+}
+
+static void flightplanGhostSetMember(naContext c, void* g, naRef field, naRef value)
+{
+ const char* fieldName = naStr_data(field);
+ FlightPlan* fp = (FlightPlan*) g;
+
+ if (!strcmp(fieldName, "id")) {
+ if (!naIsString(value)) naRuntimeError(c, "flightplan.id must be a string");
+ fp->setIdent(naStr_data(value));
+ } else if (!strcmp(fieldName, "current")) {
+ int index = value.num;
+ if ((index < 0) || (index >= fp->numLegs())) {
+ return;
+ }
+ fp->setCurrentIndex(index);
+ } else if (!strcmp(fieldName, "departure")) {
+ FGAirport* apt = airportGhost(value);
+ if (apt) {
+ fp->setDeparture(apt);
+ return;
+ }
+
+ FGRunway* rwy = runwayGhost(value);
+ if (rwy){
+ fp->setDeparture(rwy);
+ return;
+ }
+
+ naRuntimeError(c, "bad argument type setting departure");
+ } else if (!strcmp(fieldName, "destination")) {
+ FGAirport* apt = airportGhost(value);
+ if (apt) {
+ fp->setDestination(apt);
+ return;
+ }
+
+ FGRunway* rwy = runwayGhost(value);
+ if (rwy){
+ fp->setDestination(rwy);
+ return;
+ }
+
+ naRuntimeError(c, "bad argument type setting destination");
+ } else if (!strcmp(fieldName, "departure_runway")) {
+ FGRunway* rwy = runwayGhost(value);
+ if (rwy){
+ fp->setDeparture(rwy);
+ return;
+ }
+
+ naRuntimeError(c, "bad argument type setting departure");
+ } else if (!strcmp(fieldName, "destination_runway")) {
+ FGRunway* rwy = runwayGhost(value);
+ if (rwy){
+ fp->setDestination(rwy);
+ return;
+ }
+
+ naRuntimeError(c, "bad argument type setting departure");
+ } else if (!strcmp(fieldName, "sid")) {
+ Procedure* proc = procedureGhost(value);
+ if (proc && (proc->type() == PROCEDURE_SID)) {
+ fp->setSID((flightgear::SID*) proc);
+ return;
+ }
+ // allow a SID transition to be set, implicitly include the SID itself
+ if (proc && (proc->type() == PROCEDURE_TRANSITION)) {
+ fp->setSID((Transition*) proc);
+ return;
+ }
+
+ if (naIsString(value)) {
+ FGAirport* apt = fp->departureAirport();
+ fp->setSID(apt->findSIDWithIdent(naStr_data(value)));
+ return;
+ }
+
+ naRuntimeError(c, "bad argument type setting SID");
+ } else if (!strcmp(fieldName, "star")) {
+ Procedure* proc = procedureGhost(value);
+ if (proc && (proc->type() == PROCEDURE_STAR)) {
+ fp->setSTAR((STAR*) proc);
+ return;
+ }
+
+ if (proc && (proc->type() == PROCEDURE_TRANSITION)) {
+ fp->setSTAR((Transition*) proc);
+ return;
+ }
+
+ if (naIsString(value)) {
+ FGAirport* apt = fp->destinationAirport();
+ fp->setSTAR(apt->findSTARWithIdent(naStr_data(value)));
+ return;
+ }
+
+ naRuntimeError(c, "bad argument type setting STAR");
+ } else if (!strcmp(fieldName, "approach")) {
+ Procedure* proc = procedureGhost(value);
+ if (proc && Approach::isApproach(proc->type())) {
+ fp->setApproach((Approach*) proc);
+ return;
+ }
+
+ if (naIsString(value)) {
+ FGAirport* apt = fp->destinationAirport();
+ fp->setApproach(apt->findApproachWithIdent(naStr_data(value)));
+ return;
+ }
+
+ naRuntimeError(c, "bad argument type setting approach");
+ }
+}
+
+
+static naRef procedureTpType(naContext c, ProcedureType ty)
+{
+ switch (ty) {
+ case PROCEDURE_SID: return stringToNasal(c, "sid");
+ case PROCEDURE_STAR: return stringToNasal(c, "star");
+ case PROCEDURE_APPROACH_VOR:
+ case PROCEDURE_APPROACH_ILS:
+ case PROCEDURE_APPROACH_RNAV:
+ case PROCEDURE_APPROACH_NDB:
+ return stringToNasal(c, "IAP");
+ default:
+ return naNil();
+ }
+}
+
+static naRef procedureRadioType(naContext c, ProcedureType ty)
+{
+ switch (ty) {
+ case PROCEDURE_APPROACH_VOR: return stringToNasal(c, "VOR");
+ case PROCEDURE_APPROACH_ILS: return stringToNasal(c, "ILS");
+ case PROCEDURE_APPROACH_RNAV: return stringToNasal(c, "RNAV");
+ case PROCEDURE_APPROACH_NDB: return stringToNasal(c, "NDB");
+ default:
+ return naNil();
+ }
+}
+
+static const char* procedureGhostGetMember(naContext c, void* g, naRef field, naRef* out)
+{
+ const char* fieldName = naStr_data(field);
+ Procedure* proc = (Procedure*) g;
+
+ if (!strcmp(fieldName, "parents")) {
+ *out = naNewVector(c);
+ naVec_append(*out, procedurePrototype);
+ } else if (!strcmp(fieldName, "id")) *out = stringToNasal(c, proc->ident());
+ else if (!strcmp(fieldName, "airport")) *out = ghostForAirport(c, proc->airport());
+ else if (!strcmp(fieldName, "tp_type")) *out = procedureTpType(c, proc->type());
+ else if (!strcmp(fieldName, "radio")) *out = procedureRadioType(c, proc->type());
+ else if (!strcmp(fieldName, "runways")) {
+ *out = naNewVector(c);
+ BOOST_FOREACH(FGRunwayPtr rwy, proc->runways()) {
+ naVec_append(*out, stringToNasal(c, rwy->ident()));
+ }
+ } else if (!strcmp(fieldName, "transitions")) {
+ if ((proc->type() != PROCEDURE_SID) && (proc->type() != PROCEDURE_STAR)) {
+ *out = naNil();
+ return "";
+ }
+
+ ArrivalDeparture* ad = static_cast<ArrivalDeparture*>(proc);
+ *out = naNewVector(c);
+ BOOST_FOREACH(string id, ad->transitionIdents()) {
+ naVec_append(*out, stringToNasal(c, id));
+ }
+ } else {
+ return 0;
+ }
+
+ return "";
+}
+