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