1   package org.wcb.gui.table.model;
2   
3   import org.wcb.model.vo.hibernate.Logbook;
4   import org.wcb.model.vo.TotalLogEntriesVO;
5   import org.wcb.model.bd.LogbookDelegate;
6   
7   import javax.swing.table.AbstractTableModel;
8   import java.util.ArrayList;
9   import java.util.List;
10  import java.text.DateFormat;
11  
12  /**
13   * <small>
14   * Copyright (c)  2006  wbogaardt.
15   * This library is free software; you can redistribute it and/or
16   * modify it under the terms of the GNU Lesser General Public
17   * License as published by the Free Software Foundation; either
18   * version 2.1 of the License, or (at your option) any later version.
19   *
20   * This library is distributed in the hope that it will be useful,
21   * but WITHOUT ANY WARRANTY; without even the implied warranty of
22   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23   * Lesser General Public License for more details.
24   *
25   * You should have received a copy of the GNU Lesser General Public
26   * License along with this library; if not, write to the Free Software
27   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
28   * <p/>
29   * $File:  $ <br>
30   * $Change:  $ submitted by $Author: wbogaardt $ at $DateTime: Mar 28, 2006 8:51:59 AM $ <br>
31   * </small>
32   *
33   * @author wbogaardt
34   * @version 1
35   *          Date: Mar 28, 2006
36   *          Time: 8:51:59 AM
37   */
38  
39  public class LogbookTableModel extends AbstractTableModel {
40  
41      private Object[] columnNameFlat = new Object[] {
42              "","", "Date", "Registration", "From", "Via", "To", "Duration", "PIC", "SIC", "Cross Country",
43              "as Flight Instructor", "as SafetyPilot", "Dual \nReceived", "Solo",
44              "TO/LDG", "TO/LDG","Instrument approaches", "Night", "Actual IMC", "Simulated IMC",
45              "Flight Simulator", " " , " "};
46      private Object[][] columnName = new Object[][]{
47              new String[] {"Line"},
48              new String[]{"Date"},
49              new String[]{"Registration"},
50              new String[]{"From"},
51              new String[]{"Via"},
52              new String[]{"To"},
53              new String[]{"Duration", "of Flight"},
54              new String[]{"PIC"},
55              new String[]{"SIC"},
56              new String[]{"Cross", "Country"},
57              new String[]{"as Flight", "Instructor"},
58              new String[]{"as Safety", "Pilot"},
59              new String[]{"Dual", "Received"},
60              new String[]{"Solo"},
61              new String[]{"TO/Ldg"},
62              new String[]{"TO/LDG"},
63              new String[]{"Instrument", "Approaches"},
64              new String[]{"Night"},
65              new String[]{"Actual", "Instrument"},
66              new String[]{"Simulated", "Instrument"},
67              new String[]{"Flight", "Simulator"},
68              new String[]{""},
69              new String[]{""}};
70      private ArrayList row;
71      private LogbookDelegate delegate;
72      private DateFormat dateFormater = DateFormat.getDateInstance(DateFormat.MEDIUM);
73      private int numberOfPages;
74      private int MAX_ENTRIES_PER_PAGE = 15;
75      private int currentPage;
76      private List<Logbook> allEntriesList;
77  
78      public LogbookTableModel() {
79          refreshModel();
80      }
81  
82      public LogbookDelegate getDelegate() {
83          return delegate;
84      }
85  
86      public void setDelegate(LogbookDelegate delegate) {
87          this.delegate = delegate;
88      }
89  
90      public void refreshModel() {
91          if(delegate != null) {
92              allEntriesList = delegate.getAllLogbookEntries();
93              numberOfPages = allEntriesList.size() / MAX_ENTRIES_PER_PAGE;
94              row = getEntriesForPage();
95              calculatePageTotals();
96          }
97      }
98  
99  
100     /**
101      * The user may want to display more or less entries per page
102      * for their log book so let them change the value.
103      * @param value number of logbook entries per page.
104      */
105     public void setMaxEntriesPerPage(int value) {
106         this.MAX_ENTRIES_PER_PAGE = value;
107         this.refreshModel();
108     }
109 
110     private ArrayList getEntriesForPage() {
111         int startLineItem = currentPage * MAX_ENTRIES_PER_PAGE;
112         int endLineItem = startLineItem + MAX_ENTRIES_PER_PAGE;
113         //check that the end count for a page is not greater than the number of elements in the total log book.
114         //Otherwise then the highest number should be the size of all entries in the log book.
115         if (endLineItem > allEntriesList.size()) {
116             endLineItem = allEntriesList.size();
117         }
118         ArrayList returnVal = new ArrayList();
119         for(int i=startLineItem; i < endLineItem; i++) {
120             returnVal.add(allEntriesList.get(i));
121         }
122         returnVal.add(new TotalLogEntriesVO()); //bring forward totals
123         returnVal.add(new TotalLogEntriesVO()); //for totals of the page
124         returnVal.add(new TotalLogEntriesVO()); //for totals of the entire log book
125         return returnVal;
126     }
127 
128     /**
129      * Current page that the user would be on. This is loaded
130      * from a cache list of the model;
131      * @return  The current page which is number of entries divided by a set numer of entries in a page.
132      */
133     public int getCurrentPage() {
134         return currentPage;
135     }
136 
137     /**
138      * Accessor to get the total number of pages based on the list of entries.
139      * So if there are 100 entries and each page is broken down to 10 entries each
140      * you would get 10 pages.
141      * @return Number of pages.
142      */
143     public int getTotalPages() {
144         return numberOfPages;
145     }
146     /**
147      * Goes to the begining of the entries list.
148      */
149     public void goToBegining() {
150         currentPage = 0;
151         row = getEntriesForPage();
152         calculatePageTotals();
153     }
154 
155     /**
156      * Pages back one page full of entries.
157      */
158     public void previousPage() {
159         currentPage--;
160         if(currentPage<0) {
161             currentPage = 0;
162         }
163         row = getEntriesForPage();
164         calculatePageTotals();
165     }
166 
167     /**
168      * Pages forward one full page of entries.
169      */
170     public void nextPage() {
171         currentPage++;
172         if(currentPage > numberOfPages) {
173             currentPage = numberOfPages;
174         }
175         row = getEntriesForPage();
176         calculatePageTotals();
177     }
178 
179     /**
180      * Goes to the end of the full list of entries or the last page in the log book so to speak.
181      */
182     public void goToEnd() {
183         currentPage = numberOfPages;
184         row = getEntriesForPage();
185         calculatePageTotals();
186     }
187 
188     public String getColumnName(int column) {
189         return (String) columnNameFlat[column];
190     }
191 
192     public Object[] getColumnHeader(int column) {
193         return columnName[column];
194     }
195 
196     public boolean isCellEditable(int line, int column) {
197         return true;
198     }
199 
200     public int getColumnCount() {
201         return columnNameFlat.length;
202     }
203 
204     public int getRowCount() {
205         return row.size();
206     }
207 
208     public Object getValueAt(int rowLine, int column) {
209         Object objValue = row.get(rowLine);
210         if (objValue instanceof Logbook) {
211             Logbook entry = (Logbook) objValue;
212             switch(column)
213             {
214                 case 2:
215                     return dateFormater.format(entry.getEntryDate());
216                 case 3:
217                     return entry.getRegistration();
218                 case 4:
219                     return entry.getFaaFrom();
220                 case 5:
221                     return entry.getFaaVia();
222                 case 6:
223                     return entry.getFaaTo();
224                 case 7:
225                     return entry.getFlightDuration();
226                 case 8:
227                     return entry.getPic();
228                 case 9:
229                     return entry.getSic();
230                 case 10:
231                     return entry.getCrossCountry();
232                 case 11:
233                     return entry.getFlightInstructing();
234                 case 12:
235                     return entry.getSafetyPilot();
236                 case 13:
237                     return entry.getDualReceived();
238                 case 14:
239                     return entry.getSolo();
240                 case 15:
241                     return entry.getDayTakeoffs() + " | " + entry.getDayLandings();
242                 case 16:
243                     return entry.getNightTakeoffs() + " | " + entry.getNightLandings();
244                 case 17:
245                     return entry.getInstrumentApproaches();
246                 case 18:
247                     return entry.getConditionNight();
248                 case 19:
249                     return entry.getConditionActualImc();
250                 case 20:
251                     return entry.getConditionSimulatedImc();
252                 case 21:
253                     return entry.getConditionFlightSim();
254                 default:
255                     return entry;
256             }
257         }
258         if (objValue instanceof TotalLogEntriesVO) {
259             TotalLogEntriesVO totalRow = (TotalLogEntriesVO) objValue;
260             switch(column) {
261                 case 2:
262                     return totalRow.getDescription();
263                 case 7:
264                     return totalRow.getTotalFlight();
265                 case 8:
266                     return totalRow.getTotalPIC();
267                 case 9:
268                     return totalRow.getTotalSIC();
269                 case 10:
270                     return totalRow.getTotalXCountry();
271                 case 11:
272                     return totalRow.getTotalFlightInstructing();
273                 case 12:
274                     return totalRow.getTotalSafety();
275                 case 13:
276                     return totalRow.getTotalDual();
277                 case 14:
278                     return totalRow.getTotalSolo();
279                 case 17:
280                     return totalRow.getTotalApproaches();
281                 case 18:
282                     return totalRow.getTotalNight();
283                 case 19:
284                     return totalRow.getTotalIMC();
285                 case 20:
286                     return totalRow.getTotalSimulatedIMC();
287                 case 21:
288                     return totalRow.getTotalSimulatorTime();
289                 default:
290                     return totalRow;
291             }
292         }
293         return "";
294     }
295 
296     /**
297      * This updates the totals row which displays at the bottom of the table.
298      * This method would be called in cases of the model change like a row
299      * being deleted or added.
300      */
301     private void calculatePageTotals() {
302         double totalFlightDuration = 0.0;
303         double totalPIC = 0.0;
304         double totalSIC = 0.0;
305         double totalXCountry = 0.0;
306         double totalFlightInstructing = 0.0;
307         double totalSafety = 0.0;
308         double totalDual= 0.0;
309         double totalSolo = 0.0;
310         int totalApproaches = 0;
311         double totalNight = 0.0;
312         double totalIMC = 0.0;
313         double totalSimulatedIMC = 0.0;
314         double totalFlightSim = 0.0;
315         for (int i = 0; i < this.getRowCount() - 2; i++) {
316             totalFlightDuration += ((Double) this.getValueAt(i, 7)).doubleValue();
317             totalPIC += ((Double) this.getValueAt(i, 8)).doubleValue();
318             totalSIC += ((Double) this.getValueAt(i, 9)).doubleValue();
319             totalXCountry += ((Double) this.getValueAt(i, 10)).doubleValue();
320             totalFlightInstructing += ((Double) this.getValueAt(i, 11)).doubleValue();
321             totalSafety += ((Double) this.getValueAt(i, 12)).doubleValue();
322             totalDual += ((Double) this.getValueAt(i, 13)).doubleValue();
323             totalSolo += ((Double) this.getValueAt(i, 14)).doubleValue();
324             totalApproaches += ((Integer) this.getValueAt(i, 17)).intValue();
325             totalNight += ((Double) this.getValueAt(i, 18)).doubleValue();
326             totalIMC += ((Double) this.getValueAt(i, 19)).doubleValue();
327             totalSimulatedIMC += ((Double) this.getValueAt(i, 20)).doubleValue();
328             totalFlightSim += ((Double) this.getValueAt(i, 21)).doubleValue();
329         }
330         TotalLogEntriesVO voTotal = (TotalLogEntriesVO) row.get(getRowCount()-2);
331         voTotal.setDescription("Page Total");
332         voTotal.setTotalFlight(totalFlightDuration);
333         voTotal.setTotalPIC(totalPIC);
334         voTotal.setTotalSIC(totalSIC);
335         voTotal.setTotalXCountry(totalXCountry);
336         voTotal.setTotalFlightInstructing(totalFlightInstructing);
337         voTotal.setTotalDual(totalDual);
338         voTotal.setTotalSafety(totalSafety);
339         voTotal.setTotalSolo(totalSolo);
340         voTotal.setTotalApproaches(totalApproaches);
341         voTotal.setTotalNight(totalNight);
342         voTotal.setTotalIMC(totalIMC);
343         voTotal.setTotalSimulatedIMC(totalSimulatedIMC);
344         voTotal.setTotalSimulatorTime(totalFlightSim);
345         row.set(getRowCount()-2, voTotal);
346         calculateBringForwardTotals();
347         calculateTotalLogbook();
348         fireTableDataChanged();
349     }
350 
351     /**
352      * This updates the totals row which displays at the bottom of the table.
353      * This method would be called in cases of the model change like a row
354      * being deleted or added.
355      */
356     private void calculateBringForwardTotals() {
357         double totalFlightDuration = 0.0;
358         double totalPIC = 0.0;
359         double totalSIC = 0.0;
360         double totalXCountry = 0.0;
361         double totalFlightInstructing = 0.0;
362         double totalSafety = 0.0;
363         double totalDual= 0.0;
364         double totalSolo = 0.0;
365         int totalApproaches = 0;
366         double totalNight = 0.0;
367         double totalIMC = 0.0;
368         double totalSimulatedIMC = 0.0;
369         double totalFlightSim = 0.0;
370         int startLineItem = currentPage * MAX_ENTRIES_PER_PAGE;
371         for (int i = 0; i < startLineItem; i++) {
372             Logbook item = allEntriesList.get(i);
373             totalFlightDuration += item.getFlightDuration();
374             totalPIC += item.getPic();
375             totalSIC += item.getSic();
376             totalXCountry += item.getCrossCountry();
377             totalFlightInstructing += item.getFlightInstructing();
378             totalSafety += item.getSafetyPilot();
379             totalDual += item.getDualReceived();
380             totalSolo += item.getSolo();
381             totalApproaches += item.getInstrumentApproaches();
382             totalNight += item.getConditionNight();
383             totalIMC += item.getConditionActualImc();
384             totalSimulatedIMC += item.getConditionSimulatedImc();
385             totalFlightSim += item.getConditionFlightSim();
386 
387 
388         }
389         TotalLogEntriesVO voTotal = (TotalLogEntriesVO) row.get(getRowCount() - 3);
390         voTotal.setDescription("Totals Brought Forward");
391         voTotal.setTotalFlight(totalFlightDuration);
392         voTotal.setTotalPIC(totalPIC);
393         voTotal.setTotalSIC(totalSIC);
394         voTotal.setTotalXCountry(totalXCountry);
395         voTotal.setTotalFlightInstructing(totalFlightInstructing);
396         voTotal.setTotalDual(totalDual);
397         voTotal.setTotalSafety(totalSafety);
398         voTotal.setTotalSolo(totalSolo);
399         voTotal.setTotalApproaches(totalApproaches);
400         voTotal.setTotalNight(totalNight);
401         voTotal.setTotalIMC(totalIMC);
402         voTotal.setTotalSimulatedIMC(totalSimulatedIMC);
403         voTotal.setTotalSimulatorTime(totalFlightSim);
404         row.set(getRowCount()-3, voTotal);
405         calculateTotalLogbook();
406         fireTableDataChanged();
407     }
408 
409     /**
410      * This updates the totals row which displays at the bottom of the table.
411      * This method would be called in cases of the model change like a row
412      * being deleted or added.
413      */
414     private void calculateTotalLogbook() {
415         double totalFlightDuration = 0.0;
416         double totalPIC = 0.0;
417         double totalSIC = 0.0;
418         double totalXCountry = 0.0;
419         double totalFlightInstructing = 0.0;
420         double totalSafety = 0.0;
421         double totalDual= 0.0;
422         double totalSolo = 0.0;
423         int totalApproaches = 0;
424         double totalNight = 0.0;
425         double totalIMC = 0.0;
426         double totalSimulatedIMC = 0.0;
427         double totalFlightSim = 0.0;
428         // Logbook objValue;
429         for (Logbook objValue : allEntriesList) {
430             totalFlightDuration += objValue.getFlightDuration();
431             totalPIC += objValue.getPic();
432             totalSIC += objValue.getSic();
433             totalXCountry += objValue.getCrossCountry();
434             totalFlightInstructing += objValue.getFlightInstructing();
435             totalSafety += objValue.getSafetyPilot();
436             totalDual += objValue.getDualReceived();
437             totalSolo += objValue.getSolo();
438             totalApproaches += objValue.getInstrumentApproaches();
439             totalNight += objValue.getConditionNight();
440             totalIMC += objValue.getConditionActualImc();
441             totalSimulatedIMC += objValue.getConditionSimulatedImc();
442             totalFlightSim += objValue.getConditionFlightSim();
443         }
444         TotalLogEntriesVO voTotal = (TotalLogEntriesVO) row.get(getRowCount()-1);
445         voTotal.setDescription("Grand Total");
446         voTotal.setTotalFlight(totalFlightDuration);
447         voTotal.setTotalPIC(totalPIC);
448         voTotal.setTotalSIC(totalSIC);
449         voTotal.setTotalXCountry(totalXCountry);
450         voTotal.setTotalFlightInstructing(totalFlightInstructing);
451         voTotal.setTotalDual(totalDual);
452         voTotal.setTotalSafety(totalSafety);
453         voTotal.setTotalSolo(totalSolo);
454         voTotal.setTotalApproaches(totalApproaches);
455         voTotal.setTotalNight(totalNight);
456         voTotal.setTotalIMC(totalIMC);
457         voTotal.setTotalSimulatedIMC(totalSimulatedIMC);
458         voTotal.setTotalSimulatorTime(totalFlightSim);
459         row.set(getRowCount()-1,voTotal);
460         fireTableDataChanged();
461     }
462 
463     /**
464      * Remove the identified row from the
465      * model and fire a data table change event.
466      * @param rowId Row number to remove
467      */
468     public void removeRow(int rowId)
469     {
470         row.remove(rowId);
471         this.calculatePageTotals();
472         fireTableDataChanged();
473     }
474 
475     public Class getColumnClass(int columnIndex) {
476         try
477         {
478             return getValueAt(0, columnIndex).getClass();
479         }
480         catch (Exception e)
481         {
482             return String.class;
483         }
484     }
485 }