<?xml version="1.0"?>

<PropertyList>
  <nasal>
    <open>
      <![CDATA[

        setprop("sim/gui/dialogs/metar/description[1]",
					"Simple and fast weather engine that interprets METAR data " ~
					"directly or a set of manually defined parameters. Recommended for use with Multiplayer.");
        setprop("sim/gui/dialogs/metar/description[2]",
					"Advanced weather engine that gives more detailed and realistic results based on METAR " ~
					"data and a set of predefined parameters. Click on 'Apply' to run the engine, as the engine " ~
					"does not automatically load upon startup.");

        var normalize_string = func(src) {
          if( src == nil ) src = "";
          var dst = "";
          for( var i = 0; i < size(src); i+=1 ) {
            if( src[i] == `\n` or src[i] == `\r` )
              src[i] = ` `;

            if (i == 0 and src[i] == ` `)
              continue;

            if( i != 0 and src[i] == ` ` and src[i-1] == ` ` )
              continue;

            dst = dst ~ " ";
            dst[size(dst)-1] = src[i];
          }
          return dst;
        }

      var GlobalWeatherDialogController = {

        new : func( dlgRoot ) {
          var obj = { parents: [GlobalWeatherDialogController] };
          obj.dlgRoot = dlgRoot;
          obj.base = "sim/gui/dialogs/metar";
          obj.baseN = props.globals.getNode( obj.base, 1 );

          return obj;
        },

        refresh : func {

          var scenarioName = getprop( me.base ~ "/source-selection");

          if (getprop( me.base ~ "/mode/manual-weather")) {
            # In manual weather mode we have to disable live weather
            # fetch so the weather can be changed by the user in the
            # weather configuration dialog.

            setprop( "/environment/params/metar-updates-environment", 0 );
            setprop( "/environment/realwx/enabled", 0 );
            setprop( "/environment/config/enabled", 1 );
          } else if( scenarioName == "Live data" ) {
            # If we've selected Live Data we need to force
            # a refresh of the Live Data setting.
            setprop( "/environment/realwx/enabled", 1 );
          }
        },

        open : func {

          # Determine the weather mode.
          if ( getprop("/nasal/local_weather/enabled") == 1) {
            # Local weather mode
            setprop( me.base ~ "/mode/global-weather", "0" );
            setprop( me.base ~ "/mode/local-weather", "1" );
            setprop( me.base ~ "/mode/manual-weather", "0" );
          } else if ( getprop( "environment/params/metar-updates-environment" ) == 0 ) {
            # Manual weather mode
            setprop( me.base ~ "/mode/global-weather", "1" );
            setprop( me.base ~ "/mode/local-weather", "0" );
            setprop( me.base ~ "/mode/manual-weather", "1" );
          } else {
            # Global weather mode
            setprop( me.base ~ "/mode/global-weather", "1" );
            setprop( me.base ~ "/mode/local-weather", "0" );
            setprop( me.base ~ "/mode/manual-weather", "0" );
          }

          # initialize the METAR source selection
          if( getprop( "environment/realwx/enabled" ) ) {
            setprop( me.base ~ "/source-selection", "Live data" );
          } else {
            # preset configured scenario
            var wsn = props.globals.getNode( "/environment/weather-scenarios" );
            var current = getprop("/environment/weather-scenario", "");
            var found = 0;
            if( wsn != nil ) {
              var scenarios = wsn.getChildren("scenario");
              forindex (var i; scenarios ) {
                var metarN = scenarios[i].getNode("metar");
                metarN == nil and continue;
                if( scenarios[i].getNode("name").getValue() == current ) {
                  setprop( me.base ~ "/source-selection", scenarios[i].getNode("name").getValue() );
                  found = 1;
                  break;
                }
              }
            }
            if( found == 0 )
              setprop( me.base ~ "/source-selection", "Manual input" );
          }

          setprop( me.base ~ "/metar-string", normalize_string(getprop("environment/metar/data")) );
          gui.findElementByName( me.dlgRoot, "metar-string" ).getNode("legend", 1).setValue(normalize_string(getprop("environment/metar/data")));

          # fill the METAR source combo box
          var combo = gui.findElementByName( me.dlgRoot, "source-selection" );
          var wsn = props.globals.getNode( "/environment/weather-scenarios" );
          if( wsn != nil ) {
            var scenarios = wsn.getChildren("scenario");
            forindex (var i; scenarios ) {
              combo.getChild("value", i, 1).setValue(scenarios[i].getNode("name").getValue());
            }
          }

          me.scenarioListenerId = setlistener( me.base ~ "/source-selection", func(n) { me.scenarioListener(n); }, 1, 1 );
          me.metarListenerId = setlistener( "environment/metar/valid", func(n) { me.metarListener(n); }, 1, 1 );

          # Update the dialog itself
          me.refresh();
        },

        close : func {
          removelistener( me.scenarioListenerId );
          removelistener( me.metarListenerId );
        },

        apply : func {
          var scenarioName = getprop( me.base ~ "/source-selection");
          var metar = getprop( "environment/metar/data" );
          var global_weather_enabled = getprop( me.base ~ "/mode/global-weather");
          var local_weather_enabled = getprop( me.base ~ "/mode/local-weather");
          var manual_weather_enabled = getprop( me.base ~ "/mode/manual-weather");

          # General weather settings based on scenario
          if (manual_weather_enabled == 1) {
            setprop( "/environment/params/metar-updates-environment", 0 );
            setprop( "/environment/realwx/enabled", 0 );
            setprop( "/environment/config/enabled", 1 );
            metar = "";
          } else if( scenarioName == "Live data" ) {
            setprop( "/environment/params/metar-updates-environment", 1 );
            setprop( "/environment/realwx/enabled", 1 );
            setprop( "/environment/config/enabled", 1 );
          } else if( scenarioName == "Manual input" ) {
            setprop( "/environment/params/metar-updates-environment", 1 );
            setprop( "/environment/realwx/enabled", 0 );
            setprop( "/environment/config/enabled", 1 );
            metar = getprop( me.base ~ "/metar-string" );
          } else {
            setprop( "/environment/params/metar-updates-environment", 1 );
            setprop( "/environment/realwx/enabled", 0 );
            setprop( "/environment/config/enabled", 1 );
            metar = getprop( me.base ~ "/metar-string" );
            setprop("/environment/weather-scenario", scenarioName);
          }

          if( metar != nil ) {
            setprop( "environment/metar/data", normalize_string(metar) );
          }

          # Clear any local weather that might be running
          if (getprop("/nasal/local_weather/loaded")) local_weather.clear_all();
          setprop("/nasal/local_weather/enabled", "false");

          if (local_weather_enabled) {
            # If Local Weather is enabled, re-initialize with updated
            # initial tile and tile selection.
            setprop("/nasal/local_weather/enabled", "true");

            # Re-initialize local weather.
            settimer( func {local_weather.set_tile();}, 0.2);
          }
        },

        findScenarioByName : func(name) {
          var wsn = props.globals.getNode( "/environment/weather-scenarios" );
          if( wsn != nil ) {
            var scenarios = wsn.getChildren("scenario");
            foreach (var scenario; scenarios ) {
              if( scenario.getNode("name").getValue() == name )
                return scenario;
            }
          }
          return nil;
        },

        scenarioListener : func( n ) {
          var description = "";
          var metar = "nil";
          var local_weather_props = nil;

          var scenario = me.findScenarioByName( n.getValue() );
          if( scenario != nil ) {
            description = normalize_string(scenario.getNode("description", 1 ).getValue());
            metar = normalize_string(scenario.getNode("metar", 1 ).getValue());
            local_weather_props = scenario.getNode("local-weather");
          }

          if (n.getValue() == "Live data") {
            # Special case - retrieve live data
            var metar = getprop( "environment/metar/data" );
          }

          if (n.getValue() == "Manual input") {
            # Special case - retain current values
            var metar = getprop( me.base ~ "/metar-string" );
          }

          setprop(me.base ~ "/description", description );
          setprop(me.base ~ "/metar-string", metar );

          # Set the wind from the METAR string.
          var result = [];
          var msplit = split(" ", string.uc(metar));
          foreach (var word; msplit) {

            if ((size(word) > 6) and string.match(word, "*[0-9][0-9]KT")) {
              # We've got the wind definition word. Now to split it up.
              # Format is nnnmmKT or nnnmmGppKT
              # Direction is easy - the first 3 characters.
              var dir = chr(word[0]) ~ chr(word[1]) ~ chr(word[2]);

              if (dir == "VRB") {
                setprop("/local-weather/tmp/tile-orientation-deg", 360.0 * rand());
                setprop("/local-weather/tmp/gust-angular-variation-deg", 180.0);
                setprop("/local-weather/tmp/gust-frequency-hz", 0.001);
              } else {
                setprop("/local-weather/tmp/tile-orientation-deg", dir);
                setprop("/local-weather/tmp/gust-angular-variation-deg", 0.0);
                setprop("/local-weather/tmp/gust-frequency-hz", 0.0);
              }

              # Next two are the base wind
              var spd = chr(word[3]) ~ chr(word[4]);
              setprop("/local-weather/tmp/windspeed-kt", spd);

              var gst = 0;
              if ((size(word) > 7) and (chr(word[5]) == 'G')) {
                # Gusty case
                gst = chr(word[6]) ~ chr(word[7]);
              }

              if ((gst > spd) and (spd > 0)) {
                setprop("/local-weather/tmp/gust-relative-strength", (gst - spd) / spd);
                setprop("/local-weather/tmp/gust-frequency-hz", 0.7);
              } else {
                setprop("/local-weather/tmp/gust-relative-strength", 0.0);
              }
            }
          }


          if (local_weather_props != nil) {
            # The local weather properties need to be set now, so they can
            # be configured by the user if they select Advanced Settings
            props.copy(local_weather_props, props.globals.getNode("/local-weather/tmp", 1));
          } else {
            # If no local weather properties have been set, we'll read from the scenario
            # METAR
            setprop("/local-weather/tmp/tile-type", "manual");
            setprop("/local-weather/tmp/tile-management", "METAR");
          }

          me.refresh();
        },

        metarListener : func( n ) {
          var metar = getprop("environment/metar/data");
          if( metar == nil or metar == "" ) metar = "NIL";
          metar = normalize_string(metar);
          printlog( "info", "new METAR: " ~ metar );
          setprop( me.base ~ "/metar-string", metar );
          gui.dialog_update( "weather-conditions", "metar-string" );
        },

      };

      var controller = GlobalWeatherDialogController.new( cmdarg() );
      controller.open();
    ]]>
    </open>

    <close>
      <![CDATA[
      controller.close();
    ]]>
    </close>
  </nasal>

  <!-- Control the weather -->
  <name>weather</name>
  <modal>false</modal>
  <resizable>false</resizable>
  <layout>vbox</layout>
  <default-padding>3</default-padding>

  <!-- Title bar with close button -->
  <group>
    <layout>hbox</layout>
    <default-padding>1</default-padding>

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

    <text>
      <label>Weather Conditions</label>
    </text>

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

    <button>
      <legend/>
      <key>Esc</key>
      <pref-width>16</pref-width>
      <pref-height>16</pref-height>
      <border>2</border>
      <binding>
        <command>dialog-close</command>
      </binding>
    </button>
  </group>

  <hrule/>

  <group>
    <layout>hbox</layout>

    <!-- only for a gap -->
    <group>
      <layout>vbox</layout>
      <default-padding>1</default-padding>
      <text>
        <label> </label>
      </text>
    </group>

    <group>
      <layout>vbox</layout>

      <text>
        <halign>left</halign>
        <label>Select Weather Engine</label>
      </text>

      <group>
        <layout>hbox</layout>
        <halign>left</halign>
        <group>
          <layout>table</layout>
  <!--
          <pref-width>500</pref-width>
  -->
          <radio>
            <row>0</row>
            <col>0</col>
            <halign>left</halign>
            <name>simple-weather</name>
            <property>sim/gui/dialogs/metar/mode/global-weather</property>
            <live>true</live>
            <label>Basic Weather</label>
            <binding>
              <command>property-assign</command>
              <property>sim/gui/dialogs/metar/mode/global-weather</property>
              <value>1</value>
            </binding>
            <binding>
              <command>property-assign</command>
              <property>sim/gui/dialogs/metar/mode/local-weather</property>
              <value>0</value>
            </binding>
            <binding>
              <command>property-assign</command>
              <property>sim/gui/dialogs/metar/mode/manual-weather</property>
              <value>0</value>
            </binding>
            <binding>
              <command>nasal</command>
              <script>
                controller.refresh();
              </script>
            </binding>
          </radio>
          <checkbox>
            <row>0</row>
            <col>1</col>
  					<halign>right</halign>
            <name>manual-weather-config</name>
            <property>sim/gui/dialogs/metar/mode/manual-weather</property>
            <label>Manual Configuration</label>
            <live>true</live>
            <enable>
              <property>sim/gui/dialogs/metar/mode/global-weather</property>
            </enable>
            <binding>
              <command>dialog-apply</command>
              <object-name>manual-weather-config</object-name>
            </binding>
            <binding>
              <command>nasal</command>
              <script>
                controller.refresh();
              </script>
            </binding>
          </checkbox>

          <empty>
            <row>0</row>
            <col>2</col>
            <stretch>true</stretch>
          </empty>

  				<button>
            <row>0</row>
            <col>3</col>
  					<halign>right</halign>
  <!--
  					<pref-width>170</pref-width>
  -->
  					<legend>Manual Configuration ...</legend>
  					<enable>
  						<property>sim/gui/dialogs/metar/mode/manual-weather</property>
  					</enable>
  					<binding>
  						<command>dialog-show</command>
  						<dialog-name>weather-configuration</dialog-name>
  					</binding>
  					<!--<binding>
  						<command>property-assign</command>
  						<property>sim/gui/dialogs/metar/mode/manual-weather</property>
  						<value>1</value>
  					</binding>-->
  				</button>
        </group>
      </group>

      <textbox>
        <name>basic description</name>
        <halign>fill</halign>
        <stretch>true</stretch>
  <!--
        <pref-width>250</pref-width>
  -->
        <pref-height>70</pref-height>
        <slider>15</slider>
        <editable>false</editable>
        <wrap>true</wrap>
        <live>true</live>
        <top-line>0</top-line>
        <property>sim/gui/dialogs/metar/description[1]</property>
      </textbox>

      <group>
        <layout>hbox</layout>
        <halign>left</halign>
        <group>
          <layout>table</layout>
  <!--
          <pref-width>500</pref-width>
  -->
          <radio>
            <row>0</row>
            <col>0</col>
            <label>Detailed Weather</label>
            <halign>left</halign>
            <name>simple-weather</name>
            <property>sim/gui/dialogs/metar/mode/local-weather</property>
            <live>true</live>
            <binding>
              <command>property-assign</command>
              <property>sim/gui/dialogs/metar/mode/local-weather</property>
              <value>1</value>
            </binding>
            <binding>
              <command>property-assign</command>
              <property>sim/gui/dialogs/metar/mode/global-weather</property>
              <value>0</value>
            </binding>
            <binding>
              <command>property-assign</command>
              <property>sim/gui/dialogs/metar/mode/manual-weather</property>
              <value>0</value>
            </binding>
            <binding>
              <command>nasal</command>
              <script>
                controller.refresh();
              </script>
            </binding>
          </radio>

  				<text>
            <row>0</row>
            <col>1</col>
            <label>                          </label>
  				</text>

          <empty>
            <row>0</row>
            <col>2</col>
            <stretch>true</stretch>
          </empty>

  				<button>
            <row>0</row>
            <col>3</col>
  					<legend>  Advanced Settings ...</legend>
  					<halign>right</halign>
  <!--
  					<pref-width>170</pref-width>
  -->
  					<enable>
  						<property>sim/gui/dialogs/metar/mode/local-weather</property>
  						<value>1</value>
  					</enable>
  					<binding>
  						<command>dialog-show</command>
  						<dialog-name>local-weather</dialog-name>
  					</binding>
  				</button>
        </group>
      </group>

      <textbox>
        <name>advance-description</name>
        <halign>fill</halign>
        <stretch>true</stretch>
  <!--
        <pref-width>250</pref-width>
  -->
        <pref-height>90</pref-height>
        <slider>15</slider>
        <editable>false</editable>
        <wrap>true</wrap>
        <live>true</live>
        <top-line>0</top-line>
        <property>sim/gui/dialogs/metar/description[2]</property>
      </textbox>

  <!--
      <group>
        <layout>table</layout>

      </group>
  -->
      <empty>
        <stretch>true</stretch>
      </empty>

    </group>

    <!-- only for a gap -->
    <group>
      <layout>vbox</layout>
      <default-padding>1</default-padding>
      <text>
        <label> </label>
      </text>
    </group>

  </group>

  <hrule/>

  <group>
    <layout>hbox</layout>

    <!-- only for a gap -->
    <group>
      <layout>vbox</layout>
      <default-padding>1</default-padding>
      <text>
        <label> </label>
      </text>
    </group>

    <group>
      <layout>vbox</layout>
      <halign>left</halign>

      <group>
        <layout>hbox</layout>
        <halign>left</halign>
        <group>
          <layout>table</layout>
          <text>
            <row>0</row>
            <col>0</col>
            <label>Weather Conditions</label>
            <halign>left</halign>
          </text>
          <text>
            <row>0</row>
            <col>1</col>
            <label>      </label>
            <halign>left</halign>
          </text>
          <combo>
            <row>0</row>
            <col>2</col>
            <name>source-selection</name>
            <halign>fill</halign>
            <stretch>true</stretch>
            <pref-width>300</pref-width>
            <property>sim/gui/dialogs/metar/source-selection</property>
            <enable>
              <equals>
                <property>sim/gui/dialogs/metar/mode/manual-weather</property>
                <value>0</value>
              </equals>
            </enable>
            <binding>
              <command>dialog-apply</command>
              <object-name>source-selection</object-name>
            </binding>
            <binding>
              <command>dialog-update</command>
              <object-name>metar-string</object-name>
            </binding>
          </combo>
        </group>
      </group>

      <group>
        <layout>hbox</layout>
        <text>
          <label>METAR Data</label>
        </text>
        <empty>
          <stretch>true</stretch>
        </empty>
        <text>
          <label>                                              </label>
        </text>
        <text>
          <label>Data is valid</label>
        </text>
        <checkbox>
          <property>/environment/metar/valid</property>
          <label/>
          <live>true</live>
          <enable>
            <false/>
          </enable>
        </checkbox>
      </group>

      <group>
        <layout>hbox</layout>
        <textbox>
          <name>metar-string</name>
          <halign>fill</halign>
          <stretch>true</stretch>
  <!--
          <pref-width>250</pref-width>
  -->
          <pref-height>70</pref-height>
          <slider>15</slider>
          <editable>true</editable>
          <wrap>true</wrap>
          <live>false</live>
          <top-line>0</top-line>
          <property>sim/gui/dialogs/metar/metar-string</property>
          <enable>
            <and>
              <equals>
                <property>sim/gui/dialogs/metar/mode/manual-weather</property>
                <value>0</value>
              </equals>
              <equals>
                <property>sim/gui/dialogs/metar/source-selection</property>
                <value>Manual input</value>
              </equals>
            </and>
          </enable>
          <binding>
            <command>dialog-apply</command>
            <object-name>metar-string</object-name>
          </binding>
        </textbox>
      </group>

      <group>
        <layout>hbox</layout>
        <text>
          <label>Description</label>
        </text>
        <empty>
          <stretch>true</stretch>
        </empty>
      </group>

      <textbox>
        <name>description</name>
        <halign>fill</halign>
        <stretch>true</stretch>
        <pref-width>450</pref-width>
        <pref-height>100</pref-height>
        <slider>15</slider>
        <editable>false</editable>
        <wrap>true</wrap>
        <live>true</live>
        <top-line>0</top-line>
        <property>sim/gui/dialogs/metar/description[0]</property>
      </textbox>

    </group>

    <!-- only for a gap -->
    <group>
      <layout>vbox</layout>
      <default-padding>1</default-padding>
      <text>
        <label> </label>
      </text>
    </group>

  </group>

  <hrule/>

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

    <button>
      <legend>OK</legend>
      <equal>true</equal>
      <binding>
        <command>dialog-apply</command>
        <object-name>metar-string</object-name>
      </binding>
      <binding>
        <command>nasal</command>
        <script>
          controller.apply();
        </script>
      </binding>
      <binding>
        <command>dialog-close</command>
      </binding>
    </button>

    <button>
      <legend>Apply</legend>
      <equal>true</equal>
      <binding>
        <command>dialog-apply</command>
        <object-name>metar-string</object-name>
      </binding>
      <binding>
        <command>nasal</command>
        <script>
          controller.apply();
        </script>
      </binding>
    </button>

    <button>
      <legend>Close</legend>
      <equal>true</equal>
      <default>true</default>
      <key>Esc</key>
      <binding>
        <command>dialog-close</command>
      </binding>
    </button>
    <empty>
      <stretch>true</stretch>
    </empty>
  </group>

</PropertyList>