##########
#this utility is a workaround for the fact that a shader uses listeners which cannot
# be used with a tied property
#

# TODO: Make this optional (when shaders disabled etc), or move computation
# away from Nasal.

#does what it says on the tin
var clamp = func(v, min, max) { v < min ? min : v > max ? max : v }

#set global variables
var Amp = 1.0;
var Angle = 35.0;
var DAngle = 20.0;
var Freq = 0.01;
var Factor = 0.0004;
var Sharp = 1.0;

#add control properies for waves
var wave_amp_Node = props.globals.getNode("/environment/wave/amp" , 1);
wave_amp_Node.setDoubleValue(Amp);

var wave_freq_Node = props.globals.getNode("/environment/wave/freq" , 1);
wave_freq_Node.setDoubleValue(Freq);

var wave_sharp_Node = props.globals.getNode("/environment/wave/sharp" , 1);
wave_sharp_Node.setDoubleValue(Sharp);

var wave_angle_Node = props.globals.getNode("/environment/wave/angle" , 1);
wave_angle_Node.setDoubleValue(Angle);

var wave_factor_Node = props.globals.getNode("/environment/wave/factor" , 1);
wave_factor_Node.setDoubleValue(Factor);

var wave_factor_Node = props.globals.getNode("/environment/wave/dangle" , 1);
wave_factor_Node.setDoubleValue(DAngle);

props.globals.initNode("/environment/sea/surface/wind-speed-kt", 0, "DOUBLE");
props.globals.initNode("/environment/sea/surface/wind-from-east-fps", 0, "DOUBLE");
props.globals.initNode("/environment/sea/surface/wind-from-north-fps", 0, "DOUBLE");
props.globals.initNode("/environment/sea/surface/wind-from-deg", 0, "DOUBLE");
props.globals.initNode("/environment/sea/surface/config/enabled", 0, "DOUBLE");
#object rotation values
props.globals.initNode("/orientation/model/heading-deg", 0, "DOUBLE");
props.globals.initNode("/orientation/model/pitch-deg", 0, "DOUBLE");
props.globals.initNode("/orientation/model/roll-deg", 0, "DOUBLE");


var update_waves = func (wind) {
	var wind = 0;
	var amp = 0;
	var angle = 0;
	var dangle = 0;
	var freq = 0;
	var factor = 0;
	var sharp = 0;

	amp = Amp + 0.02 * wind;
	amp = clamp(amp, 1.0, 2.0);

	setprop("/environment/wave/amp", amp);

	angle = Angle + 0.2 * wind;
	setprop("/environment/wave/angle", angle);

	dangle = DAngle - 0.4 * wind;
	setprop("/environment/wave/dangle", dangle);

	freq = Freq + 0.0008 * wind;
	freq = clamp(freq, 0.01, 0.015);
	setprop("/environment/wave/freq", freq);

	factor = Factor - 0.00001 * wind;
	factor = clamp(factor, 0.0001, 0.0004);
	setprop("/environment/wave/factor", factor);

	sharp = Sharp + 0.02 * wind;
	sharp = clamp(sharp, 1.0, 2.0);
	setprop("/environment/wave/sharp", sharp);
};

var is_initialized = 0;
var initialize = func {
	if (is_initialized)
		return; # only install listeners once
	is_initialized = 1;

	var wind_from_east_Node = props.globals.getNode("/environment/config/boundary/entry[0]/wind-from-east-fps", 1);
	wind_from_east_Node.setDoubleValue(0);

	var wind_from_north_Node = props.globals.getNode("/environment/config/boundary/entry[0]/wind-from-north-fps", 1);
	wind_from_north_Node.setDoubleValue(0);

	var wind_from_Node = props.globals.getNode("/environment/config/boundary/entry[0]/wind-from-heading-deg", 1);
	wind_from_Node.setDoubleValue(0);

	var wind_speed_Node = props.globals.getNode("/environment/config/boundary/entry[0]/wind-speed-kt", 1);
	wind_speed_Node.setDoubleValue(0);

	var wind_status_Node = props.globals.getNode("/environment/config/enabled", 1);
	wind_status_Node.setBoolValue(1);

	var ground_vis_Node = props.globals.getNode("/environment/ground-visibility-m", 1);
	ground_vis_Node.setDoubleValue(500);

	var ground_thick_Node = props.globals.getNode("/environment/ground-haze-thickness-m" , 1);
	ground_thick_Node.setDoubleValue(300);

	var ground_term_Node = props.globals.getNode("/environment/terminator-relative-position-m" , 1);
	ground_term_Node.setDoubleValue(60000);

# ##################  listeners ####################
#
# installing a listener to /environment/sea/surface/wind-speed-kt does not make sense,
# since it's currently being written in _every_ update loop anyway).
#	setlistener("/environment/sea/surface/wind-speed-kt", func(n) {update_waves(n.getValue())},
#		1,
#		0);# end listener
		
	print("weather util initialized ...");
	loop();
}# end init

var loop = func {
	var value = getprop("/environment/config/boundary/entry[0]/wind-from-east-fps");
	setprop("/environment/sea/surface/wind-from-east-fps", value);
#        print("wind-from-east-fps ", getprop("/environment/sea/surface/wind-from-east-fps"));

	value = getprop("/environment/config/boundary/entry[0]/wind-from-north-fps");
	setprop("/environment/sea/surface/wind-from-north-fps", value);
#        print("wind-from-north-fps ", getprop("/environment/sea/surface/wind-from-north-fps"));

	value = getprop("/environment/config/boundary/entry[0]/wind-from-heading-deg");
	setprop("/environment/sea/surface/wind-from-deg", value);
#        print("wind-from-deg ", getprop("/environment/sea/surface/wind-from-deg"));

	value = getprop("/environment/config/boundary/entry[0]/wind-speed-kt");
	setprop("/environment/sea/surface/wind-speed-kt", value);
#        print("wind-speed-kt ", getprop("/environment/sea/surface/wind-speed-kt"));
	# Direct call to update wave settings (much more effective than using a listener,
	# since it's written in every loop anyway.
	update_waves(value);

	value = getprop("/environment/config/enabled");
	setprop("/environment/sea/config/enabled", value);
#        print("wind-speed-kt ", getprop("/environment/config/enabled"));

#						orientation fix
#orientation
	value = getprop("/orientation/heading-deg") or 0.0;
	setprop("/orientation/model/heading-deg", value);
	value = getprop("/orientation/pitch-deg") or 0.0;
	setprop("/orientation/model/pitch-deg", value);
	value = getprop("/orientation/roll-deg") or 0.0;
	setprop("/orientation/model/roll-deg", value);

	settimer(loop,0);

}

# Fire it up

setlistener("sim/signals/fdm-initialized", initialize);

# end

###
# Adjust snow line to match METAR
#

var snowLineDefault = 3200;

_setlistener("/environment/metar/valid", func {
	var snowCover = getprop("/environment/metar/snow-cover");
	var snowLine = getprop("/environment/snow-level-m");
	
	# Put the snow line slightly below the station's elevation, 
	# so the station is completely covered with snow
	var stationElev = getprop("/environment/metar/station-elevation-ft") * globals.FT2M - 50;

	if (snowCover == 1){
		if (stationElev > snowLineDefault) { snowLine = snowLineDefault; }
		if ((stationElev <= snowLineDefault) and (snowLine > stationElev)) { snowLine = stationElev; }
	}
	setprop("/environment/snow-level-m",snowLine);
});

#
###