package seng302.Controllers; import javafx.animation.AnimationTimer; import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; import org.xml.sax.SAXException; import seng302.Mock.*; import seng302.Model.Boat; import seng302.Model.RaceClock; import seng302.VisualiserInput; import seng302.RaceDataSource; import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; import java.net.URL; import java.text.ParseException; import java.util.List; import java.util.Observable; import java.util.Observer; import java.util.ResourceBundle; import java.util.stream.Stream; /** * Created by esa46 on 6/04/17. */ public class StartController extends Controller implements Observer { @FXML private GridPane start; @FXML private AnchorPane startWrapper; @FXML private TableView boatNameTable; @FXML private TableColumn boatNameColumn; @FXML private TableColumn boatCodeColumn; @FXML private Label timeZoneTime; @FXML private Label timer; @FXML private int PRERACE_TIME = 15000; @FXML Button oneMinButton; @FXML Button fiveMinButton; @FXML Button fifteenMinButton; private RaceClock raceClock; private StreamedCourse raceData; private long timeLeft = 1; /** * Begins the race with a scale factor of 15 */ public void startRace1Min() { startRace(15); } /** * Begins the race with a scale factor of 3 */ public void startRace5Min() { startRace(3); } /** * Begins the race with a scale factor of 1 */ public void startRaceNoScaling() { startRace(1); } private void startRace(int raceScale){ oneMinButton.setDisable(true); fiveMinButton.setDisable(true); fifteenMinButton.setDisable(true); countdownTimer(raceScale); } @Override public void initialize(URL location, ResourceBundle resources){ raceData = null; try { raceData = new StreamedCourse(); raceData.addObserver(this); VisualiserInput visualiserInput = new VisualiserInput(raceData); new Thread(visualiserInput).start(); // StreamedCourse streamedCourse = new StreamedCourse(new BoatXMLReader("mockXML/boatXML/boatTest.xml")); // streamedCourse.setStreamedCourseXMLReader(new StreamedCourseXMLReader("mockXML/raceXML/raceTest.xml")); // streamedCourse.setRegattaXMLReader(new RegattaXMLReader("mockXML/regattaXML/regattaTest.xml")); // raceData = streamedCourse; // }catch (ParseException e) { // e.printStackTrace(); // } catch (ParserConfigurationException e) { // e.printStackTrace(); // } catch (SAXException e) { // e.printStackTrace(); // } catch (StreamedCourseXMLException e) { // e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public AnchorPane startWrapper(){ return startWrapper; } private void initialiseTables() { List boats = raceData.getBoats(); ObservableList observableBoats = FXCollections.observableArrayList(boats); boatNameTable.setItems(observableBoats); boatNameColumn.setCellValueFactory(cellData -> cellData.getValue().getName()); boatCodeColumn.setCellValueFactory(new PropertyValueFactory<>("abbrev")); } /** * Updates the calculated time to the timer label * * @param time The calculated time from calcTimer() method */ protected void updateTime(String time) { Platform.runLater(() -> { timer.setText(time); }); } /** * Countdown timer until race starts. Use PRERACE_TIME to set countdown duration. */ protected void countdownTimer(int scaleFactor) { new AnimationTimer() { long currentTime = System.currentTimeMillis(); long startTime = currentTime + (PRERACE_TIME/scaleFactor); long minutes; long currentTimeInSeconds; long remainingSeconds; long hours; @Override public void handle(long arg0) { timeLeft = startTime - currentTime; if (timeLeft <= 0) { updateTime("Race is starting..."); stop(); parent.beginRace(scaleFactor, raceData); startWrapper.setVisible(false); } else { currentTimeInSeconds = (timeLeft*scaleFactor) / 1000; minutes = currentTimeInSeconds / 60; remainingSeconds = currentTimeInSeconds % 60; hours = minutes / 60; minutes = minutes % 60; updateTime(String.format("Race Clock: -%02d:%02d:%02d", hours, minutes, remainingSeconds)); } currentTime = System.currentTimeMillis(); } }.start(); } protected void setRaceClock() { raceClock = new RaceClock(raceData.getZonedDateTime()); timeZoneTime.textProperty().bind(raceClock.timeStringProperty()); new AnimationTimer() { @Override public void handle(long arg0) { if (timeLeft > 0) { raceClock.updateTime(); } else { stop(); } } }.start(); } @Override public void update(Observable o, Object arg) { if(o instanceof StreamedCourse) { if(((StreamedCourse) o).getBoats() != null) { initialiseTables(); } if (((StreamedCourse) o).getZonedDateTime() != null) { Platform.runLater(() -> { { setRaceClock(); } }); } } } }