# Dynon Avionics D180 by D-ECHO based on

# A3XX Lower ECAM Canvas
# Joshua Davidson (it0uchpods)
#######################################

var d180_main = nil;
var d180_start = nil;
var d180_display = nil;
var page = "main";

var groupMain = nil;

var base = props.globals.getNode("/instrumentation/efis-d180/", 1);
var menu_p = base.initNode("menu", 0, "INT");
var start_p = base.initNode("start", 0.0, "DOUBLE");

var volt_p = props.globals.getNode("/systems/electrical/outputs/efis", 1);

var qnh_hpa = props.globals.getNode("instrumentation/altimeter/setting-hpa", 1);
var alt_ft = props.globals.getNode("instrumentation/altimeter/indicated-altitude-ft", 1);

var ai_pitch = props.globals.getNode("orientation/pitch-deg", 1);
var ai_roll = props.globals.getNode("orientation/roll-deg", 1);

var ias_kt = props.globals.getNode("instrumentation/airspeed-indicator/indicated-speed-kt", 1);

var hdg_deg = props.globals.getNode("orientation/heading-deg", 1);

var wind_fr_deg = props.globals.getNode("environment/wind-from-heading-deg", 1);
var wind_sp_kt  = props.globals.getNode("environment/wind-speed-kt", 1);

var vs_fpm = props.globals.initNode("instrumentation/vertical-speed-indicator/indicated-speed-fpm", 0.0, "DOUBLE");

var ball_value = props.globals.getNode("instrumentation/slip-skid-ball/indicated-slip-skid", 1);

var instrument_path = "Aircraft/CH750STOL/Models/Interior/Panel/Dynon_D180/";





#roundToNearest function used for alt tape, thanks @Soitanen (737-800)!
var roundToNearest = func(n, m) {
	var x = int(n/m)*m;
	if((math.mod(n,m)) > (m/2) and n > 0)
			x = x + m;
	if((m - (math.mod(n,m))) > (m/2) and n < 0)
			x = x - m;
	return x;
}


var canvas_d180_base = {
	init: func(canvas_group, file) {
		var font_mapper = func(family, weight) {
			return "LiberationFonts/LiberationSans-Bold.ttf";
		};

		
		canvas.parsesvg(canvas_group, file, {'font-mapper': font_mapper});

		 var svg_keys = me.getKeys();
		 
		foreach(var key; svg_keys) {
			me[key] = canvas_group.getElementById(key);
			var svg_keys = me.getKeys();
			foreach (var key; svg_keys) {
			me[key] = canvas_group.getElementById(key);
			var clip_el = canvas_group.getElementById(key ~ "_clip");
			if (clip_el != nil) {
				clip_el.setVisible(0);
				var tran_rect = clip_el.getTransformedBounds();
				var clip_rect = sprintf("rect(%d,%d, %d,%d)", 
				tran_rect[1], # 0 ys
				tran_rect[2], # 1 xe
				tran_rect[3], # 2 ye
				tran_rect[0]); #3 xs
				#   coordinates are top,right,bottom,left (ys, xe, ye, xs) ref: l621 of simgear/canvas/CanvasElement.cxx
				me[key].set("clip", clip_rect);
				me[key].set("clip-frame", canvas.Element.PARENT);
			}
			}
		}
		
		if(me["horizon"]!=nil) {
			me.h_trans = me["horizon"].createTransform();
			me.h_rot = me["horizon"].createTransform();
		}

		me.page = canvas_group;

		return me;
	},
	getKeys: func() {
		return [];
	},
	update: func() {
		var volt = volt_p.getValue();
		var start = start_p.getValue();
		if ( start == 1 and volt > 11) {
			d180_start.page.hide();
			d180_main.page.show();
			d180_main.update();
		} else if ( start > 0.05 and start < 0.95 and volt > 11){
			d180_main.page.hide();
			d180_start.page.show();
		} else {
			d180_main.page.hide();
			d180_start.page.hide();
		}
		
		settimer(func me.update(), 0.02);
	},
};
	
	
var canvas_d180_main = {
	new: func(canvas_group, file) {
		var m = { parents: [canvas_d180_main , canvas_d180_base] };
		m.init(canvas_group, file);

		return m;
	},
	getKeys: func() {
		return ["asi.tape","asi.rollingdigits","asi.10","horizon","hdg.bar","hdg.digits","rollpointer","wind.arrow","wind.spd","vs.down","vs.up","alt.rollingdigits","alt.100","alt.1000","altTapeScale","altTextHigh1","altTextHigh2","altTextHigh3","altTextHigh4","altTextHigh5","altTextHigh6","altTextHigh7","altTextHigh8","altTextHigh9","altTextHigh10",
		"altTextLow1","altTextLow2","altTextLow3","altTextLow4","altTextLow5","altTextLow6","altTextLow7","altTextLow8","altTextLow9",
		"altTextHighSmall2","altTextHighSmall3","altTextHighSmall4","altTextHighSmall5","altTextHighSmall6","altTextHighSmall7","altTextHighSmall8","altTextHighSmall9","altTextHighSmall10",
		"altTextLowSmall1","altTextLowSmall2","altTextLowSmall3","altTextLowSmall4","altTextLowSmall5","altTextLowSmall6","altTextLowSmall7","altTextLowSmall8","altTextLowSmall9","qnh","menu","menu.name","menu.box1","menu.box2","menu.box3","menu.box4","menu.box5","menu.box6","ball"];
	},
	update: func() {
		
		#Attitude Indicator
		
		var pitch = ai_pitch.getValue();
		var roll =  ai_roll.getValue();
		
		me.h_trans.setTranslation(0,pitch*3.7);
		me.h_rot.setRotation(-roll*D2R,me["horizon"].getCenter());
		
		me["rollpointer"].setRotation(roll*D2R);
		
		#Airspeed indicator (ASI)
		var airspeed = ias_kt.getValue();
		if(airspeed > 20 ){
			me["asi.tape"].setTranslation(0,5.037*airspeed);
		}else{
			me["asi.tape"].setTranslation(0,0);
		}
		
		me["asi.10"].setText(sprintf("%2d", math.floor(airspeed/10, 10)));
		
		me["asi.rollingdigits"].setTranslation(0,math.round((10*math.mod(airspeed/10,1))*19, 0.1));
		
		#Heading indicator (HI)		
		var heading = hdg_deg.getValue();
		me["hdg.digits"].setText(sprintf("%3d", heading));		
		me["hdg.bar"].setTranslation(heading*-4,0);
		
		#Wind aloft indicator
		
		var wind_relative_direction = wind_fr_deg.getValue() - heading;
		var wind_speed = wind_sp_kt.getValue();
		
		me["wind.arrow"].setRotation(wind_relative_direction*D2R);
		if(wind_speed>2){
			me["wind.spd"].setText(sprintf("%3d", wind_speed));
		}else{	
			me["wind.spd"].setText("");
		}
		
		#Vertical speed indicator
		
		var vs =  vs_fpm.getValue();
		if(vs>0){
			if(vs<2000){
				me["vs.up"].setTranslation(0,-vs/1000*33);
			}else{
				me["vs.up"].setTranslation(0,-66);
			}
			me["vs.down"].setTranslation(0,0);
		}else{
			if(vs>-2000){
				me["vs.down"].setTranslation(0,-vs/1000*33);
			}else{
				me["vs.down"].setTranslation(0,66);
			}
			me["vs.up"].setTranslation(0,0);
		}
		
		#Altimeter
		
		var alt = alt_ft.getValue();
		var hpa = qnh_hpa.getValue();
		me["qnh"].setText(sprintf("%4d", math.round(hpa)));
		me["alt.1000"].setText(sprintf("%2d", math.floor(alt/1000, 1000)));
		me["alt.100"].setText(sprintf("%1d", 10*math.mod(math.floor(alt/100, 100)/10,1)));
		
		me["alt.rollingdigits"].setTranslation(0,100*math.mod(alt/100,1)*1.5);
		
		me["altTapeScale"].setTranslation(0,(alt - roundToNearest(alt, 1000))*0.33);
		
		if (roundToNearest(alt, 1000) == 0) {
			me["altTextLowSmall1"].setText(sprintf("%0.0f",1));
			me["altTextLowSmall2"].setText(sprintf("%0.0f",2));
			me["altTextLowSmall3"].setText(sprintf("%0.0f",3));
			me["altTextLowSmall4"].setText(sprintf("%0.0f",4));
			me["altTextLowSmall5"].setText(sprintf("%0.0f",5));
			me["altTextLowSmall6"].setText(sprintf("%0.0f",6));
			me["altTextLowSmall7"].setText(sprintf("%0.0f",7));
			me["altTextLowSmall8"].setText(sprintf("%0.0f",8));
			me["altTextLowSmall9"].setText(sprintf("%0.0f",9));
			me["altTextHighSmall2"].setText(sprintf("%0.0f",1));
			me["altTextHighSmall3"].setText(sprintf("%0.0f",2));
			me["altTextHighSmall4"].setText(sprintf("%0.0f",3));
			me["altTextHighSmall5"].setText(sprintf("%0.0f",4));
			me["altTextHighSmall6"].setText(sprintf("%0.0f",5));
			me["altTextHighSmall7"].setText(sprintf("%0.0f",6));
			me["altTextHighSmall8"].setText(sprintf("%0.0f",7));
			me["altTextHighSmall9"].setText(sprintf("%0.0f",8));
			me["altTextHighSmall10"].setText(sprintf("%0.0f",9));
			var altNumLow = "-";
			var altNumHigh = "";
			var altNumCenter = altNumHigh;
		} elsif (roundToNearest(alt, 1000) > 0) {
			me["altTextLowSmall1"].setText(sprintf("%0.0f",9));
			me["altTextLowSmall2"].setText(sprintf("%0.0f",8));
			me["altTextLowSmall3"].setText(sprintf("%0.0f",7));
			me["altTextLowSmall4"].setText(sprintf("%0.0f",6));
			me["altTextLowSmall5"].setText(sprintf("%0.0f",5));
			me["altTextLowSmall6"].setText(sprintf("%0.0f",4));
			me["altTextLowSmall7"].setText(sprintf("%0.0f",3));
			me["altTextLowSmall8"].setText(sprintf("%0.0f",2));
			me["altTextLowSmall9"].setText(sprintf("%0.0f",1));
			me["altTextHighSmall2"].setText(sprintf("%0.0f",1));
			me["altTextHighSmall3"].setText(sprintf("%0.0f",2));
			me["altTextHighSmall4"].setText(sprintf("%0.0f",3));
			me["altTextHighSmall5"].setText(sprintf("%0.0f",4));
			me["altTextHighSmall6"].setText(sprintf("%0.0f",5));
			me["altTextHighSmall7"].setText(sprintf("%0.0f",6));
			me["altTextHighSmall8"].setText(sprintf("%0.0f",7));
			me["altTextHighSmall9"].setText(sprintf("%0.0f",8));
			var altNumLow = roundToNearest(alt, 1000)/1000 - 1;
			var altNumHigh = roundToNearest(alt, 1000)/1000;
			var altNumCenter = altNumHigh;
		} elsif (roundToNearest(alt, 1000) < 0) {
			me["altTextLowSmall1"].setText(sprintf("%0.0f",1));
			me["altTextLowSmall2"].setText(sprintf("%0.0f",2));
			me["altTextLowSmall3"].setText(sprintf("%0.0f",3));
			me["altTextLowSmall4"].setText(sprintf("%0.0f",4));
			me["altTextLowSmall5"].setText(sprintf("%0.0f",5));
			me["altTextLowSmall6"].setText(sprintf("%0.0f",6));
			me["altTextLowSmall7"].setText(sprintf("%0.0f",7));
			me["altTextLowSmall8"].setText(sprintf("%0.0f",8));
			me["altTextLowSmall9"].setText(sprintf("%0.0f",9));
			me["altTextHighSmall2"].setText(sprintf("%0.0f",9));
			me["altTextHighSmall3"].setText(sprintf("%0.0f",8));
			me["altTextHighSmall4"].setText(sprintf("%0.0f",7));
			me["altTextHighSmall5"].setText(sprintf("%0.0f",6));
			me["altTextHighSmall6"].setText(sprintf("%0.0f",5));
			me["altTextHighSmall7"].setText(sprintf("%0.0f",4));
			me["altTextHighSmall8"].setText(sprintf("%0.0f",3));
			me["altTextHighSmall9"].setText(sprintf("%0.0f",2));
			me["altTextHighSmall10"].setText(sprintf("%0.0f",1));
			var altNumLow = roundToNearest(alt, 1000)/1000;
			var altNumHigh = roundToNearest(alt, 1000)/1000 + 1;
			var altNumCenter = altNumLow;
		}
		if ( altNumLow == 0 ) {
			altNumLow = "";
		}
		if ( altNumHigh == 0 and alt < 0) {
			altNumHigh = "-";
		}
		me["altTextLow1"].setText(sprintf("%s", altNumLow));
		me["altTextLow2"].setText(sprintf("%s", altNumLow));
		me["altTextLow3"].setText(sprintf("%s", altNumLow));
		me["altTextLow4"].setText(sprintf("%s", altNumLow));
		me["altTextLow5"].setText(sprintf("%s", altNumLow));
		me["altTextLow6"].setText(sprintf("%s", altNumLow));
		me["altTextLow7"].setText(sprintf("%s", altNumLow));
		me["altTextLow8"].setText(sprintf("%s", altNumLow));
		me["altTextLow9"].setText(sprintf("%s", altNumLow));
		me["altTextHigh1"].setText(sprintf("%s", altNumCenter));
		me["altTextHigh2"].setText(sprintf("%s", altNumHigh));
		me["altTextHigh3"].setText(sprintf("%s", altNumHigh));
		me["altTextHigh4"].setText(sprintf("%s", altNumHigh));
		me["altTextHigh5"].setText(sprintf("%s", altNumHigh));
		me["altTextHigh6"].setText(sprintf("%s", altNumHigh));
		me["altTextHigh7"].setText(sprintf("%s", altNumHigh));
		me["altTextHigh8"].setText(sprintf("%s", altNumHigh));
		me["altTextHigh9"].setText(sprintf("%s", altNumHigh));
		me["altTextHigh10"].setText(sprintf("%s", altNumHigh));
		
		#Virtual Ball
		me["ball"].setTranslation(ball_value.getValue()*50, 0);
		
		#Menus		
		var menu = menu_p.getValue();
		if(menu == 0){
			me["menu"].hide();
		}else if(menu == 1){
			me["menu"].show();
			me["menu.name"].setText("EFIS");
			me["menu.box1"].setText("");
			me["menu.box2"].setText("BARO");
			me["menu.box3"].setText("BUGS");
			me["menu.box4"].setText("LISTS");
			me["menu.box5"].setText("MORE");
			me["menu.box6"].setText("EXIT");
		}else if(menu == 2){
			me["menu"].show();
			me["menu.name"].setText("EFIS");
			me["menu.box1"].setText("SETUP");
			me["menu.box2"].setText("INFO");
			me["menu.box3"].setText("DIM");
			me["menu.box4"].setText("TIMER");
			me["menu.box5"].setText("MORE");
			me["menu.box6"].setText("EXIT");
		}else if(menu == 3){
			me["menu"].show();
			me["menu.name"].setText("BARO");
			me["menu.box1"].setText("UNITS:");
			me["menu.box2"].setText("MBAR");
			me["menu.box3"].setText("1013");
			me["menu.box4"].setText("DEC -");
			me["menu.box5"].setText("INC +");
			me["menu.box6"].setText("BACK");
		}
	}
	
};


var canvas_d180_start = {
	new: func(canvas_group, file) {
		var m = { parents: [canvas_d180_start , canvas_d180_base] };
		m.init(canvas_group, file);

		return m;
	},
	getKeys: func() {
		return [];
	},
	update: func() {
	}
	
};




setlistener("sim/signals/fdm-initialized", func {
	d180_display = canvas.new({
		"name": "EFIS_D180",
		"size": [854, 480],
		"view": [854, 480],
		"mipmapping": 1
	});
	d180_display.addPlacement({"node": "d180.screen"});
	var groupMain = d180_display.createGroup();
	var groupStart = d180_display.createGroup();


	d180_main = canvas_d180_main.new(groupMain, instrument_path~"d180-pfd.svg");
	d180_start = canvas_d180_start.new(groupStart, instrument_path~"d180-start.svg");
	canvas_d180_base.update();
});

var button5 = func {
	var current_menu = menu_p.getValue();
	if(current_menu == 0){
		setprop(base~"menu", 1);
	}else if(current_menu == 1){
		setprop(base~"menu", 2);
	}else if(current_menu == 2){
		setprop(base~"menu", 1);
	}else if(current_menu == 3){
		qnh_hpa.setValue(qnh_hpa.getValue()+1);
	}
}

setlistener(volt_p, func{
	if(volt_p.getValue() > 11 and start_p.getValue() == 0){
		interpolate(start_p, 1, 4 );
	}else if( volt_p.getValue() <= 11 and start_p.getValue() != 0){
		start_p.setValue(0);
	}
});
