<?xml version="1.0"?>

<PropertyList>
	<name>property-browser</name>
	<layout>vbox</layout>
	<resizable>true</resizable>
	<default-padding>3</default-padding>

	<group>
		<layout>vbox</layout>
		<group>
			<layout>hbox</layout>
			
			<default-padding>1</default-padding>

			<text>
				<name>title</name>
				<label>/</label>
				<property>/sim/gui/dialogs/property-browser/title</property>
				<live>true</live>
			</text>

			<empty><stretch>true</stretch></empty>

			<button>
				<legend>Clone</legend>
				<pref-width>60</pref-width>
				<pref-height>20</pref-height>
				<border>2</border>
				<binding>
					<command>nasal</command>
					<script>clone(dir)</script>
				</binding>
			</button>
			<button>
				<legend>/</legend>
				<pref-width>20</pref-width>
				<pref-height>20</pref-height>
				<binding>
					<command>nasal</command>
					<script>
					select("/");
					</script>
				</binding>
			</button>
			<button>
				<legend>?</legend>
				<key>?</key>
				<pref-width>20</pref-width>
				<pref-height>20</pref-height>
				<binding>
					<command>dialog-show</command>
					<dialog-name>help-property-browser</dialog-name>
				</binding>
			</button>
			<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>
	</group>

	<hrule/>

	<property-list>
		<name>property-list</name>
		<pref-height>500</pref-height>
		<halign>fill</halign>
		<valign>fill</valign>
		<stretch>true</stretch>
		<property>/sim/gui/dialogs/property-browser/list</property>
		<binding>
			<command>dialog-apply</command>
			<object-name>property-list</object-name>
		</binding>
		<binding>
			<command>nasal</command>
			<script>select()</script>
		</binding>
	</property-list>

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

		<empty><whatever/></empty>

		<text>
			<label>--</label>
			<live>true</live>
			<halign>fill</halign>
			<stretch>true</stretch>
			<property>/sim/gui/dialogs/property-browser/label</property>
			<pref-width>170</pref-width>
		</text>

		<input>
			<name>input</name>
			<halign>fill</halign>
			<stretch>true</stretch>
			<pref-width>170</pref-width>
			<property>/sim/gui/dialogs/property-browser/input</property>
		</input>

		<button>
			<legend>Set</legend>
			<pref-width>50</pref-width>
			<default>true</default>
			<binding>
				<command>dialog-apply</command>
				<object-name>input</object-name>
			</binding>
			<binding>
				<command>nasal</command>
				<script>set()</script>
			</binding>
		</button>
	</group>

	<nasal>
		<open>
		<![CDATA[
			var self = cmdarg();	# the node tree representing this dialog as seen in this XML
			var startdir = props.globals.getNode("/sim/gui/dialogs/property-browser-startdir", 1);
			var dlgname = self.getNode("name").getValue();
			
			# props holding values of the dialog elements
			var dlg = props.globals.getNode("/sim/gui/dialogs/" ~ dlgname, 1);
			var title = dlg.getNode("title", 1);
			var label = dlg.getNode("label", 1);
			var input = dlg.getNode("input", 1);
			var list = dlg.getNode("list", 1);
			
			var node = nil;         # selected node entry (props.Node)
			var dir = nil;          # current directory (string)
			var update_interval = 2;
			var no_selection = "[none]";

			var update = func(w) {
				self.setValues({ "dialog-name": dlgname, "object-name": w });
				fgcommand("dialog-update", self);
			}

			var select = func(path = nil) {

				# Shift-click       adds the selected property to the property display
				# Shift-Alt-click   adds all children of the selected property to the property display
				# Shift-Ctrl-click  removes all properties from the display
				var update_prop_display = func(n) {
					if (n.getPath() != "" and getprop("/devices/status/keyboard/shift")) {
						if (getprop("/devices/status/keyboard/ctrl"))
							return screen.property_display.reset();
						if (!n.getAttribute("children"))
							screen.property_display.add(n);
						elsif (getprop("/devices/status/keyboard/alt"))
							screen.property_display.add(n.getChildren());
					}
				};

				if (path == nil) {
					var lst = list.getValue();
				}
				else {
					var lst = path;
				}
				node = props.globals.getNode(lst);
				if (node == nil)
					node = props.globals;

				update_prop_display(node);

				if (node.getAttribute("children")) {
					dir = node.getPath();
					title.setValue(node.getPath() == "" ? "Property Browser" : lst);
					node = nil;
					label.setValue(no_selection);
					input.setValue("");
					list.setValue(dir);
					update("property-list");
				} else {
					var name = node.getName();
					var index = node.getIndex();
					var type = node.getType();
					if (index)
						name ~= "[" ~ index ~ "]";

					var value = nil;
					if (type == "BOOL") {
						value = node.getBoolValue() ? "true" : "false";
						title.setValue("Hint: Ctrl-click toggles bool values");
						settimer(func title.setValue(dir), 5, 1);
					} elsif (type == "STRING") {
						value = node.getValue();
					} elsif (type == "NONE") {
						value = "";
					} elsif (type != "ALIAS") {
						value = node.getValue() ~ "";
					}
					label.setValue(string.squeeze(name, 30));
					input.setValue(value);
				}
				update("input");
			}

			var set = func {
				if (node != nil)
					node.setValue(input.getValue());
			}

			var clone = func(start) {
				startdir.setValue(start);
				var base = props.globals.getNode("/sim/gui/dialogs", 1);
				var name = "property-browser";
				var new_ = base.addChild(name, 1);
				var path = new_.getPath();
				var i = new_.getIndex();
				if (! self.getNode("x", 1).getIntValue()) {
					self.getNode("x").setValue(self.getNode("__bx", 1).getValue() or 40);
				}
				if (! self.getNode("y", 1).getIntValue()) {
					self.getNode("y").setValue(self.getNode("__by", 1).getValue() or -40);
				}

				# update the property paths for dialog elements...
				self.setValues({
					"name": name~"["~i~"]",
					"dialog-name": name~"["~i~"]" ,
					"group[0]/group[0]/text/property": path ~ "/title",
					"property-list/property": path ~ "/list",
					"group[1]/text/property": path ~ "/label",
					"group[1]/input/property": path ~ "/input",
					"x": self.getNode("x").getIntValue() + 20,
					"y": self.getNode("y").getIntValue() - 20,
				});
				
				# ... and create new dialog
				fgcommand("dialog-new", self);
				fgcommand("dialog-show", self);
			}
			
			# this function removes the selection marker from the list
			var auto_update = func {
				list.setValue(dir);
				update("property-list");
				if (update_interval)
					settimer(auto_update, update_interval, 1);
			}

			dir = startdir.getValue();
			if (dir == nil) {
				dir = "/";
				startdir.setValue(dir);
			}
			list.setValue(dir);
			select();
			auto_update();
		]]>
		</open>

		<close>
		<![CDATA[
			update_interval = 0;
			dlg.remove();			
			startdir.setValue(dir);
		]]>
		</close>
	</nasal>
</PropertyList>
