/*
* ShootOFF - Software for Laser Dry Fire Training
* Copyright (C) 2016 phrack
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.shootoff.gui.pane;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.shootoff.camera.CameraManager;
import com.shootoff.camera.Shot;
import com.shootoff.config.Configuration;
import com.shootoff.gui.ExerciseListener;
import com.shootoff.gui.controller.PluginManagerController;
import com.shootoff.gui.controller.SessionViewerController;
import com.shootoff.plugins.ExerciseMetadata;
import com.shootoff.plugins.ProjectorTrainingExerciseBase;
import com.shootoff.plugins.TrainingExercise;
import com.shootoff.plugins.engine.PluginListener;
import com.shootoff.session.SessionRecorder;
import com.shootoff.session.io.SessionIO;
import com.shootoff.targets.Hit;
import com.shootoff.targets.Target;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.control.TitledPane;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ExerciseSlide extends Slide implements PluginListener, ItemSelectionListener<TrainingExercise> {
private static final Logger logger = LoggerFactory.getLogger(ExerciseSlide.class);
private final Configuration config;
private final ExerciseListener exerciseListener;
private final TitledPane projectorPane;
private final ToggleButton noneButton;
private final ItemSelectionPane<TrainingExercise> exerciseItemPane = new ItemSelectionPane<>(true, this);
private final ItemSelectionPane<TrainingExercise> projectorExerciseItemPane = new ItemSelectionPane<>(
exerciseItemPane.getToggleGroup(), this);
private static final TrainingExercise noneExercise = new TrainingExercise() {
@Override
public void init() {}
@Override
public void targetUpdate(Target target, TargetChange change) {}
@Override
public ExerciseMetadata getInfo() {
return null;
}
@Override
public void shotListener(Shot shot, Optional<Hit> hit) {}
@Override
public void reset(List<Target> targets) {}
@Override
public void destroy() {}
};
public ExerciseSlide(Pane parentControls, Pane parentBody, ExerciseListener exerciseListener) {
super(parentControls, parentBody);
this.exerciseListener = exerciseListener;
config = Configuration.getConfig();
addSlideControlButton("Get Exercises", (event) -> {
final Optional<FXMLLoader> loader = createPluginManagerStage();
if (loader.isPresent()) {
final PluginManagerController pluginManagerController = (PluginManagerController) loader.get()
.getController();
pluginManagerController.init(exerciseListener.getPluginEngine(),
(Stage) parentControls.getScene().getWindow());
final PluginManagerSlide pluginViewerSlide = new PluginManagerSlide(parentControls, parentBody,
pluginManagerController);
pluginViewerSlide.showControls();
pluginViewerSlide.showBody();
}
});
addSlideControlButton("Record Session", (event) -> {
if (config.getSessionRecorder().isPresent()) {
stopRecordingSession();
((Button) event.getSource()).setText("Record Session");
} else {
startRecordingSession();
((Button) event.getSource()).setText("Stop Recording");
}
hide();
});
addSlideControlButton("View Sessions", (event) -> {
final Optional<FXMLLoader> loader = createSessionViewerStage();
if (loader.isPresent()) {
final SessionViewerController sessionViewerController = (SessionViewerController) loader.get()
.getController();
sessionViewerController.init(Configuration.getConfig());
final SessionViewerSlide sessionViewerSlide = new SessionViewerSlide(parentControls, parentBody,
sessionViewerController);
sessionViewerSlide.showControls();
sessionViewerSlide.showBody();
}
});
noneButton = addNoneButton();
final TitledPane universalPane = new TitledPane("Universal Exercises", exerciseItemPane);
projectorPane = new TitledPane("Projector Exercises", projectorExerciseItemPane);
projectorPane.setDisable(true);
projectorPane.setExpanded(false);
addBodyNode(new VBox(universalPane, projectorPane));
}
@Override
public void showControls() {
super.showControls();
showBody();
}
private ToggleButton addNoneButton() {
final ToggleButton noneButton = (ToggleButton) exerciseItemPane.addButton(noneExercise, "None");
noneButton.setSelected(true);
exerciseItemPane.setDefault(noneExercise);
return noneButton;
}
private Optional<FXMLLoader> createSessionViewerStage() {
final FXMLLoader loader = new FXMLLoader(
getClass().getClassLoader().getResource("com/shootoff/gui/SessionViewer.fxml"));
try {
loader.load();
} catch (final IOException e) {
logger.error("Cannot load SessionViewer.fxml", e);
return Optional.empty();
}
return Optional.of(loader);
}
private Optional<FXMLLoader> createPluginManagerStage() {
final FXMLLoader loader = new FXMLLoader(
getClass().getClassLoader().getResource("com/shootoff/gui/PluginManager.fxml"));
try {
loader.load();
} catch (final IOException e) {
logger.error("Cannot load SessionViewer.fxml", e);
return Optional.empty();
}
return Optional.of(loader);
}
@Override
public void registerExercise(TrainingExercise exercise) {
final Tooltip t = new Tooltip(exercise.getInfo().getDescription());
t.setPrefWidth(500);
t.setWrapText(true);
exerciseItemPane.addButton(exercise, exercise.getInfo().getName(), Optional.empty(), Optional.of(t));
}
@Override
public void registerProjectorExercise(TrainingExercise exercise) {
final Tooltip t = new Tooltip(exercise.getInfo().getDescription());
t.setPrefWidth(500);
t.setWrapText(true);
projectorExerciseItemPane.addButton(exercise, exercise.getInfo().getName(), Optional.empty(), Optional.of(t));
}
@Override
public void unregisterExercise(TrainingExercise exercise) {
exerciseItemPane.removeButton(exercise);
}
public void toggleProjectorExercises(boolean isDisabled) {
if (isDisabled) {
noneButton.fire();
}
projectorPane.setDisable(isDisabled);
projectorPane.setExpanded(!isDisabled);
}
public ExerciseListener getExerciseListener() {
return exerciseListener;
}
private void startRecordingSession() {
config.setSessionRecorder(new SessionRecorder());
for (final CameraManager cm : config.getRecordingManagers()) {
cm.startRecordingShots();
}
}
public void stopRecordingSession() {
for (final CameraManager cm : config.getRecordingManagers()) {
cm.stopRecordingShots();
}
SessionIO.saveSession(config.getSessionRecorder().get(), new File(System.getProperty("shootoff.home")
+ File.separator + "sessions/" + config.getSessionRecorder().get().getSessionName() + ".xml"));
config.setSessionRecorder(null);
}
@Override
public void onItemClicked(TrainingExercise selectedExercise) {
if (selectedExercise.equals(noneExercise)) {
exerciseListener.setExercise(null);
} else if (selectedExercise instanceof ProjectorTrainingExerciseBase) {
exerciseListener.setProjectorExercise(selectedExercise);
} else {
exerciseListener.setExercise(selectedExercise);
}
hide();
}
}