<?xml version="1.0"?>

<!--
command interface /autopilot/route-manager/input:

  @clear             ... clear route
  @pop               ... remove first entry
  @delete3           ... delete 4th entry
  @insert2:ksfo@900  ... insert "ksfo@900" as 3rd entry
  ksfo@900           ... append "ksfo@900"

-->

<PropertyList>
    <name>route-manager</name>
    <layout>vbox</layout>
    <resizable>true</resizable>

    <nasal>
        <open><![CDATA[
            var ft = getprop("/sim/startup/units") == "feet";
            var dlg = props.globals.getNode("/sim/gui/dialogs/route-manager", 1);
            var selection = dlg.getNode("selection", 1);
            var input = dlg.getNode("input", 1);
            var routem = props.globals.getNode("/autopilot/route-manager", 1);

            selection.setIntValue(-1);
            input.setValue("");

            var list = cmdarg().getNode("list");
            var cmd = routem.getNode("input", 1);
            var route = routem.getNode("route", 1);
            var dep = routem.getNode("departure", 1);
            var dest = routem.getNode("destination", 1);

            var sel_index = func {
                return int(selection.getValue());
            }

            var clear = func {
                flightplan().cleanPlan();
                selection.setIntValue(-1);
            }

            var insert = func {
                var insertIndex = sel_index();
                if (insertIndex < 0) {
                    var msg = "Select the waypoint after which new waypoints should be added";
                    setprop("sim/messages/copilot", msg);
                    return;
                }

                # Input is a list of space-separated waypoint specifications
                var argv = split(" ", input.getValue());
                foreach (var arg; argv) {
                    # When argument is not empty (caused by multiple space
                    # separators) insert *after* waypoint
                    if (size(arg) > 0) {
                        insertIndex += 1;
                        cmd.setValue("@insert" ~ insertIndex ~ ":" ~ arg);
                    }
                }

                input.setValue("");
                selection.setValue(insertIndex);
                gui.dialog_update("route-manager");
            }

            var remove = func {
                flightplan().deleteWP(sel_index());
            }

            var route = func {
                var fp = flightplan();
                var from = fp.getWP(sel_index() - 1);
                var to = fp.getWP(sel_index());

                if ((from  == nil ) or (to == nil)) {
                    printlog('info', 'unable to route, invalid start ad end points');
                    return;
                }

                var route = airwaysRoute(from, to);
                fp.insertWaypoints(route, sel_index());
            }

            var jump_to = func {
                flightplan().current = sel_index();
            }

            var load_route = func(path) {
                routem.getNode("file-path", 1).setValue(path.getValue());
                cmd.setValue("@load");
                gui.dialog_update("route-manager");
            }

            var save_route = func(path) {
                routem.getNode("file-path", 1).setValue(path.getValue());
                cmd.setValue("@save");
                gui.dialog_update("route-manager");
            }

            var file_selector = gui.FileSelector.new(load_route, "Load flight-plan", "Load");
            var save_selector = gui.FileSelector.new(save_route, "Save flight-plan", "Save");

            var activate_fp = func {
                fgcommand("activate-flightplan", props.Node.new({"activate": 1}));
            }

            var departureRunways = dlg.getNode("departure-runways", 1);
            var destRunways = dlg.getNode("destination-runways", 1);
            var sids = dlg.getNode("sids", 1);
            var stars = dlg.getNode("stars", 1);
            var approaches = dlg.getNode("approaches", 1);

            var updateRunways = func {
                departureRunways.removeChildren("value");
                destRunways.removeChildren("value");

                var apt = flightplan().departure;
                if (apt != nil) {
                    var i=0;
                    foreach (var rwy; keys(apt.runways)) {
                        departureRunways.getNode("value[" ~ i ~ "]", 1).setValue(rwy);
                        i += 1;
                    }
                }

                apt = flightplan().destination;
                if (apt != nil) {
                    var i=0;
                    foreach (var rwy; keys(apt.runways)) {
                        destRunways.getNode("value[" ~ i ~ "]", 1).setValue(rwy);
                        i += 1;
                    }
                }

                gui.dialog_update("route-manager");
            }

            var updateSIDs = func {
                sids.removeChildren("value");

                var apt = flightplan().departure;
                var rwy = flightplan().departure_runway;
                if (apt == nil) {
                    return;
                }

                if (size(apt.sids(rwy)) == 0) {
                    sids.getNode("value[0]", 1).setValue("DEFAULT");
                    sids.getNode("value[1]", 1).setValue("(none)");
                    gui.dialog_update("route-manager", "sid");
                    return;
                }

                var i=1;
                sids.getNode("value[0]", 1).setValue("(none)");
                foreach (var s; apt.sids(rwy)) {
                    var sid = apt.getSid(s);
                    var transVec = sid.transitions;

                    if (size(transVec) > 0) {
                        # list each transition of the SID
                        foreach (var trans; transVec) {
                            sids.getNode("value[" ~ i ~ "]", 1).setValue(s ~ "-" ~ trans);
                            i += 1;
                        }
                    } else {
                        # no transitions defined, simple case
                        sids.getNode("value[" ~ i ~ "]", 1).setValue(s);
                        i += 1;
                    }
                }

                gui.dialog_update("route-manager", "sid");
            }

            var updateSTARs = func {
                stars.removeChildren("value");
                var apt = flightplan().destination;
                var rwy = flightplan().destination_runway;
                if (apt == nil or apt.stars(rwy) == nil) {
                    return;
                }

                var i=1;
                stars.getNode("value[0]", 1).setValue("(none)");
                foreach (var s; apt.stars(rwy)) {
                    var star = apt.getStar(s);
                    var transVec = star.transitions;

                    if (size(transVec) > 0) {
                        # list each transition of the STAR
                        foreach (var trans; transVec) {
                            stars.getNode("value[" ~ i ~ "]", 1).setValue(s ~ "-" ~ trans);
                            i += 1;
                        }
                    } else {
                        # no transitions defined, simple case
                        stars.getNode("value[" ~ i ~ "]", 1).setValue(s);
                        i += 1;
                    }
                }

                gui.dialog_update("route-manager", "star");
            }

            var updateApproaches = func {
                approaches.removeChildren("value");
                var apt = flightplan().destination;
                var rwy = flightplan().destination_runway;

                if (apt == nil) {
                    return;
                }

                if (size(apt.getApproachList(rwy)) == 0) {
                    approaches.getNode("value[0]", 1).setValue("DEFAULT");
                    approaches.getNode("value[1]", 1).setValue("(none)");
                    gui.dialog_update("route-manager", "approach");
                    return;
                }

                var i=1;
                approaches.getNode("value[0]", 1).setValue("(none)");
                foreach (var s; apt.getApproachList(rwy)) {
                    approaches.getNode("value[" ~ i ~ "]", 1).setValue(s);
                    i += 1;
                }

                gui.dialog_update("route-manager", "approach");
            }

            var initPosition = func {
              var routeActive = routem.getNode("active").getValue();
              if (routeActive) return;

              # FIXME have user waypoints check
              var fp = flightplan();

              var airborne = getprop('/gear/gear[0]/wow') == 0;
              if (airborne) {
                printlog('info', 'route-manager dialog, init in-air, clearing departure settings');
                fp.departure = nil;
                return;
              }



              # we're on the ground, find the nearest airport to start from
              if (fp.departure == nil) {
                var apts = findAirportsWithinRange(25.0);
                if (size(apts) == 0) return; # no airports nearby
                fp.departure = apts[0]; # use the closest one
              }

              if (fp.departure_runway == nil) {
                printlog('info', 'selecting departure runway');
                var rwy = fp.departure.findBestRunwayForPos( geo.aircraft_position() );
                fp.departure_runway = rwy;
              }
            }

        # initialise departure values based on current position
            initPosition();

            updateRunways();
            updateSIDs();
            updateSTARs();
            updateApproaches();
        ]]></open>

        <close>
            file_selector.del();
            save_selector.del();
        </close>
    </nasal>

    <group>
        <layout>hbox</layout>
        <empty><stretch>1</stretch></empty>

        <text>
            <label>Route Manager</label>
        </text>

        <empty><stretch>1</stretch></empty>

        <button>
            <pref-width>16</pref-width>
            <pref-height>16</pref-height>
            <legend></legend>
            <default>1</default>
            <keynum>27</keynum>
            <border>2</border>

            <binding>
                <command>dialog-close</command>
            </binding>
        </button>
    </group>
    <hrule/>
    <!-- departure / arrival airport information -->

    <group>
        <layout>table</layout>
        <text>
            <row>0</row>
            <col>0</col>
            <halign>right</halign>
            <label> Departure:</label>
        </text>
        <input>
            <row>0</row>
            <col>1</col>
            <halign>left</halign>
            <name>departure-airport</name>
            <pref-width>70</pref-width>
            <property>/autopilot/route-manager/departure/airport</property>
            <live>true</live>
            <binding>
                <command>dialog-apply</command>
                <object-name>departure-airport</object-name>
            </binding>

            <binding>
                <command>nasal</command>
                <script>updateRunways();</script>
            </binding>
        </input>

        <text>
            <row>0</row>
            <col>2</col>
            <format>%s</format>
            <property>/autopilot/route-manager/departure/name</property>
            <live>true</live>
            <stretch>true</stretch>
            <halign>fill</halign>
        </text>

        <text>
            <row>0</row>
            <col>3</col>
            <halign>right</halign>
            <label>Rwy:</label>
        </text>
        <combo>
            <row>0</row>
            <col>4</col>
            <halign>left</halign>
            <name>departure-runway</name>
            <property>/autopilot/route-manager/departure/runway</property>
            <editable>false</editable>
            <properties>/sim/gui/dialogs/route-manager/departure-runways</properties>

            <binding>
                <command>dialog-apply</command>
                <object-name>departure-runway</object-name>
            </binding>
            <binding>
                <command>nasal</command>
                <script>updateSIDs();</script>
            </binding>
        </combo>

        <text>
            <row>0</row>
            <col>7</col>
            <halign>right</halign>
            <label>SID:</label>
        </text>
        <combo>
            <row>0</row>
            <col>8</col>
            <halign>left</halign>
            <name>sid</name>
            <property>/autopilot/route-manager/departure/sid</property>
            <editable>false</editable>
            <properties>/sim/gui/dialogs/route-manager/sids</properties>

            <binding>
                <command>dialog-apply</command>
                <object-name>sid</object-name>
            </binding>
        </combo>

        <text>
            <row>1</row>
            <col>0</col>
            <halign>right</halign>
            <label>Arrival:</label>
        </text>
        <input>
            <row>1</row>
            <col>1</col>
            <halign>left</halign>
            <pref-width>70</pref-width>
            <name>destination-airport</name>
            <property>/autopilot/route-manager/destination/airport</property>
            <live>true</live>
            <binding>
                <command>dialog-apply</command>
                <object-name>destination-airport</object-name>
            </binding>
            <binding>
                <command>nasal</command>
                <script>updateRunways();</script>
            </binding>
        </input>
        <text>
            <row>1</row>
            <col>2</col>
            <stretch>true</stretch>
            <pref-width>200</pref-width>
            <format>%s</format>
            <property>/autopilot/route-manager/destination/name</property>
            <live>true</live>
            <halign>fill</halign>
        </text>

        <text>
            <row>1</row>
            <col>3</col>
            <halign>right</halign>
            <label>Rwy:</label>
        </text>
        <combo>
            <row>1</row>
            <col>4</col>
            <halign>left</halign>
            <name>destination-runway</name>
            <property>/autopilot/route-manager/destination/runway</property>
            <editable>false</editable>
            <properties>/sim/gui/dialogs/route-manager/destination-runways</properties>

            <binding>
                <command>dialog-apply</command>
                <object-name>destination-runway</object-name>
            </binding>

            <binding>
                <command>nasal</command>
                <script>
                    updateSTARs();
                    updateApproaches();
                </script>
            </binding>
        </combo>

        <text>
            <row>1</row>
            <col>5</col>
            <halign>right</halign>
            <label>Approach:</label>
        </text>
        <combo>
            <row>1</row>
            <col>6</col>
            <pref-width>120</pref-width>
            <halign>left</halign>
            <name>approach</name>
            <property>/autopilot/route-manager/destination/approach</property>
            <editable>false</editable>
            <properties>/sim/gui/dialogs/route-manager/approaches</properties>

            <binding>
                <command>dialog-apply</command>
                <object-name>approach</object-name>
            </binding>
        </combo>


        <text>
            <row>1</row>
            <col>7</col>
            <halign>right</halign>
            <label>STAR:</label>
        </text>
        <combo>
            <row>1</row>
            <col>8</col>
            <halign>left</halign>
            <name>star</name>
            <property>/autopilot/route-manager/destination/star</property>
            <editable>false</editable>
            <properties>/sim/gui/dialogs/route-manager/stars</properties>

            <binding>
                <command>dialog-apply</command>
                <object-name>star</object-name>
            </binding>
        </combo>
    </group>
    <!--
    <group>
        <layout>hbox</layout>
        <text>
            <label>Alternate:</label>
            <pref-width>80</pref-width>
        </text>
        <input>
            <name>alt-airport</name>
            <halign>fill</halign>
            <stretch>true</stretch>
            <pref-width>150</pref-width>
            <property>/autopilot/route-manager/alternate/airport</property>
        </input>

    </group>
    -->
    <group>
        <layout>hbox</layout>
        <text>
            <halign>right</halign>
            <label>  Cruise Speed (kts):</label>
        </text>
        <input>
            <name>cruise-speed</name>
            <live>true</live>
            <halign>left</halign>
            <stretch>true</stretch>
            <pref-width>100</pref-width>
            <property>/autopilot/route-manager/cruise/speed-kts</property>
            <binding>
                <command>dialog-apply</command>
                <object-name>cruise-speed</object-name>
            </binding>
        </input>

        <text>
            <label>Cruise Altitude (ft/FL):</label>
            <halign>right</halign>
        </text>
        <input>
            <name>cruise-alt</name>
            <live>true</live>
            <halign>left</halign>
            <stretch>true</stretch>
            <pref-width>100</pref-width>
            <property>/autopilot/route-manager/cruise/altitude-ft</property>
            <binding>
                <command>dialog-apply</command>
                <object-name>cruise-alt</object-name>
            </binding>
        </input>
    </group>

    <hrule/>

    <group>
        <layout>hbox</layout>
        <default-padding>2</default-padding>

        <text>
            <label>MMMMMMMMMMMMMMMM</label>
            <format>Target: %s</format>
            <property>/autopilot/route-manager/wp[0]/id</property>
            <live>true</live>
        </text>

        <text>
            <label>MMMMMMMMM</label>
            <format>Dist: %.2f nm</format>
            <property>/autopilot/route-manager/wp[0]/dist</property>
            <live>true</live>
        </text>

        <text>
            <label>MMMMMMMMM</label>
            <format>ETA: %s</format>
            <property>/autopilot/route-manager/wp[0]/eta</property>
            <live>true</live>
        </text>
    </group>

    <group>
        <layout>hbox</layout>
        <default-padding>2</default-padding>
        <stretch>true</stretch>
        <halign>fill</halign>
        <valign>fill</valign>

        <!-- gap -->
        <text>
          <label> </label>
        </text>

        <waypointlist>
            <name>list</name>
            <halign>fill</halign>
            <valign>fill</valign>
            <stretch>true</stretch>
            <pref-height>150</pref-height>
            <property>/sim/gui/dialogs/route-manager/selection</property>
            <binding>
                <command>dialog-apply</command>
                <object-name>list</object-name>
            </binding>
        </waypointlist>

        <!-- gap -->
        <text>
          <label> </label>
        </text>

    </group>

    <group>
        <layout>hbox</layout>
        <default-padding>4</default-padding>

        <text>
            <label>  Waypoint:</label>
<!--
            <pref-width>60</pref-width>
-->
        </text>

        <input>
            <name>input</name>
            <halign>fill</halign>
            <stretch>true</stretch>
            <pref-width>220</pref-width>
            <property>/sim/gui/dialogs/route-manager/input</property>
        </input>

        <button>
            <legend>Add</legend>
            <default>true</default>
<!--
            <pref-width>70</pref-width>
-->
            <binding>
                <command>dialog-apply</command>
                <object-name>input</object-name>
            </binding>
            <binding>
                <command>nasal</command>
                <script>insert()</script>
            </binding>
            <binding>
                <command>dialog-update</command>
            </binding>
        </button>

        <!-- gap -->
        <text>
          <label></label>
        </text>
    </group>

    <text>
        <padding>1</padding>
        <label>Format: list of (airport|fix|nav|nav/rad/dst|lon,lat)[@alt] -- e.g. "KSFO@900", "SAHEY CIITY@6000"</label>
        <color>
            <red>0.7</red>
            <green>0.7</green>
            <blue>0.7</blue>
        </color>
    </text>

    <!-- button field -->
    <group>
        <layout>hbox</layout>
        <halign>fill</halign>
        <default-padding>8</default-padding>

        <button>
            <legend>Clear List</legend>
            <equal>true</equal>
            <binding>
                <command>nasal</command>
                <script>clear()</script>
            </binding>
        </button>

        <button>
            <legend>Remove</legend>
            <equal>true</equal>
            <enable>
                <greater-than>
                <property>/sim/gui/dialogs/route-manager/selection</property>
                <value>-1</value>
                </greater-than>
            </enable>
            <binding>
                <command>nasal</command>
                <script>remove()</script>
            </binding>
        </button>

        <button>
            <legend>Route</legend>
            <equal>true</equal>
            <binding>
              <command>nasal</command>
              <script>route()</script>
            </binding>
        </button>
<!--
        <button>
            <legend>Auto-route</legend>
            <equal>true</equal>
            <binding>
                <command>nasal</command>
                <script>auto_route()</script>
            </binding>
        </button>
-->
        <button>
            <legend>Jump To</legend>
            <enable>
                <greater-than>
                <property>/sim/gui/dialogs/route-manager/selection</property>
                <value>-1</value>
                </greater-than>
            </enable>
            <binding>
                <command>nasal</command>
                <script>jump_to()</script>
            </binding>
        </button>

        <button>
            <legend>Activate</legend>
            <equal>true</equal>
            <enable>
                <not><property>/autopilot/route-manager/active</property></not>
            </enable>
            <binding>
                <command>dialog-apply</command>
            </binding>
            <binding>
                <command>nasal</command>
                <script>activate_fp()</script>
            </binding>
        </button>

        <empty><stretch>true</stretch></empty>
        <!-- gap -->
        <text>
          <label></label>
        </text>

        <button>
            <legend>Load ...</legend>
            <equal>true</equal>
            <enable>
            <not><property>/autopilot/route-manager/active</property></not>
            </enable>
            <binding>
                <command>nasal</command>
                <script>file_selector.open()</script>
            </binding>
        </button>
        <button>
            <legend>Save ...</legend>
            <equal>true</equal>
            <binding>
                <command>nasal</command>
                <script>save_selector.open();</script>
            </binding>
        </button>
        <button>
            <legend>Close</legend>
            <equal>true</equal>
            <key>Esc</key>
            <binding>
                <command>dialog-close</command>
            </binding>
        </button>
    </group>
</PropertyList>