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