<?xml version="1.0"?>

<PropertyList>
    <name>input-systems</name>
    <layout>vbox</layout>
    <resizable>true</resizable>
    <pref-width>600</pref-width>

    <nasal>
        <open>
            var DLGROOT = cmdarg();
            var dlg_prefix = "/sim/gui/dialogs/"
                ~DLGROOT.getNode("name", 1).getValue()~"/";
            var systems = {
                "js": "Joystick",
                "hid": "USB HID",
                "linux": "Linux Event Input"
            };
            var path_selected = props.getNode("/input/event", 1);

            # setup a device list
            # list: dialog list element to setup
            # input_system: 'event' or 'joystick'
            # class: for input_system 'event', filter devices by _class-id
            var setupList = func(list, input_system, class, child="device") {
                var list_items = props.globals.getNode(dlg_prefix~list, 1);
                list_items.removeChildren();
                foreach (var device; props.globals.getNode("/input/"~input_system).getChildren(child)) {
                    if (class) {
                        var cid = device.getChild("_class-id");
                        if (cid and cid.getValue() == class) {
                            list_items.addChild("value").setValue(device.getValue("name")~" ("~device.getIndex()~")");
                            list_items.addChild("path").setValue(device.getPath());
                        }
                    }
                    else {
                        # name is displayed in the list
                        list_items.addChild("value").setValue(device.getValue("name"));
                        # path to device config
                        list_items.addChild("path").setValue(device.getPath());
                    }
                }
            }

            # populate list boxes for all three input systems
            setupList("js-devs", "joysticks", "", "js");
            setupList("hid-devs", "hid", "FGHIDDevice");
            setupList("linux-devs", "event", "FGLinuxInputDevice");

            # get nodes to display last input event of selected device
            var last_name = props.getNode(dlg_prefix~"last-name", 1);
            var last_value = props.getNode(dlg_prefix~"last-value", 1);
            var selected_variant = props.getNode(dlg_prefix~"variant", 1);

            # update the info section of the dialog when an list item is clicked
            # see bindings below
            var updateInfo = func(sys) {
                setprop(dlg_prefix~"system", systems[sys]);
                var list = props.globals.getNode(dlg_prefix~sys~"-devs");
                var selected = getprop(dlg_prefix~"devname");
                foreach (var v; list.getChildren("value")) {
                    if (v.getValue() == selected) {
                        path_selected = list.getChild("path", v.getIndex());
                        var device_config = props.getNode(path_selected.getValue());

                        # link dialog elements to currently selected device
                        last_name.unalias();
                        last_name.alias(path_selected.getValue()~"/last-event/name");
                        last_value.unalias();
                        last_value.alias(path_selected.getValue()~"/last-event/value");

                        setprop(dlg_prefix~"cfgfile",
                            string.squeeze(device_config.getChild("source").getValue(), 75));

                        # update variants and open device specific dialog if available
                        updateVariantListbox(device_config);
                        deviceDialog(device_config);
                    }
                }
            }

            # update config variant listbox
            var updateVariantListbox = func(cfg) {
                var variants = cfg.getNode("config-variants", 1).getChildren("variant");
                var selected = cfg.getNode("_selected-variant", 1).getValue() or '';
                var list_items = props.globals.getNode(dlg_prefix~"variants", 1);
                list_items.removeChildren();
                selected_variant.setValue('');

                if (size(variants)) {
                    foreach (var v; variants) {
                        var id = v.getNode("id").getValue();
                        var description = v.getNode("description").getValue();
                        list_items.addChild("id").setValue(id);
                        list_items.addChild("value").setValue(description);
                        if (id == selected) {
                            selected_variant.setValue(description);
                        }
                    }
                }

                DLGROOT.setValues({
                    "dialog-name": DLGROOT.getNode("name", 1).getValue(),
                    "object-name": "listvariant"
                    });
				fgcommand("dialog-update", DLGROOT);
            }

            # a device specific dialog can be opened provided that
            # such dialog exists in FGDATA/gui/dialogs/
            # and the config contains a device-dialog tag with the name of the dialog
            var deviceDialog = func(cfg) {
                var d = cfg.getNode("device-dialog");
                if (d) fgcommand("dialog-show", props.Node.new({"dialog-name": d.getValue()}));
            }

            # apply config variant
            var applyVariant = func() {
                var cfg = props.getNode(path_selected.getValue(), 1);
                var list = props.globals.getNode(dlg_prefix~"variants", 1);
                foreach (var v; list.getChildren("value")) {
                    if (v.getValue() == selected_variant.getValue()) {
                        cfg.getNode("_selected-variant", 1)
                            .setValue(list.getChild("id", v.getIndex()).getValue());
                    }
                }
            }
        </open>
    </nasal>

    <group>
        <layout>hbox</layout>
        <text>
            <label>Input Devices</label>
        </text>
        <empty><stretch>true</stretch></empty>

        <button>
            <legend>X</legend>
            <key>Esc</key>
            <pref-width>20</pref-width>
            <pref-height>20</pref-height>
            <binding>
                <command>dialog-close</command>
            </binding>
        </button>
    </group>

    <hrule/>
    <group>
        <name>button-bar-top</name>
        <layout>hbox</layout>
        <button>
            <name>mouse-config</name>
            <legend>Mouse Config</legend>
            <key>m</key>
            <binding>
                <command>dialog-show</command>
                <dialog-name>mouse-config</dialog-name>
            </binding>
        </button>
        <button>
            <name>joystick-config</name>
            <legend>Joystick Config</legend>
            <key>j</key>
            <enable>
                <not><property>/sim/input/no-joystick-input</property></not>
            </enable>
            <binding>
                <command>dialog-show</command>
                <dialog-name>joystick-config</dialog-name>
            </binding>
        </button>
        <button>
            <name>hid-config</name>
            <legend>HID Config</legend>
            <enable>
                <not><property>/sim/input/no-hid-input</property></not>
            </enable>
            <binding>
                <command>dialog-show</command>
                <dialog-name>hid-config</dialog-name>
            </binding>
        </button>
        <button>
            <legend>Config Variant Selector</legend>
            <key>v</key>
            <binding>
                <command>dialog-show</command>
                <dialog-name>input-config-select</dialog-name>
            </binding>
        </button>
    </group>
    <hrule />
    <group>
        <layout>hbox</layout>
        <group> <!-- left col -->
            <layout>vbox</layout>
            <text>
                <label>Input Systems Overview</label>
            </text>
            <group>
                <layout>hbox</layout>
                <text>
                    <halign>left</halign>
                    <label>Joystick input</label>
                    <enable>
                        <not><property>/sim/input/no-joystick-input</property></not>
                    </enable>
                </text>
                <text>
                    <label>disabled</label>
                    <visible>
                        <property>/sim/input/no-joystick-input</property>
                    </visible>
                </text>
                <empty><stretch>true</stretch></empty>
            </group>
            <list>
                <visible>
                    <not><property>/sim/input/no-joystick-input</property></not>
                </visible>
                <name>joysticks</name>
                <halign>left</halign>
                <pref-width>350</pref-width>
                <pref-height>100</pref-height>
                <property>/sim/gui/dialogs/input-systems/devname</property>
                <properties>/sim/gui/dialogs/input-systems/js-devs</properties>
                <binding>
                    <command>dialog-apply</command>
                    <object-name>joysticks</object-name>
                </binding>
                <binding>
                    <command>nasal</command>
                    <script>
                    updateInfo("js");
                    </script>
                </binding>
            </list>
            <group>
                <layout>hbox</layout>
                <text>
                    <halign>left</halign>
                    <label>USB HID input</label>
                    <enable>
                        <not><property>/sim/input/no-hid-input</property></not>
                    </enable>
                </text>
                <text>
                    <label>disabled</label>
                    <visible>
                        <property>/sim/input/no-hid-input</property>
                    </visible>
                </text>
                <empty><stretch>true</stretch></empty>
            </group>
            <list>
                <visible>
                    <not><property>/sim/input/no-hid-input</property></not>
                </visible>
                <name>hids</name>
                <halign>left</halign>
                <pref-width>350</pref-width>
                <pref-height>100</pref-height>
                <property>/sim/gui/dialogs/input-systems/devname</property>
                <properties>/sim/gui/dialogs/input-systems/hid-devs</properties>
                <binding>
                    <command>dialog-apply</command>
                    <object-name>hids</object-name>
                </binding>
                <binding>
                    <command>nasal</command>
                    <script>
                    updateInfo("hid");
                    </script>
                </binding>
            </list>
            <group>
                <layout>hbox</layout>
                <text>
                    <halign>left</halign>
                    <label>Linux Event input</label>
                    <enable>
                        <not><property>/sim/input/no-event-input</property></not>
                    </enable>
                </text>
                <text>
                    <label>disabled</label>
                    <visible>
                        <property>/sim/input/no-event-input</property>
                    </visible>
                </text>
                <empty><stretch>true</stretch></empty>
            </group>
            <list>
                <visible>
                    <not><property>/sim/input/no-event-input</property></not>
                </visible>
                <name>linux</name>
                <halign>left</halign>
                <pref-width>350</pref-width>
                <pref-height>100</pref-height>
                <property>/sim/gui/dialogs/input-systems/devname</property>
                <properties>/sim/gui/dialogs/input-systems/linux-devs</properties>
                <binding>
                    <command>dialog-apply</command>
                    <object-name>linux</object-name>
                </binding>
                <binding>
                    <command>nasal</command>
                    <script>
                    updateInfo("linux");
                    </script>
                </binding>
            </list>
        </group> <!-- left col -->

        <vrule/>
        <group>
            <layout>vbox</layout>
            <valign>top</valign>
            <text>
                <label>Config variant</label>
                <halign>left</halign>
            </text>
            <list>
                <name>listvariant</name>
                <halign>left</halign>
                <pref-width>200</pref-width>
                <pref-height>150</pref-height>
                <property>/sim/gui/dialogs/input-systems/variant</property>
                <properties>/sim/gui/dialogs/input-systems/variants</properties>
                <binding>
                    <command>dialog-apply</command>
                    <object-name>listvariant</object-name>
                </binding>
                <binding>
                    <command>nasal</command>
                    <script>applyVariant();</script>
                </binding>
            </list>
            <text>
                <!-- live does not seem to work on list so when updating the
                variant list, nothing appears to be selected :/
                for now, show selected value as text -->
                <name>selected-variant</name>
                <halign>left</halign>
                <live>true</live>
                <property>/sim/gui/dialogs/input-systems/variant</property>
            </text>
        </group> <!-- right col -->
    </group>
    <hrule />
    <group>
        <name>devinfo</name>
        <layout>table</layout>
        <text>
            <row>0</row><col>0</col>
            <pref-width>50</pref-width>
            <label>Device:</label>
            <halign>left</halign>
        </text>
        <text>
            <row>0</row><col>1</col>
            <name>system</name>
            <halign>left</halign>
            <live>true</live>
            <property>/sim/gui/dialogs/input-systems/system</property>
        </text>
        <text>
            <row>0</row><col>2</col>
            <pref-width>200</pref-width>
            <name>devname</name>
            <halign>left</halign>
            <live>true</live>
            <property>/sim/gui/dialogs/input-systems/devname</property>
        </text>

        <text>
            <row>1</row><col>0</col>
            <label>Config file:</label>
            <halign>left</halign>
        </text>
        <text>
            <row>1</row><col>1</col>
            <colspan>3</colspan>
            <name>cfgfile</name>
            <halign>left</halign>
            <live>true</live>
            <property>/sim/gui/dialogs/input-systems/cfgfile</property>
        </text>
        <text>
            <row>2</row><col>0</col>
            <pref-width>50</pref-width>
            <label>Last event:</label>
            <halign>left</halign>
            <visible>
                <not-equals>
                    <property>/sim/gui/dialogs/input-systems/system</property>
                    <value>Joystick</value>
                </not-equals>
            </visible>
        </text>
        <text>
            <row>2</row><col>1</col>
            <pref-width>100</pref-width>
            <name>lastname</name>
            <halign>left</halign>
            <live>true</live>
            <property>/sim/gui/dialogs/input-systems/last-name</property>
        </text>
        <text>
            <row>2</row><col>2</col>
            <name>lastvalue</name>
            <halign>left</halign>
            <live>true</live>
            <property>/sim/gui/dialogs/input-systems/last-value</property>
        </text>
        <button>
            <legend>Debug</legend>
            <row>2</row><col>3</col>
            <pref-height>20</pref-height>
            <binding>
                <command>nasal</command>
                <script>gui.property_browser(path_selected.getValue());</script>
            </binding>
        </button>
    </group>
    <group>
        <name>button-bar-bottom</name>
        <layout>hbox</layout>
    </group>
</PropertyList>
