// Install and Remove scripts for GPS Trackers
	
InstallScript := func(partFrame)
begin
	// register the auxiliary GPS button for Notes
	RegAuxButton(kAuxGPSSymbol,{
		destApp: 'paperroll,// Add buttons to Notes
		_proto: protoTextButton,
		text: "GPS",
		viewBounds: RelBounds(0,0,40,10),
		trk:	nil,	// the GPS tracker
		nTrys:	0,		// used in getPos
		maxTrys: 10,
			
		getPos: func()
		begin
			if trk then
			begin
				if trk:isConnected() then
				begin
					if not Visible(trk) then
						trk:Show();
					local pos;
					pos := trk:getPositionStrings();
					if pos = nil and nTrys < maxTrys then
					begin
						nTrys := nTrys + 1;
						AddDelayedCall(func() self:getPos(), nil, 2000);
					end
					else begin
						local tim := trk:getUTCTime();
						local dat := trk:getDatum();
						local inf := trk:getTrackerType();
						local svs := trk:getSVs();
						local obs := trk:getObsData();
						local raw := trk:getRawMeasurement();
						if Visible(trk) then
							trk:Hide();
						nTrys := 0;
						local msg;
						if pos then
						begin
							msg := "Position:";
							if pos.zone then
								msg := msg && pos.zone;
							msg := msg && pos.x && pos.y && pos.z & "\n";
							if tim then
								msg := msg & "Timestamp:" && NumberStr(tim.day) & "/" 
										   & NumberStr(tim.month) & "/" 
										   & NumberStr(tim.year)
										  && NumberStr(tim.hour) & ":" 
										   & NumberStr(tim.minute) & ":" 
										   & NumberStr(tim.second) & "\n";
							if dat then
							begin
								msg := msg & "Datum:";
								if dat.index >= kDatumWGS84 and dat.index <= kDatumOSGB then
									msg := msg && kDatumList[dat.index];
								msg := msg & "\n";
							end;
							if obs then
							begin
								if svs then
								begin
									msg := msg & "SVs: (" & NumberStr(obs.nsvs) & ") ";
									for i := 0 to obs.nsvs-1 do
									begin
										if i > 0 then
											msg := msg & ", ";
										msg := msg & NumberStr(svs[i].prn);
									end;
									msg := msg & "\n";
								end;
								msg := msg & "Mode: ";
								if obs.mode then
									msg := msg & obs.mode;
								if obs.diff then
									msg := msg & ", Diff:" && obs.diff;
								if obs.pdop > 0.0 then
									msg := msg & ", PDOP:" && FormattedNumberStr(obs.pdop,"%2.1f");
								if obs.hdop > 0.0 then
									msg := msg & ", HDOP:" && FormattedNumberStr(obs.hdop,"%2.1f");
								msg := msg & "\n";
							end;
							if inf then
								msg := msg & "Sensor:" && inf.sensorName & "\n";
							if raw then
							begin
								if raw.status = kDataAvailable then
								begin
									msg := msg & "Raw data:\n";
									for i := 0 to raw.nsvs - 1 do
									begin
										local r := raw.sv[i];
										if r.prn then
											msg := msg & "SV:" && NumberStr(r.prn);
										if r.snr exists then
											if r.snr then
												msg := msg & " SS:" && FormattedNumberStr(r.snr,"%2.1f");
										if r.codePhase exists then
											if r.codePhase then
												msg := msg & " CP:" && FormattedNumberStr(r.codePhase,"%12.2f");
										if r.doppler exists then
											if r.doppler then
												msg := msg & " Dp:" && FormattedNumberStr(r.doppler,"%12.2f");
										if r.pseudoRange exists then
											if r.pseudoRange then
												msg := msg & " PR:" && FormattedNumberStr(r.pseudoRange,"%12.2f");
										if r.carrierPhase exists then
											if r.carrierPhase then
												msg := msg & " ICP:" && FormattedNumberStr(r.carrierPhase,"%12.2f");
										if r.t then
											msg := msg & " T:" && FormattedNumberStr(r.t,"%8.2f");
										msg := msg & "\n";
									end;
								end;
							end;
						end else
							msg := "No location info\n";
							
						msg := msg & "\n";
						InsertItemsAtCaret({insertItems: {text: msg, styles: 9218,}});
					end;
					trk:Disconnect();
				end
				else
				begin
					:Notify(kNotifyAlert, "GPS Button", "GPS tracker connection failed.");
				end;
			end;			
		end,
		
		buttonClickScript: func()
		begin
			// we ought to be able to insert a new paragraph into an empty note, 
			// but for now we insist that user places the caret first.
			//
			if GetCaretInfo() = nil then
			begin
				:Notify(kNotifyAlert, "GPS Button", 
						"Click in note to place caret at required insertion point, then press GPS button again.");
				return;
			end;
			local trkman := GetRoot().('|TrackMan:UKC_MCFE|);
			if trkman = nil then
			begin
				:Notify(kNotifyAlert, "TrackerManager missing!", 
					"Make sure TrackerManager is installed.");
			end
			else if trkman.currentGPSSym = nil then
			begin
				:Notify(kNotifyAlert, "No default GPS tracker!", 
			   		"Use TrackerManager to set the default GPS Tracker.");
			end
			else begin
				trk := GetRoot().(trkman.currentGPSSym);
				if trk = nil then
				begin
					:Notify(kNotifyAlert, "Default GPS tracker is missing!", 
					    "Either use TrackerManager to set another default GPS Tracker, or install the required Tracker.");
				end
				else begin
					if trk.viewCObject = nil then
						if trk:Open() = nil then
							return;
					trk:EnableRawData(true);
					if trk:isConnected() then
						:getPos();
					else begin
						trk:Connect();
						AddDelayedCall(func() self:getPos(), nil, 3000);
					end;
				end;
			end;
		end,
	});
end;

RemoveScript := func(partFrame)
begin
	// remove the auxiliary GPS button from Notes
	UnRegAuxButton(kAuxGPSSymbol);
end;
