]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/KLN89/kln89_page_fpl.cxx
- fix unzoomed tapes (TODO: restore tick length)
[flightgear.git] / src / Instrumentation / KLN89 / kln89_page_fpl.cxx
1 // kln89_page_*.[ch]xx - this file is one of the "pages" that
2 //                       are used in the KLN89 GPS unit simulation. 
3 //
4 // Written by David Luff, started 2005.
5 //
6 // Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
7 //
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as
10 // published by the Free Software Foundation; either version 2 of the
11 // License, or (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 // General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 //
22 // $Id$
23
24 #ifdef HAVE_CONFIG_H
25 #  include "config.h"
26 #endif
27
28 #include "kln89_page_fpl.hxx"
29 #include <algorithm>
30
31 using namespace std;
32
33 KLN89FplPage::KLN89FplPage(KLN89* parent)
34 : KLN89Page(parent) {
35         _nSubPages = 26;
36         _subPage = 0;
37         _name = "FPL";
38         _fpMode = 0;
39         _actFpMode = 0;
40         _wLinePos = 0;
41         _bEntWp = false;
42         _bEntExp = false;
43         _entWp = NULL;
44         _fplPos = 0;
45         _resetFplPos0 = true;
46         _delFP = false;
47         _delWp = false;
48         _delAppr = false;
49         _changeAppr = false;
50         _fp0SelWpId = "";
51 }
52
53 KLN89FplPage::~KLN89FplPage() {
54 }
55
56 void KLN89FplPage::Update(double dt) {
57         Calc();
58         
59         // NOTE - we need to draw the active leg arrow outside of this block to avoid the _delFP check.
60         // TODO - we really ought to merge the page 0 and other pages drawing code with a couple of lines of extra logic.
61         if(_subPage == 0 && !_delFP) {  // Note that in the _delFP case, the active flightplan gets a header, and hence the same geometry as the other fps, so we draw it there.
62                 // active FlightPlan
63                 // NOTE THAT FOR THE ACTIVE FLIGHT PLAN, TOP POSITION IS STILL 4 in the underline position scheme, to make 
64                 // copy and paste easier!!!!
65
66                 // ---------------------------------- Copy the active FlightPlan and insert approach header and fence if required ---------------
67                 // For synatical convienience
68                 //vector<GPSWaypoint*> waylist = _kln89->_flightPlans[_subPage]->waypoints;
69                 // Copy every waypoint for now.
70         // This is inefficient, but allows us to insert dummy waypoints to represent the header and fence 
71                 // in our *local copy* of the flightplan, if an approach is loaded.  There must be a better way to do this!!!!
72                 //cout << "AA" << endl;
73                 vector<GPSWaypoint> waylist;
74                 for(unsigned int i=0; i<_kln89->_flightPlans[_subPage]->waypoints.size(); ++i) {
75                         waylist.push_back(*_kln89->_flightPlans[_subPage]->waypoints[i]);
76                 }
77                 //cout << "BB" << endl;
78                 _hdrPos = -1;
79                 _fencePos = -1;
80                 if(_kln89->_approachLoaded) {
81                         GPSWaypoint wp;
82                         wp.id = "HHHH";
83                         wp.type = GPS_WP_VIRT;
84                         wp.appType = GPS_HDR;
85                         //cout << "CC" << endl;
86                         for(unsigned int i=0; i<waylist.size(); ++i) {
87                                 // Insert the hdr immediately before the IAF
88                                 if(waylist[i].appType == GPS_IAF) {
89                                         waylist.insert(waylist.begin()+i, wp);
90                                         // Need to insert empty string into the params to keep them in sync
91                                         _params.insert(_params.begin()+i-1, "");
92                                         _hdrPos = i;
93                                         break;
94                                 }
95                         }
96                         //cout << "DD" << endl;
97                         wp.id = "FFFF";
98                         wp.type = GPS_WP_VIRT;
99                         wp.appType = GPS_FENCE;
100                         for(unsigned int i=0; i<waylist.size(); ++i) {
101                                 // Insert the fence between the MAF and the MAP
102                                 if(waylist[i].appType == GPS_MAHP) {
103                                         waylist.insert(waylist.begin()+i, wp);
104                                         // Need to insert empty string into the params to keep them in sync
105                                         _params.insert(_params.begin()+i-1, "");
106                                         _fencePos = i;
107                                         break;
108                                 }
109                         }
110                 }
111                 /*
112                 // Now make up a vector of waypoint numbers, since they aren't aligned with list position anymore
113                 int num = 0;
114                 vector<int> numlist;
115                 numlist.clear();
116                 for(unsigned int i=0; i<waylist.size(); ++i) {
117                         if(waylist[i].appType != GPS_HDR && waylist[i].appType != GPS_FENCE) {
118                                 numlist.push_back(num);
119                                 num++;
120                         } else {
121                                 numlist.push_back(-1);
122                         }
123                 }
124                 */
125                 int hfcount = 0;
126                 for(unsigned int i=0; i<waylist.size(); ++i) {
127                         //cout << i + 1 - hfcount << ":  ID= " << waylist[i].id;
128                         if(waylist[i].appType == GPS_HDR) {
129                                 hfcount++;
130                                 //cout << " HDR!";
131                         }
132                         if(waylist[i].appType == GPS_FENCE) {
133                                 hfcount++;
134                                 //cout << " FENCE!";
135                         }
136                         //cout << '\n';
137                 }
138                 //----------------------------------------- end active FP copy ------------------------------------------------
139                 
140                 // Recalculate which waypoint is displayed at the top of the list if required (generally if this page has lost focus).
141                 int idx = _parent->GetActiveWaypointIndex();
142                 if(_resetFplPos0) {
143                         if(waylist.size() <= 1) {
144                                 _fplPos = 0;
145                         } else if(waylist.size() <= 4) {
146                                 _fplPos = 1;
147                         } else {
148                                 // Make the active waypoint the second WP displayed
149                                 _fplPos = idx;
150                                 if(_fplPos != 0) {
151                                         _fplPos--;
152                                 }
153                         }
154                         //cout << "HeaderPos = " << _hdrPos << ", fencePos = " << _fencePos << ", _fplPos = " << _fplPos << ", active waypoint index = " << _parent->GetActiveWaypointIndex() << '\n';
155                         if(_hdrPos >= 0 && idx >= _hdrPos) {
156                                 _fplPos++;
157                                 if(_fencePos >= 0 && (idx + 1) >= _fencePos) {
158                                         _fplPos++;
159                                 }
160                         }
161                         _resetFplPos0 = false;
162                 }
163                 
164                 // Increment the active waypoint position if required due hdr and fence here not above so it gets called every frame
165                 if(_hdrPos >= 0 && idx >= _hdrPos) {
166                         idx++;
167                         if(_fencePos >= 0 && idx >= _fencePos) {
168                                 idx++;
169                         }
170                 }
171                 
172                 // Draw the leg arrow etc
173                 int diff = idx - (int)_fplPos;
174                 int drawPos = -1;
175                 if(idx < 0) {
176                         // No active waypoint
177                 } else if(diff < 0) {
178                         // Off screen to the top
179                 } else if(diff > 2) {
180                         // TODO !
181                 } else {
182                         drawPos = diff;
183                 }
184                 // Only the head is blinked during waypoint alerting
185                 if(!(_kln89->_waypointAlert && _kln89->_blink)) {
186                         _kln89->DrawSpecialChar(4, 2, 0, 3-drawPos);
187                 }
188                 // If the active waypoint is immediately after an approach header then we need to do an extra-long tail leg
189                 if(_hdrPos >= 0 && idx == _hdrPos + 1) {
190                         if(drawPos > 0 && !_kln89->_dto) _kln89->DrawLongLegTail(3-drawPos);
191                 } else {
192                         if(drawPos > 0 && !_kln89->_dto) _kln89->DrawLegTail(3-drawPos);
193                 }
194                 
195                 //cout << "Top pos is " << _fplPos0 << ' ';
196                 
197                 if(_kln89->_mode == KLN89_MODE_CRSR) {
198                         if(_uLinePos == 3) {
199                                 _kln89->Underline(2, 13, 3, 3);
200                         } else if(_uLinePos >= 4) {
201                                 if(_bEntWp) {
202                                         if(_wLinePos == 0) {
203                                                 _kln89->Underline(2, 5, 3 - (_uLinePos - 4), 4);
204                                         } else if(_wLinePos == 4) {
205                                                 _kln89->Underline(2, 4, 3 - (_uLinePos - 4), 4);
206                                         } else {
207                                                 _kln89->Underline(2, 4, 3 - (_uLinePos - 4), _wLinePos);
208                                                 _kln89->Underline(2, 5 + _wLinePos, 3 - (_uLinePos - 4), 4 - _wLinePos);
209                                         }
210                                         if(!_kln89->_blink) {
211                                                 //_kln89->DrawText(_entWp->id, 2, 4, 2 - (_uLinePos - 4), false, _wLinePos);
212                                                 _kln89->DrawEnt();
213                                         }
214                                 } else {
215                                         _kln89->Underline(2, 4, 3 - (_uLinePos - 4), 5);
216                                 }
217                         }
218                 }
219                 // ----------------------------------
220                 //cout << "A1" << endl;
221                         
222                 // Sanity check the top position - remember that we can have an extra blank one at the bottom even if CRSR is off if crsr is switched on then off
223                 if((int)_fplPos > ((int)waylist.size()) - 3) _fplPos = (((int)waylist.size()) - 3 < 0 ? 0 : waylist.size() - 3);
224                 unsigned int last_pos;
225                 if(waylist.empty()) {
226                         last_pos = 0;
227                 } else {
228                         last_pos = ((int)_fplPos == ((int)waylist.size()) - 3 ? waylist.size() : waylist.size() - 1);
229                 }
230                 //cout << "Initialising last_pos, last_pos = " << last_pos << '\n';
231                 //cout << "B1" << endl;
232                 if(waylist.size() < 4) last_pos = waylist.size();
233                 
234                 // Don't draw the cyclic field header if the top waypoint is the approach header
235                 // Not sure if this also applies to the fence - don't think so but TODO - check!
236                 if(waylist[_fplPos].appType != GPS_HDR) {
237                         _kln89->DrawChar('>', 2, 12, 3);
238                         if(!(_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == 3 && _kln89->_blink)) {
239                                 DrawFpMode(3);
240                         }
241                 }
242                 
243                 // ACTIVE
244                 for(unsigned int i=0; i<4; ++i) {
245                         //cout << "F1... " << i << endl;
246                         // Don't draw the waypoint number for the header or fence
247                         //cout << "_fplPos0 = " << _fplPos0 << ", waylist size is " << waylist.size() << '\n';
248                         //cout << "F1, i = " << i << ", way id = " << waylist[_fplPos0+i].id << '\n'; 
249                         if((waylist[_fplPos+i].appType == GPS_HDR || waylist[_fplPos+i].appType == GPS_FENCE) 
250                             && i != 3) {        // By definition, the header and fence lines can't be displayed on the last line hence the unconditional !i==3 is safe.
251                                 // no-op
252                                 //cout << "NOOP\n";
253                         } else {
254                                 int n = (i < 3 ? _fplPos + i + 1 : last_pos + 1);
255                                 if(_kln89->_approachLoaded) {
256                                         if(n > _hdrPos) --n;
257                                         if(n > _fencePos) --n;
258                                 }
259                                 string s = GPSitoa(n);
260                                 // Don't draw the colon for waypoints that are part of the published approach
261                                 if(waylist[_fplPos+i].appType == GPS_APP_NONE) {
262                                         s += ':';
263                                 }
264                                 if(!(_delWp && _uLinePos == i+4)) _kln89->DrawText(s, 2, 4 - (s[s.size()-1] == ':' ? s.size() : s.size()+1), 3 - i);
265                         }
266                         //cout << "F1 done!\n";
267                         bool drawID = true;
268                         if(_delWp && _uLinePos == i+4) {
269                                 if(!_kln89->_blink) {
270                                         _kln89->DrawText("Del", 2, 0, 3-i);
271                                         _kln89->DrawChar('?', 2, 10, 3-i);
272                                         _kln89->Underline(2, 0, 3-i, 11);
273                                         _kln89->DrawEnt();
274                                 }
275                         } else if(_kln89->_mode == KLN89_MODE_CRSR && _bEntWp && _uLinePos == i+4) {
276                                 if(!_kln89->_blink) {
277                                         if(_wLinePos >= _entWp->id.size()) {
278                                                 _kln89->DrawText(_entWp->id, 2, 4, 3-i);
279                                                 _kln89->DrawChar(' ', 2, 4+_wLinePos, 3-i, false, true);
280                                         } else {
281                                                 _kln89->DrawText(_entWp->id.substr(0, _wLinePos), 2, 4, 3-i);
282                                                 _kln89->DrawChar(_entWp->id[_wLinePos], 2, 4+_wLinePos, 3-i, false, true);
283                                                 _kln89->DrawText(_entWp->id.substr(_wLinePos+1, _entWp->id.size()-_wLinePos-1), 2, 5+_wLinePos, 3-i);
284                                         }
285                                 }
286                                 drawID = false;
287                         }
288                         //cout << "F2" << endl;
289                         if(drawID) {
290                                 //cout << "F2a" << endl;
291                                 if(i == 3 || _fplPos + i == waylist.size()) {
292                                         //cout << "F2a1" << endl;
293                                         //cout << "_uLinePos = " << _uLinePos << ", i = " << i << ", waylist.size() = " << waylist.size() << endl;
294                                         if(!(_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == (i + 4) && _kln89->_blink)) {
295                                                 //cout << "Drawing underline..." << endl;
296                                                 _kln89->DrawText(last_pos < waylist.size() ? waylist[last_pos].GetAprId() : "_____", 2, 4, 3-i);
297                                                 //cout << "2" << endl;
298                                         }
299                                         //cout << "3" << endl;
300                                         //cout << "last_pos = " << last_pos << endl;
301                                         if(last_pos > 0 && last_pos < waylist.size() && i > 0) {
302                                                 //cout << "4" << endl; 
303                                                 // Draw the param
304                                                 if(_actFpMode == 0) {
305                                                         string s = _params[last_pos - 1];
306                                                         _kln89->DrawText(s, 2, 16-s.size(), 3-i);
307                                                 } else if(_actFpMode == 3) {
308                                                         string s = _params[last_pos - 1];
309                                                         _kln89->DrawText(s, 2, 15-s.size(), 3-i);
310                                                         _kln89->DrawSpecialChar(0, 2, 15, 3-i);
311                                                 }
312                                                 //cout << "5" << endl;
313                                         }
314                                         //cout << "6" << endl;
315                                         break;
316                                 } else {
317                                         //cout << "F2a2" << endl;
318                                         if(!(_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == (i + 4) && _kln89->_blink)) {
319                                                 if(waylist[_fplPos+i].appType == GPS_HDR) {
320                                                         if(_delAppr) {
321                                                                 _kln89->DrawText("DELETE APPR?", 2, 1, 3-i);
322                                                         } else if(_changeAppr) {
323                                                                 _kln89->DrawText("CHANGE APPR?", 2, 1, 3-i);
324                                                         } else {
325                                                                 _kln89->DrawText(_kln89->_approachAbbrev, 2, 1, 3-i);
326                                                                 _kln89->DrawText(_kln89->_approachRwyStr, 2, 7, 3-i);
327                                                                 _kln89->DrawText(_kln89->_approachID, 2, 12, 3-i);
328                                                         }
329                                                 } else if(waylist[_fplPos+i].appType == GPS_FENCE) {
330                                                         _kln89->DrawText("*NO WPT SEQ", 2, 0, 3-i);
331                                                 } else {
332                                                         _kln89->DrawText(waylist[_fplPos+i].GetAprId(), 2, 4, 3-i);
333                                                 }
334                                         }
335                                 }
336                                 //cout << "F2b" << endl;
337                                 if(i > 0) {
338                                         // Draw the param
339                                         //cout << "i > 0 param draw...\n";
340                                         if(_actFpMode == 0) {
341                                                 string s = _params[_fplPos + i - 1];
342                                                 _kln89->DrawText(s, 2, 16-s.size(), 3-i);
343                                         } else if(_actFpMode == 3) {
344                                                 string s = _params[_fplPos + i - 1];
345                                                 _kln89->DrawText(s, 2, 15-s.size(), 3-i);
346                                                 _kln89->DrawSpecialChar(0, 2, 15, 3-i);
347                                         }
348                                 }
349                                 //cout << "F2c" << endl;
350                         }
351                         //cout << "F3" << endl;
352                 }
353                 //cout << "GGGGGG" << endl;
354         } else {  // Not active flightplan
355                 //cout << "Top pos is " << _fplPos << ' ';
356                 // For synatical convienience
357                 //int nWp = (_subPage == 0 && !_delFP ? 4 : 3); // number of waypoints to display
358                 vector<GPSWaypoint*> waylist = _kln89->_flightPlans[_subPage]->waypoints;
359                 if(waylist.empty()) {
360                         if(!(_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == 1 && _kln89->_blink)) {
361                                 _kln89->DrawText(_delFP ? "Delete FPL?" : "Copy FPL 0?", 2, 0, 3);
362                         }
363                 } else {
364                         if(!(_kln89->_mode == KLN89_MODE_CRSR && (_uLinePos == 1 || _uLinePos == 2) && _kln89->_blink)) {
365                                 _kln89->DrawText(_delFP ? "Delete FPL?" : "Use?", 2, 0, 3);
366                         }
367                         if(!(_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == 2 && _kln89->_blink)) {
368                                 if(!_delFP) _kln89->DrawText("Inverted?", 2, 5, 3);
369                         }
370                 }
371                 
372                 // ----------------------------------
373                 if(_kln89->_mode == KLN89_MODE_CRSR) {
374                         if(_uLinePos == 1) {
375                                 if(!_kln89->_blink) {
376                                         _kln89->Underline(2, 0, 3, (waylist.empty() || _delFP ? 11 : 4));       // This underline is blinked
377                                         _kln89->DrawEnt();
378                                 }
379                         } else if(_uLinePos == 2) {
380                                 // assert(!waylist.empty());
381                                 if(!_kln89->_blink) {
382                                         _kln89->Underline(2, 0, 3, 14); // This underline is blinked
383                                         _kln89->DrawEnt();
384                                 }
385                         } else if(_uLinePos == 3) {
386                                 _kln89->Underline(2, 13, 2, 3);
387                         } else if(_uLinePos >= 4) {
388                                 if(_bEntWp) {
389                                         if(_wLinePos == 0) {
390                                                 _kln89->Underline(2, 5, 2 - (_uLinePos - 4), 4);
391                                         } else if(_wLinePos == 4) {
392                                                 _kln89->Underline(2, 4, 2 - (_uLinePos - 4), 4);
393                                         } else {
394                                                 _kln89->Underline(2, 4, 2 - (_uLinePos - 4), _wLinePos);
395                                                 _kln89->Underline(2, 5 + _wLinePos, 2 - (_uLinePos - 4), 4 - _wLinePos);
396                                         }
397                                         if(!_kln89->_blink) {
398                                                 //_kln89->DrawText(_entWp->id, 2, 4, 2 - (_uLinePos - 4), false, _wLinePos);
399                                                 _kln89->DrawEnt();
400                                         }
401                                 } else {
402                                         if(!_delWp) _kln89->Underline(2, 4, 2 - (_uLinePos - 4), 5);
403                                 }
404                         }
405                 }
406                 // ----------------------------------
407                         
408                 _kln89->DrawChar('>', 2, 12, 2);
409                 if(!(_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == 3 && _kln89->_blink)) DrawFpMode(2);
410                 // Sanity check the top position - remember that we can have an extra blank one at the bottom even if CRSR is off if crsr is switched on then off
411                 if((int)_fplPos > ((int)waylist.size()) - 2) _fplPos = (((int)waylist.size()) - 2 < 0 ? 0 : waylist.size() - 2);
412                 unsigned int last_pos;
413                 if(waylist.empty()) {
414                         last_pos = 0;
415                 } else {
416                         last_pos = ((int)_fplPos == ((int)waylist.size()) - 2 ? waylist.size() : waylist.size() - 1);
417                 }
418                 if(waylist.size() < 3) last_pos = waylist.size();
419                 for(unsigned int i=0; i<3; ++i) {
420                         string s = GPSitoa(i < 2 ? _fplPos + i + 1 : last_pos + 1);
421                         s += ':';
422                         if(!(_delWp && _uLinePos == i+4)) _kln89->DrawText(s, 2, 4 - s.size(), 2 - i);
423                         bool drawID = true;
424                         if(_delWp && _uLinePos == i+4) {
425                                 if(!_kln89->_blink) {
426                                         _kln89->DrawText("Del", 2, 0, 2-i);
427                                         _kln89->DrawChar('?', 2, 10, 2-i);
428                                         _kln89->Underline(2, 0, 2-i, 11);
429                                         _kln89->DrawEnt();
430                                 }
431                         } else if(_kln89->_mode == KLN89_MODE_CRSR && _bEntWp && _uLinePos == i+4) {
432                                 if(!_kln89->_blink) {
433                                         if(_wLinePos >= _entWp->id.size()) {
434                                                 _kln89->DrawText(_entWp->id, 2, 4, 2-i);
435                                                 _kln89->DrawChar(' ', 2, 4+_wLinePos, 2-i, false, true);
436                                         } else {
437                                                 _kln89->DrawText(_entWp->id.substr(0, _wLinePos), 2, 4, 2-i);
438                                                 _kln89->DrawChar(_entWp->id[_wLinePos], 2, 4+_wLinePos, 2-i, false, true);
439                                                 _kln89->DrawText(_entWp->id.substr(_wLinePos+1, _entWp->id.size()-_wLinePos-1), 2, 5+_wLinePos, 2-i);
440                                         }
441                                 }
442                                 drawID = false;
443                         }
444                         if(drawID) {
445                                 if(i == 2 || _fplPos + i == waylist.size()) {
446                                         if(!(_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == (i + 4) && _kln89->_blink)) {
447                                                 _kln89->DrawText(last_pos < waylist.size() ? waylist[last_pos]->id : "_____", 2, 4, 2-i);
448                                         }
449                                         if(last_pos > 0 && last_pos < waylist.size() && i > 0) {
450                                                 // Draw the param
451                                                 if(_fpMode == 0) {
452                                                         string s = _params[last_pos - 1];
453                                                         _kln89->DrawText(s, 2, 16-s.size(), 2-i);
454                                                 }
455                                         }
456                                         break;
457                                 } else {
458                                         if(!(_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == (i + 4) && _kln89->_blink)) {
459                                                 _kln89->DrawText(waylist[_fplPos+i]->id, 2, 4, 2-i);
460                                         }
461                                         if(i > 0) {
462                                                 // Draw the param
463                                                 if(_fpMode == 0) {
464                                                         string s = _params[_fplPos + i - 1];
465                                                         _kln89->DrawText(s, 2, 16-s.size(), 2-i);
466                                                 }
467                                         }
468                                 }
469                         }
470                 }
471         }
472         
473         KLN89Page::Update(dt);
474 }
475
476 void KLN89FplPage::DrawFpMode(int ypos) {
477         string s = "Dis";
478         if(0 == _subPage) {
479                 if(_actFpMode == 1) {
480                         s = "ETE";
481                 } else if(_actFpMode == 2) {
482                         s = "UTC";      // TODO - alter depending on chosen timezone
483                 } else if(_actFpMode == 3) {
484                         s = (_kln89->_obsMode ? "OBS" : "Dtk");
485                 }
486         } else {
487                 if(_fpMode == 1) {
488                         s = "Dtk";
489                 }
490         }
491         _kln89->DrawText(s, 2, 13, ypos);
492 }
493
494 // Bit of an ipsy-dipsy function this one - calc the required parameters for the displayed flightplan.
495 void KLN89FplPage::Calc() {
496         _params.clear();
497         GPSFlightPlan* fp = _kln89->_flightPlans[_subPage];
498         vector<GPSWaypoint*> wv = fp->waypoints;
499         if(0 == _subPage) {
500                 // Active FP - parameters are only displayed for the active waypoint onwards for the active plan,
501                 // and distance is cumulative from the user position.
502                 if(0 == _actFpMode) {
503                         // Dis
504                         double cum_tot = 0.0;
505                         if(wv.size() > 0) {
506                                 //cum_tot += _kln89->GetHorizontalSeparation(_kln89->_gpsLat, _kln89->_gpsLon, wv[0]->lat, wv[0]->lon) * SG_METER_TO_NM;
507                                 cum_tot += _kln89->GetGreatCircleDistance(_kln89->_gpsLat, _kln89->_gpsLon, wv[0]->lat, wv[0]->lon);
508                         }
509                         for(unsigned int i=1; i<wv.size(); ++i) {
510                                 //cum_tot += _kln89->GetHorizontalSeparation(wv[i-1]->lat, wv[i-1]->lon, wv[i]->lat, wv[i]->lon) * SG_METER_TO_NM;      // TODO - add units switch!
511                                 cum_tot += _kln89->GetGreatCircleDistance(wv[i-1]->lat, wv[i-1]->lon, wv[i]->lat, wv[i]->lon);  // TODO - add units switch!
512                                 int n = (int)(cum_tot + 0.5);
513                                 _params.push_back(GPSitoa(n));
514                         }
515                 } else if(1 == _actFpMode) {
516                 } else if(2 == _actFpMode) {
517                 } else {
518                         // Dtk
519                         for(int i=1; i<wv.size(); ++i) {
520                                 double dtk = _kln89->GetMagHeadingFromTo(wv[i-1]->lat, wv[i-1]->lon, wv[i]->lat, wv[i]->lon);
521                                 int n = (int)(dtk + 0.5);
522                                 _params.push_back(GPSitoa(n));
523                         }
524                         
525                 }
526         } else {
527                 // other FPs
528                 if(0 == _fpMode) {
529                         double cum_tot = 0.0;
530                         for(int i=1; i<wv.size(); ++i) {
531                                 //cum_tot += _kln89->GetHorizontalSeparation(wv[i-1]->lat, wv[i-1]->lon, wv[i]->lat, wv[i]->lon) * SG_METER_TO_NM;      // TODO - add units switch!
532                                 cum_tot += _kln89->GetGreatCircleDistance(wv[i-1]->lat, wv[i-1]->lon, wv[i]->lat, wv[i]->lon);  // TODO - add units switch!
533                                 int n = (int)(cum_tot + 0.5);
534                                 _params.push_back(GPSitoa(n));
535                         }
536                 } else {
537                 }
538         }
539 }
540
541 void KLN89FplPage::CrsrPressed() {
542         if(_delFP) {
543                 _delFP = false;
544                 _kln89->_mode = KLN89_MODE_DISP;
545                 return;
546         }
547
548         _wLinePos = 0;
549         if(_kln89->_mode == KLN89_MODE_DISP) {
550                 _fp0SelWpId.clear();
551                 if(_bEntWp) {
552                         for(unsigned int i = 0; i < _kln89->_flightPlans[_subPage]->waypoints.size(); ++i) {
553                                 if(_kln89->_flightPlans[_subPage]->waypoints[i] == _entWp) {
554                                         _kln89->_flightPlans[_subPage]->waypoints.erase(_kln89->_flightPlans[_subPage]->waypoints.begin() + i);
555                                 }
556                         }
557                         delete _entWp;
558                         _entWp = NULL;
559                         _bEntWp = false;
560                         _entWpStr.clear();
561                 }
562         } else {
563                 if(_kln89->_obsMode) {
564                         _uLinePos = 0;
565                 } else {
566                         if(_kln89->_flightPlans[_subPage]->IsEmpty()) {
567                                 _uLinePos = 4;
568                         } else {
569                                 _uLinePos = (_subPage == 0 ? 3 : 1);
570                         }
571                 }
572         }
573 }
574
575 void KLN89FplPage::ClrPressed() {
576         if(_delFP) {
577                 _kln89->_mode = KLN89_MODE_DISP;
578                 _delFP = false;
579         } else if(_delAppr) {
580                 _kln89->_mode = KLN89_MODE_DISP;
581                 _delAppr = false;
582         } else {
583                 if(KLN89_MODE_CRSR == _kln89->_mode) {
584                         // TODO - see if we need to delete a waypoint
585                         if(_uLinePos >= 4) {
586                                 if(_delWp) {
587                                         _kln89->_mode = KLN89_MODE_DISP;
588                                         _delWp = false;
589                                 } else {
590                                         // First check that we're not trying to delete an approach waypoint.  Note that we can delete the approach by deleting the header though.
591                                         // Check for approach waypoints or header/fences in flightplan 0
592                                         int n = _fplPos + _uLinePos - 4;
593                                         bool hdrPos = false;
594                                         bool fencePos = false;
595                                         //cout << "_fplPos = " << _fplPos << ", _uLinePos = " << _uLinePos << ", n = " << n << ", _hdrPos = " << _hdrPos << ", _fencePos = " << _fencePos << '\n';
596                                         if(n == _hdrPos) {
597                                                 //cout << "HEADER POS\n";
598                                                 hdrPos = true;
599                                         }
600                                         if(n == _fencePos) {
601                                                 //cout << "FENCE POS\n";
602                                                 fencePos = true;
603                                         }
604                                         if(_hdrPos >= 0 && n > _hdrPos) --n;
605                                         if(_fencePos >= 0 && n >= _fencePos) --n;       // This one needs to be >= since n is already decremented by 1 in the line above!
606                                         //cout << "New n = " << n << '\n';
607                                         if(hdrPos) {
608                                                 //cout << "HDRP\n";
609                                                 _delAppr = true;
610                                         } else if(fencePos) {
611                                                 //cout << "FENP\n";
612                                                 // no-op
613                                         } else if(n >= _kln89->_flightPlans[_subPage]->waypoints.size()) {
614                                                 // no-op - off the end of the list on the entry field
615                                         } else if(_kln89->_flightPlans[_subPage]->waypoints[n]->appType == GPS_APP_NONE) {
616                                                 //cout << "DELFP\n";
617                                                 _kln89->_mode = KLN89_MODE_CRSR;
618                                                 _delWp = true;
619                                         } else {
620                                                 ShowScratchpadMessage("Invald", " Del  ");
621                                         }
622                                 }
623                         } else if(_uLinePos == 3) {
624                                 if(_subPage == 0) {
625                                         _actFpMode++;
626                                         if(_actFpMode > 3) _actFpMode = 0;
627                                 } else {
628                                         _fpMode++;
629                                         if(_fpMode > 1) _fpMode = 0;
630                                 }
631                         }
632                 } else {
633                         _delFP = true;
634                         _uLinePos = 1;
635                         _kln89->_mode = KLN89_MODE_CRSR;
636                 }
637         }
638 }
639
640 void KLN89FplPage::CleanUp() {
641         // TODO - possibly need to clean up _delWp here as well, since it goes off if dto and then ent are pressed.
642         
643         _bEntWp = false;
644         for(unsigned int i = 0; i < _kln89->_flightPlans[_subPage]->waypoints.size(); ++i) {
645                 if(_kln89->_flightPlans[_subPage]->waypoints[i] == _entWp) {
646                         _kln89->_flightPlans[_subPage]->waypoints.erase(_kln89->_flightPlans[_subPage]->waypoints.begin() + i);
647                 }
648         }
649         delete _entWp;
650         _entWp = NULL;
651         _entWpStr.clear();
652         KLN89Page::CleanUp();
653 }
654
655 void KLN89FplPage::LooseFocus() {
656         _fplPos = 0;
657         _resetFplPos0 = true;
658         _wLinePos = 0;
659         _uLinePos = 0;
660         _fp0SelWpId.clear();
661         _scratchpadMsg = false;
662 }
663
664 void KLN89FplPage::EntPressed() {
665         if(_delFP) {
666                 _parent->ClearFlightPlan(_subPage);
667                 CrsrPressed();
668         } else if(_delWp) {
669                 int pos = _uLinePos - 4 + _fplPos;
670                 // Sanity check - the calculated wp position should never be off the end of the waypoint list.
671                 if(pos > _kln89->_flightPlans[_subPage]->waypoints.size() - 1) {
672                         cout << "ERROR - _uLinePos too big in KLN89FplPage::EntPressed!\n";
673                         return;
674                 }
675                 _kln89->_flightPlans[_subPage]->waypoints.erase(_kln89->_flightPlans[_subPage]->waypoints.begin() + pos);
676                 _delWp = false;
677                 // Do we need to re-calc _fplPos here?
678         } else if(_bEntExp) {
679                 _bEntWp = false;
680                 _bEntExp = false;
681                 _entWp = NULL;  // DON'T delete it! - it's been pushed onto the waypoint list at this point.
682                 _entWpStr.clear();
683                 _kln89->_cleanUpPage = -1;
684                 _wLinePos = 0;
685                 // TODO - in actual fact the previously underlined waypoint stays in the same position and underlined
686                 // in some or possibly all circumstances - need to check this out and match it, but not too important
687                 // for now.
688         } else if(_bEntWp) {
689                 if(_entWp != NULL) {
690                         // TODO - should be able to get rid of this switch I think and use the enum values.
691                         switch(_entWp->type) {
692                         case GPS_WP_APT:
693                                 _kln89->_activePage = _kln89->_pages[0];
694                                 _kln89->_curPage = 0;
695                                 ((KLN89Page*)_kln89->_pages[0])->SetEntInvert(true);
696                                 break;
697                         case GPS_WP_VOR:
698                                 _kln89->_activePage = _kln89->_pages[1];
699                                 _kln89->_curPage = 1;
700                                 ((KLN89Page*)_kln89->_pages[1])->SetEntInvert(true);
701                                 break;
702                         case GPS_WP_NDB:
703                                 _kln89->_activePage = _kln89->_pages[2];
704                                 _kln89->_curPage = 2;
705                                 ((KLN89Page*)_kln89->_pages[2])->SetEntInvert(true);
706                                 break;
707                         case GPS_WP_INT:
708                                 _kln89->_activePage = _kln89->_pages[3];
709                                 _kln89->_curPage = 3;
710                                 ((KLN89Page*)_kln89->_pages[3])->SetEntInvert(true);
711                                 break;
712                         case GPS_WP_USR:
713                                 _kln89->_activePage = _kln89->_pages[4];
714                                 _kln89->_curPage = 4;
715                                 ((KLN89Page*)_kln89->_pages[4])->SetEntInvert(true);
716                                 break;
717                         default:
718                                 cout << "Error - unknown waypoint type found in KLN89::FplPage::EntPressed()\n";
719                         }
720                         _kln89->_activePage->SetId(_entWp->id);
721                         _kln89->_entJump = 7;
722                         _kln89->_cleanUpPage = 7;
723                         _kln89->_entRestoreCrsr = true;
724                         _kln89->_mode = KLN89_MODE_DISP;
725                 }
726                 _bEntExp = true;
727         } else if(_uLinePos == 1) {
728                 if(_kln89->_flightPlans[_subPage]->IsEmpty()) {
729                         // Copy fpl 0
730                         for(unsigned int i=0; i<_kln89->_flightPlans[0]->waypoints.size(); ++i) {
731                                 GPSWaypoint* wp = new GPSWaypoint;
732                                 *wp = *(_kln89->_flightPlans[0]->waypoints[i]);
733                                 _kln89->_flightPlans[_subPage]->waypoints.push_back(wp);
734                         }
735                 } else {
736                         // Use
737                         _parent->ClearFlightPlan(0);
738                         for(unsigned int i=0; i<_kln89->_flightPlans[_subPage]->waypoints.size(); ++i) {
739                                 GPSWaypoint* wp = new GPSWaypoint;
740                                 *wp = *(_kln89->_flightPlans[_subPage]->waypoints[i]);
741                                 _kln89->_flightPlans[0]->waypoints.push_back(wp);
742                         }
743                         _kln89->OrientateToActiveFlightPlan();
744                         _subPage = 0;
745                 }
746                 _parent->CrsrPressed();
747         } else if(_uLinePos == 2) {
748                 if(_kln89->_flightPlans[_subPage]->IsEmpty()) {
749                         // ERROR !!!
750                 } else {
751                         // Use Invert
752                         _parent->ClearFlightPlan(0);
753                         for(unsigned int i=0; i<_kln89->_flightPlans[_subPage]->waypoints.size(); ++i) {
754                                 GPSWaypoint* wp = new GPSWaypoint;
755                                 *wp = *(_kln89->_flightPlans[_subPage]->waypoints[i]);
756                                 // FIXME - very inefficient - use a reverse iterator on the source array and push_back instead!!!!!!!!
757                                 _kln89->_flightPlans[0]->waypoints.insert(_kln89->_flightPlans[0]->waypoints.begin(), wp);
758                         }
759                         _kln89->OrientateToActiveFlightPlan();
760                 }
761                 _parent->CrsrPressed();
762                 _subPage = 0;
763         }
764 }
765
766 void KLN89FplPage::Knob1Left1() {
767         if(_delFP) {
768                 _delFP = false;
769                 return;
770         }
771         _delWp = false;
772         _changeAppr = false;
773
774         if(_kln89->_mode == KLN89_MODE_CRSR) {
775                 if(_bEntWp) {
776                         if(_wLinePos > 0) _wLinePos--;
777                 } else {
778                         // _uLinePos with empty/not-empty plan: 1 = Copy FPL 0? / Use?, 2 = unused if empty / Invert?, 3 = >Dis/Dtk field, 4+ = Waypoint 1+
779                         if(_uLinePos == 0) {
780                                 // No-op
781                         } else if(_uLinePos == 1 || _uLinePos == 2) {
782                                 _uLinePos--;
783                         } else if(_uLinePos == 3) {
784                                 _uLinePos = 4;
785                         } else if(_uLinePos == 4) {
786                                 if(_kln89->_flightPlans[_subPage]->IsEmpty()) {
787                                         _uLinePos = (_subPage == 0 ? 0 : 1);
788                                 } else if(_fplPos == 0) {
789                                         _uLinePos = (_subPage == 0 ? 0 : 2);
790                                 } else {
791                                         _fplPos--;
792                                 }
793                         } else if(_uLinePos == 5) {
794                                 _uLinePos = 3;
795                         } else {
796                                 _uLinePos--;
797                         }
798
799                         if(_subPage == 0 && _uLinePos > 3) {
800                                 int ix = _fplPos + (_uLinePos - 4);
801                                 if(_fencePos >= 0 && ix >= _fencePos) ix--;
802                                 if(_hdrPos >= 0 && ix >= _hdrPos) ix--;
803                                 if(ix >= _kln89->_activeFP->waypoints.size()) {
804                                         _fp0SelWpId.clear();
805                                 } else {
806                                         _fp0SelWpId = _kln89->_activeFP->waypoints[ix]->id;
807                                 }
808                         } else {
809                                 _fp0SelWpId.clear();
810                                 //cout << "Not page 0, or not in waypoints, clearing id!\n";
811                         }
812                 }
813         }
814 }
815
816 void KLN89FplPage::Knob1Right1() {
817         if(_delFP) {
818                 _delFP = false;
819                 return;
820         }
821         _delWp = false;
822         _changeAppr = false;
823         
824         if(_kln89->_mode == KLN89_MODE_CRSR) {
825                 if(_bEntWp) {
826                         if(_wLinePos < 4) _wLinePos++;
827                 } else {
828                         // _uLinePos with empty/not-empty plan: 
829                         // 1 = Copy FPL 0? / Use?, 2 = unused if empty / Invert?, 3 = >Dis/Dtk field, 4+ = Waypoint 1+
830                         if(_uLinePos == 0) {
831                                 _uLinePos = (_subPage == 0 ? 4 : 1);
832                         } else if(_uLinePos == 1) {
833                                 _uLinePos = (_kln89->_flightPlans[_subPage]->IsEmpty() ? 4 : 2);
834                         } else if(_uLinePos == 2) {
835                                 _uLinePos = 4;
836                         } else if(_uLinePos == 3) {
837                                 if(!_kln89->_flightPlans[_subPage]->IsEmpty()) _uLinePos = 5;
838                         } else if(_uLinePos == 4) {
839                                 _uLinePos = 3;
840                         } else if((_subPage == 0 && _uLinePos == 6) || (_subPage > 0 && _uLinePos == 5)) {
841                                 // Urrggh - complicated!
842                                 // 3 possibilities:
843                                 // 1: We're on the entry field at the end of the list, and can't move any more.
844                                 // 2: We're on the last or second-last field, and move to the last position
845                                 // 3: We're on a field before the second-last one, and don't move, but change the list-head position
846                                 // And 4: _subPage 0 can be complicated by the presence of header/fence lines in an approach.
847                                 int hfcount = 0;
848                                 if(_subPage == 0) {
849                                         if(_hdrPos >= 0) hfcount++;
850                                         if(_fencePos >= 0) hfcount++;
851                                 }
852                                 if(_kln89->_flightPlans[_subPage]->waypoints.size() == 1 || _fplPos == _kln89->_flightPlans[_subPage]->waypoints.size() + hfcount - 1) {
853                                         // 1: Don't move
854                                 } else if(_fplPos >= _kln89->_flightPlans[_subPage]->waypoints.size() + hfcount - (_subPage == 0 ? 4 : 3)) {
855                                         _uLinePos++;
856                                 } else {
857                                         _fplPos++;
858                                 }
859                         } else if(_uLinePos == 5) {
860                                 // Must be _subPage 0
861                                 _uLinePos++;
862                         } else {
863                                 // Must be the last line - either _uLinePos 6 or 7 depending on _subPage
864                                 int thresh = (_subPage == 0 ? 3 : 2);
865                                 if(_kln89->_flightPlans[_subPage]->waypoints.size() == thresh || _fplPos == _kln89->_flightPlans[_subPage]->waypoints.size() - thresh) {
866                                         // Don't move
867                                 } else {
868                                         _fplPos++;
869                                 }
870                         }
871                         
872                         if(_subPage == 0 && _uLinePos > 3) {
873                                 int ix = _fplPos + (_uLinePos - 4);
874                                 if(_fencePos >= 0 && ix >= _fencePos) ix--;
875                                 if(_hdrPos >= 0 && ix >= _hdrPos) ix--;
876                                 if(ix >= _kln89->_activeFP->waypoints.size()) {
877                                         _fp0SelWpId.clear();
878                                 } else {
879                                         _fp0SelWpId = _kln89->_activeFP->waypoints[ix]->id;
880                                 }
881                         } else {
882                                 _fp0SelWpId.clear();
883                                 //cout << "Not page 0, or not in waypoints, clearing id!\n";
884                         }
885                 }
886         }
887 }
888
889 void KLN89FplPage::Knob2Left1() {
890         if(_delFP) {
891                 _delFP = false;
892                 return;
893         }
894         _delWp = false;
895
896         if(_kln89->_mode != KLN89_MODE_CRSR || _uLinePos == 0) {
897                 if(_kln89->_mode != KLN89_MODE_CRSR) _resetFplPos0 = true;
898                 KLN89Page::Knob2Left1();
899         } else {
900                 if(_uLinePos > 3) {
901                         // Check for approach waypoints or header/fences in flightplan 0
902                         int n = _fplPos + _uLinePos - 4;
903                         bool hdrPos = false;
904                         bool fencePos = false;
905                         bool appWp = false;
906                         //cout << "_fplPos = " << _fplPos << ", _uLinePos = " << _uLinePos << ", n = " << n << ", _hdrPos = " << _hdrPos << ", _fencePos = " << _fencePos << '\n';
907                         if(n == _hdrPos) {
908                                 //cout << "HEADER POS\n";
909                                 hdrPos = true;
910                         }
911                         if(n == _fencePos) {
912                                 //cout << "FENCE POS\n";
913                                 fencePos = true;
914                         }
915                         if(_hdrPos >= 0 && n > _hdrPos) --n;
916                         if(_fencePos >= 0 && n >= _fencePos) --n;       // This one needs to be >= since n is already decremented by 1 in the line above!
917                         //cout << "New n = " << n << '\n';
918                         
919                         if(n < _kln89->_flightPlans[_subPage]->waypoints.size()) {
920                                 if(_kln89->_flightPlans[_subPage]->waypoints[n]->appType != GPS_APP_NONE) {
921                                         appWp = true;
922                                 }
923                         }
924                         
925                         if(hdrPos) {
926                                 // TODO - not sure what we actually do in this condition
927                                 _changeAppr = true;
928                         } else if(fencePos) {
929                                 // no-op?
930                         } else if(appWp) {
931                                 ShowScratchpadMessage("Invald", " Add  ");
932                         } else {
933                                 if((_wLinePos + 1) > _entWpStr.size()) {
934                                         _entWpStr += '9';
935                                 } else {
936                                         _entWpStr[_wLinePos] = _kln89->DecChar(_entWpStr[_wLinePos], (_wLinePos == 0 ? false : true));
937                                 }
938                                 _bEntWp = true;
939                                 _fp0SelWpId.clear();    // Waypoints don't become the DTO default whilst being entered.
940                                 
941                                 bool multi;
942                                 const GPSWaypoint* wp = _kln89->FindFirstById(_entWpStr.substr(0, _wLinePos+1), multi, false);
943                                 if(NULL == wp) {
944                                         // no-op
945                                 } else {
946                                         if(_entWp == NULL) {
947                                                 _entWp = new GPSWaypoint;
948                                                 if(_fplPos + (_uLinePos - 4) >= _kln89->_flightPlans[_subPage]->waypoints.size()) {
949                                                         _kln89->_flightPlans[_subPage]->waypoints.push_back(_entWp);
950                                                 } else {
951                                                         _kln89->_flightPlans[_subPage]->waypoints.insert(_kln89->_flightPlans[_subPage]->waypoints.begin()+(_fplPos + (_uLinePos - 4)), _entWp);
952                                                 }
953                                         }
954                                         // copy
955                                         *_entWp = *wp;
956                                 }
957                         }
958                 }
959         }
960 }
961
962 void KLN89FplPage::Knob2Right1() {
963         if(_delFP) {
964                 _delFP = false;
965                 return;
966         }
967         _delWp = false;
968
969         if(_kln89->_mode != KLN89_MODE_CRSR || _uLinePos == 0) {
970                 if(_kln89->_mode != KLN89_MODE_CRSR) _resetFplPos0 = true;
971                 KLN89Page::Knob2Right1();
972         } else {
973                 if(_uLinePos > 3) {
974                         // Check for approach waypoints or header/fences in flightplan 0
975                         int n = _fplPos + _uLinePos - 4;
976                         bool hdrPos = false;
977                         bool fencePos = false;
978                         bool appWp = false;
979                         //cout << "_fplPos = " << _fplPos << ", _uLinePos = " << _uLinePos << ", n = " << n << ", _hdrPos = " << _hdrPos << ", _fencePos = " << _fencePos << '\n';
980                         if(n == _hdrPos) {
981                                 //cout << "HEADER POS\n";
982                                 hdrPos = true;
983                         }
984                         if(n == _fencePos) {
985                                 //cout << "FENCE POS\n";
986                                 fencePos = true;
987                         }
988                         if(_hdrPos >= 0 && n > _hdrPos) --n;
989                         if(_fencePos >= 0 && n >= _fencePos) --n;       // This one needs to be >= since n is already decremented by 1 in the line above!
990                         //cout << "New n = " << n << '\n';
991                         
992                         if(n < _kln89->_flightPlans[_subPage]->waypoints.size()) {
993                                 if(_kln89->_flightPlans[_subPage]->waypoints[n]->appType != GPS_APP_NONE) {
994                                         appWp = true;
995                                 }
996                         }
997                         
998                         if(hdrPos) {
999                                 // TODO - not sure what we actually do in this condition
1000                                 _changeAppr = true;
1001                         } else if(fencePos) {
1002                                 // no-op?
1003                         } else if(appWp) {
1004                                 ShowScratchpadMessage("Invald", " Add  ");
1005                         } else {
1006                                 if((_wLinePos + 1) > _entWpStr.size()) {
1007                                         _entWpStr += '9';
1008                                 } else {
1009                                         _entWpStr[_wLinePos] = _kln89->DecChar(_entWpStr[_wLinePos], (_wLinePos == 0 ? false : true));
1010                                 }
1011                                 _bEntWp = true;
1012                                 _fp0SelWpId.clear();    // Waypoints don't become the DTO default whilst being entered.
1013                                 
1014                                 bool multi;
1015                                 const GPSWaypoint* wp = _kln89->FindFirstById(_entWpStr.substr(0, _wLinePos+1), multi, false);
1016                                 if(NULL == wp) {
1017                                         // no-op
1018                                 } else {
1019                                         if(_entWp == NULL) {
1020                                                 _entWp = new GPSWaypoint;
1021                                                 if(_fplPos + (_uLinePos - 4) >= _kln89->_flightPlans[_subPage]->waypoints.size()) {
1022                                                         _kln89->_flightPlans[_subPage]->waypoints.push_back(_entWp);
1023                                                 } else {
1024                                                         _kln89->_flightPlans[_subPage]->waypoints.insert(_kln89->_flightPlans[_subPage]->waypoints.begin()+(_fplPos + (_uLinePos - 4)), _entWp);
1025                                                 }
1026                                         }
1027                                         // copy
1028                                         *_entWp = *wp;
1029                                 }
1030                         }
1031                 }
1032         }
1033 }