# Garmin GPS100 by Bea Wolf (D-ECHO) based on A320 canvas avionics by Joshua Davidson
# References: 	http://retro-gps.info/Manuals/downloads/files/Garmin%20GPS%20100AVD_Inst.pdf
#		http://static.garmin.com/pumac/GPS100STD_OwnersManual.pdf

var GPS100_selftest = nil;
var GPS100_init = nil;
var GPS100_gpsstat = nil;
var GPS100_position = nil;
var GPS100_display = nil;

var volts		=	props.globals.getNode("/systems/electrical/outputs/gps", 1);
var base		=	props.globals.getNode("/instrumentation/gps100/");

var pos			=	props.globals.getNode("/position");
var ori			=	props.globals.getNode("/orientation");
var vel			=	props.globals.getNode("/velocities");

var alt			=	pos.getNode("altitude-ft");
var gs			=	vel.getNode("groundspeed-kt");
var trk			=	ori.getNode("track-deg");

var instrument_path = "Aircraft/HK36/Models/Instruments/GPS100/";

var gps_status = 0; # 0 = search sky; 1 = acquiring; 2 = 2D NAV; 3 = 3D NAV
var state = 0;	# 0 = off; 1 = starting; 2 = waiting for init confirmation; 3 = running

var canvas_GPS100_base = {
	init: func(canvas_group, file) {
		var font_mapper = func(family, weight) {
			return "lcd.txf";
		};

		
		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 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);
			}
		}

		me.page = canvas_group;

		return me;
	},
	getKeys: func() {
		return [];
	},
	update: func() {
		if ( volts.getValue() >= 10) {
			if ( state == 3 ){
				if ( gps_status >= 2 ) {
					GPS100_position.page.show();
					GPS100_position.update();
					GPS100_gpsstat.page.hide();
					GPS100_init.page.hide();
					GPS100_selftest.page.hide();
				} else {
					GPS100_position.page.hide();
					GPS100_gpsstat.page.show();
					GPS100_gpsstat.update();
					GPS100_init.page.hide();
					GPS100_selftest.page.hide();
				}
			} else if ( state == 2 ){
				GPS100_init.page.show();
				GPS100_init.update();
				GPS100_gpsstat.page.hide();
				GPS100_position.page.hide();
				GPS100_selftest.page.hide();
			} else if ( state == 1 ){
				GPS100_position.page.hide();
				GPS100_gpsstat.page.hide();
				GPS100_init.page.hide();
				GPS100_selftest.page.show();
			}
		} else {
			GPS100_position.page.hide();
			GPS100_gpsstat.page.hide();
			GPS100_selftest.page.hide();
			GPS100_init.page.hide();
		}
	},
};
	
	
var canvas_GPS100_position = {
	new: func(canvas_group, file) {
		var m = { parents: [canvas_GPS100_position , canvas_GPS100_base] };
		m.init(canvas_group, file);

		return m;
	},
	getKeys: func() {
		return ["alt","lon.string","lat.string", "gs", "trk"];
	},
	update: func() {
		me["alt"].setText(sprintf("%5d", alt.getValue()));
		
		me["lon.string"].setText( getprop("/position/longitude-string") );
		me["lat.string"].setText( getprop("/position/latitude-string") );
		
		var gs_string = "";
		var gs_value = gs.getValue();
		if( gs_value >= 10.0 ){
			gs_string = sprintf("%3d", gs_value);
		} else {
			gs_string = sprintf("%3.1f", gs_value);
		}
		me["gs"].setText( gs_string );
		me["trk"].setText(sprintf("%3d", trk.getValue() ));
	},
};


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

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

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

		return m;
	},
	getKeys: func() {
		return ["utc","lon.string","lat.string","nearest_fix","bearing_to_nearest","dist_from_nearest"];
	},
	update: func() {
		me["utc"].setText(getprop("/sim/time/gmt"));
		
		me["lon.string"].setText( getprop("/position/longitude-string") );
		me["lat.string"].setText( getprop("/position/latitude-string") );
		
		
	},
};

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

		return m;
	},
	getKeys: func() {
		return ["status"];
	},
	update: func() {		
		if ( gps_status == 0 ){
			me["status"].setText("SEARCH SKY");
		} else if ( gps_status == 1 ){
			me["status"].setText("ACQUIRING");
		} else if ( gps_status == 2 ){
			me["status"].setText("2D NAV");
		} else if ( gps_status == 3 ){
			me["status"].setText("3D NAV");
		} else {
			me["status"].setText("INVALID");
		}
	},
};


var gps100_update = maketimer(0.2, func {
	canvas_GPS100_base.update();
});

setlistener("sim/signals/fdm-initialized", func {
	GPS100_display = canvas.new({
		"name": "GPS100",
		"size": [512, 128],
		"view": [512, 128],
		"mipmapping": 1
	});
	GPS100_display.addPlacement({"node": "gps100.display"});
	var groupMain = GPS100_display.createGroup();
	var groupSelftest = GPS100_display.createGroup();
	var groupInit = GPS100_display.createGroup();
	var groupGPSStat = GPS100_display.createGroup();


	GPS100_position = canvas_GPS100_position.new(groupMain, instrument_path~"gps100_position.svg");
	GPS100_selftest = canvas_GPS100_selftest.new(groupSelftest, instrument_path~"gps100_selftest.svg");
	GPS100_init = canvas_GPS100_init.new(groupInit, instrument_path~"gps100_init.svg");
	GPS100_gpsstat = canvas_GPS100_gpsstat.new(groupGPSStat, instrument_path~"gps100_gps_status.svg");

	gps100_update.start();
});

var check_state = func () {
	if ( state == 0 ){
		if ( volts.getValue() >= 10 ) {
			state = 1;
			init();
			settimer( func() { state = 2; }, 2);
		}
	} else {
		if ( volts.getValue() < 10 ){
			state = 0;
		}
	}
}

var init = func () {
	
}

var enter_button = func () {
	if ( state == 2 ){
		state = 3;
		gps_status = 0;
		settimer( func() { 
				gps_status = 1;
				settimer( func() { gps_status = 3; }, 5);
			}, 10 );
	}
}

setlistener(volts, func{
	check_state();
});
