View Javadoc
1   /*******************************************************************************
2    * jhunters: Pool League
3    * Copyright 2015 Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   ********************************************************************************/
17  package net.sourceforge.jhunters.pool.ui;
18  
19  import java.time.LocalDate;
20  import java.util.Iterator;
21  
22  import org.w3c.dom.Element;
23  
24  import javafx.beans.property.SimpleStringProperty;
25  import javafx.beans.property.StringProperty;
26  import javafx.beans.value.ObservableValue;
27  import javafx.collections.FXCollections;
28  import javafx.collections.ObservableList;
29  import javafx.geometry.Pos;
30  import javafx.scene.control.TableColumn;
31  import javafx.scene.control.TableColumn.CellDataFeatures;
32  import javafx.util.Callback;
33  import net.sourceforge.jhunters.pool.data.Competition;
34  import net.sourceforge.jhunters.pool.data.DataSet;
35  import net.sourceforge.jhunters.pool.data.Fixture;
36  import net.sourceforge.jhunters.pool.data.Fixture.FixtureField;
37  import net.sourceforge.jhunters.pool.data.FixtureSet;
38  import net.sourceforge.jhunters.pool.data.Player;
39  import net.sourceforge.jhunters.pool.data.Result;
40  import net.sourceforge.jhunters.pool.ui.ReportPanel.TableSource;
41  import net.sourceforge.jhunters.pool.ui.TableUtils.FieldCell;
42  import net.sourceforge.jhunters.pool.ui.TableUtils.FieldTableColumn;
43  import net.sourceforge.jhunters.pool.ui.TableUtils.FieldTableView;
44  
45  /**
46   * FixtureSet Table.
47   */
48  public class FixtureSetTable
49          extends FieldTableView<Fixture, FixtureField>
50          implements TableSource {
51      /**
52       * Width for player.
53       */
54      private static final int WIDTH_PLAYER = 150;
55  
56      /**
57       * Width for result.
58       */
59      private static final int WIDTH_RESULT = 60;
60  
61      /**
62       * Width for date.
63       */
64      protected static final int WIDTH_DATE = 100;
65  
66      /**
67       * WeekBye value.
68       */
69      private static final StringProperty BYE_PROPERTY = new SimpleStringProperty(Player.PLAYER_BYE);
70  
71      /**
72       * Week fixture format.
73       */
74      private static final String WEEK_FORMAT = GuiResource.REPORT_FIXTURES_TITLE.getValue();
75  
76      /**
77       * Current dataSet.
78       */
79      private DataSet theDataSet;
80  
81      /**
82       * Current competition.
83       */
84      private Competition theCompetition;
85  
86      /**
87       * Current fixture list.
88       */
89      private ObservableList<Fixture> theList;
90  
91      /**
92       * Constructor.
93       */
94      protected FixtureSetTable() {
95          /* Allow editing */
96          setEditable(true);
97  
98          /* Access column list */
99          ObservableList<TableColumn<Fixture, ?>> myColumns = getColumns();
100 
101         /* Create the date column */
102         TableColumn<Fixture, LocalDate> myDateCol = new FieldTableColumn<Fixture, FixtureField, LocalDate>(FixtureField.DATE);
103         myDateCol.setCellValueFactory(p -> p.getValue().dateProperty());
104         myDateCol.setCellFactory(TableUtils.dateCellFactory());
105         myDateCol.setSortable(false);
106         myDateCol.setEditable(false);
107         myDateCol.setMinWidth(WIDTH_DATE);
108         myColumns.add(myDateCol);
109 
110         /* Create the home column */
111         TableColumn<Fixture, String> myHomeCol = new FieldTableColumn<Fixture, FixtureField, String>(FixtureField.HOME);
112         myHomeCol.setCellValueFactory(new PlayerCellValueFactory(true));
113         myHomeCol.setCellFactory(TableUtils.itemCellFactory(Pos.CENTER_RIGHT));
114         myHomeCol.setMinWidth(WIDTH_PLAYER);
115         myHomeCol.setSortable(false);
116         myHomeCol.setEditable(false);
117         myColumns.add(myHomeCol);
118 
119         /* Create the result column */
120         TableColumn<Fixture, Result> myResultCol = new FieldTableColumn<Fixture, FixtureField, Result>(FixtureField.RESULT);
121         myResultCol.setCellValueFactory(p -> p.getValue().resultProperty());
122         myResultCol.setCellFactory(TableUtils.enumCellFactory(Result.class));
123         myResultCol.setSortable(false);
124         myResultCol.setMinWidth(WIDTH_RESULT);
125         myColumns.add(myResultCol);
126 
127         /* Create the away column */
128         TableColumn<Fixture, String> myAwayCol = new FieldTableColumn<Fixture, FixtureField, String>(FixtureField.AWAY);
129         myAwayCol.setCellValueFactory(new PlayerCellValueFactory(false));
130         myAwayCol.setCellFactory(TableUtils.itemCellFactory(Pos.CENTER_LEFT));
131         myAwayCol.setMinWidth(WIDTH_PLAYER);
132         myAwayCol.setSortable(false);
133         myAwayCol.setEditable(false);
134         myColumns.add(myAwayCol);
135     }
136 
137     /**
138      * Set dataSet.
139      * @param pData the dataSet
140      */
141     protected void setData(final DataSet pData) {
142         /* Store the DataSet */
143         theDataSet = pData;
144     }
145 
146     /**
147      * Set competition.
148      * @param pCompetition the competition
149      */
150     protected void setCompetition(final Competition pCompetition) {
151         /* Store the Competition */
152         theCompetition = pCompetition;
153     }
154 
155     /**
156      * Set table data.
157      * @param pFixtureSet the fixtureSet
158      */
159     protected void setFixtureSet(final FixtureSet pFixtureSet) {
160         /* Access the fixture list */
161         theList = pFixtureSet != null
162                                       ? FXCollections.observableList(pFixtureSet.getFixtures())
163                                       : FXCollections.observableArrayList();
164 
165         /* Declare the list */
166         setItems(theList);
167     }
168 
169     @Override
170     public void buildReport(final ReportBuilder pBuilder) {
171         /* Build the main report */
172         buildMainReport(pBuilder);
173     }
174 
175     @Override
176     public void createWeb(final ReportBuilder pBuilder) {
177         /* Build the main report */
178         buildMainReport(pBuilder);
179     }
180 
181     /**
182      * build the main report.
183      * @param pBuilder the builder
184      */
185     private void buildMainReport(final ReportBuilder pBuilder) {
186         /* Loop through the fixtures */
187         Iterator<FixtureSet> myIterator = theCompetition.getFixtureList().fixtureIterator();
188         while (myIterator.hasNext()) {
189             FixtureSet myFixtureSet = myIterator.next();
190 
191             /* Build the fixture report */
192             buildSubReport(pBuilder, myFixtureSet);
193         }
194     }
195 
196     /**
197      * Build fixture list.
198      * @param pBuilder the builder
199      * @param pFixtureSet the fixture Set
200      */
201     private void buildSubReport(final ReportBuilder pBuilder,
202                                 final FixtureSet pFixtureSet) {
203         /* Set the heading */
204         int myWeek = pFixtureSet.getWeekNo();
205         pBuilder.setHeading(WEEK_FORMAT, myWeek);
206 
207         /* Determine break point */
208         int myBreak = theCompetition.getPlayerCount() >> 2;
209 
210         /* Create a new table */
211         pBuilder.newTable();
212 
213         /* Set the column headings */
214         pBuilder.setColumnHeading(FixtureField.DATE.toString());
215         pBuilder.setColumnHeading(FixtureField.HOME.toString());
216         pBuilder.setColumnHeading(FixtureField.RESULT.toString());
217         pBuilder.setColumnHeading(FixtureField.AWAY.toString());
218 
219         /* Loop through the fixtures */
220         int i = 0;
221         Iterator<Fixture> myIterator = pFixtureSet.fixtureIterator();
222         while (myIterator.hasNext()) {
223             Fixture myFixture = myIterator.next();
224 
225             /* Determine whether we need a separator */
226             boolean bSeparator = (i++ % myBreak) == 0;
227             if (bSeparator) {
228                 /* Create a new row */
229                 Element myRow = pBuilder.newRow();
230                 pBuilder.addClassAttribute(myRow, ReportBuilder.CLASS_SEPARATOR);
231 
232                 /* Add date to cell and set span */
233                 Element myCell = pBuilder.setCellDate(myFixture.dateProperty().getValue());
234                 myCell.setAttribute(ReportBuilder.ATTR_ROWSPAN, Integer.toString(myBreak));
235             } else {
236                 /* Create a new row */
237                 pBuilder.newRow();
238             }
239 
240             /* Set the cells */
241             pBuilder.setCellPlayerRight(myFixture.homePlayerProperty().getValue());
242             pBuilder.setCellResult(myFixture.resultProperty().getValue());
243             pBuilder.setCellPlayerLeft(myFixture.awayPlayerProperty().getValue());
244         }
245 
246         /* If the week is even */
247         if ((myWeek & 1) == 0) {
248             /* Create a page break */
249             pBuilder.setPageBreak();
250 
251             /* else add some spaces */
252         } else {
253             pBuilder.setLineSpace();
254         }
255     }
256 
257     @Override
258     public boolean preEditHook(final FieldCell<Fixture, FixtureField> pCell) {
259         /* Access the details */
260         Fixture myFixture = pCell.getTheRow();
261         FixtureField myField = pCell.getTheField();
262 
263         /* Switch on field */
264         switch (myField) {
265             case NEWDATE:
266                 return myFixture.getResult() == null;
267             case RESULT:
268                 return true;
269             default:
270                 return false;
271         }
272     }
273 
274     @Override
275     public void postCommitHook(final FieldCell<Fixture, FixtureField> pCell) {
276         /* Note that the data is updated */
277         theDataSet.setUpdated(Boolean.TRUE);
278 
279         /* process fixtures */
280         theCompetition.processFixtures();
281     }
282 
283     /**
284      * PlayerCellValue factory.
285      */
286     protected static final class PlayerCellValueFactory
287             implements Callback<CellDataFeatures<Fixture, String>, ObservableValue<String>> {
288         /**
289          * Home/Away.
290          */
291         private final boolean isHome;
292 
293         /**
294          * Constructor.
295          * @param pHome is this for home (or away)
296          */
297         protected PlayerCellValueFactory(final boolean pHome) {
298             isHome = pHome;
299         }
300 
301         @Override
302         public ObservableValue<String> call(final CellDataFeatures<Fixture, String> p) {
303             Player myPlayer = isHome
304                                      ? p.getValue().getHomePlayer()
305                                      : p.getValue().getAwayPlayer();
306             return myPlayer == null
307                                     ? BYE_PROPERTY
308                                     : myPlayer.nameProperty();
309         }
310     }
311 }