/*
* Copyright (c) 2014-2016 Jan Strauß <jan[at]over9000.eu>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package eu.over9000.skadi.ui.dialogs;
import eu.over9000.cathode.data.RootBox;
import eu.over9000.skadi.io.PersistenceHandler;
import eu.over9000.skadi.model.StateContainer;
import eu.over9000.skadi.service.CheckAuthService;
import eu.over9000.skadi.util.TwitchUtil;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBar.ButtonData;
import javafx.scene.control.*;
import javafx.scene.control.Dialog;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import org.apache.commons.lang3.SystemUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.*;
import java.io.File;
import java.util.Optional;
public class SettingsDialog extends Dialog<StateContainer> {
public static final String LIVESTREAMER_CONFIG_PATH_WIN = System.getenv("APPDATA") + "\\livestreamer\\";
private static final Logger LOGGER = LoggerFactory.getLogger(SettingsDialog.class);
private final StateContainer state;
private final PersistenceHandler persistenceHandler;
private CheckBox cbShowNotifications;
private CheckBox cbMinimizeToTray;
private CheckBox cbDarkTheme;
private Label lbLivestreamer;
private Label lbChrome;
private Label lbAuthUser;
private Label valueAuthUser;
private TextField tfLivestreamer;
private TextField tfChrome;
private Button btLivestreamerCfg;
private Button btSkadiLog;
private Button btChangeAuth;
private VBox boxSkadiLog;
private ProgressIndicator pi;
private GridPane contentPane;
public SettingsDialog(final StateContainer state, final PersistenceHandler persistenceHandler) {
this.persistenceHandler = persistenceHandler;
this.state = state;
setTitle("Skadi settings");
setHeaderText(null);
setGraphic(null);
final ButtonType saveButtonType = new ButtonType("Save", ButtonData.OK_DONE);
getDialogPane().getButtonTypes().addAll(saveButtonType, ButtonType.CANCEL);
getDialogPane().setContent(getContentPane());
setResultConverter(btn -> {
if (btn == saveButtonType) {
state.setExecutableLivestreamer(tfLivestreamer.getText());
state.setExecutableChrome(tfChrome.getText());
state.setDisplayNotifications(cbShowNotifications.isSelected());
state.setMinimizeToTray(cbMinimizeToTray.isSelected());
state.setUseDarkTheme(cbDarkTheme.isSelected());
return state;
}
return null;
});
}
public CheckBox getCbShowNotifications() {
if (cbShowNotifications == null) {
cbShowNotifications = new CheckBox("Show notifications");
cbShowNotifications.setSelected(state.isDisplayNotifications());
}
return cbShowNotifications;
}
public CheckBox getCbMinimizeToTray() {
if (cbMinimizeToTray == null) {
cbMinimizeToTray = new CheckBox("Minimize to tray");
cbMinimizeToTray.setSelected(state.isMinimizeToTray());
}
return cbMinimizeToTray;
}
public CheckBox getCbDarkTheme() {
if (cbDarkTheme == null) {
cbDarkTheme = new CheckBox("Use dark Theme");
cbDarkTheme.setSelected(state.isUseDarkTheme());
}
return cbDarkTheme;
}
public Label getLbLivestreamer() {
if (lbLivestreamer == null) {
lbLivestreamer = new Label("Livestreamer executable");
}
return lbLivestreamer;
}
public TextField getTfLivestreamer() {
if (tfLivestreamer == null) {
tfLivestreamer = new TextField(state.getExecutableLivestreamer());
tfLivestreamer.setPrefColumnCount(25);
}
return tfLivestreamer;
}
public Button getBtLivestreamerCfg() {
if (btLivestreamerCfg == null) {
btLivestreamerCfg = new Button("Open configuration folder");
btLivestreamerCfg.setOnAction(event -> {
try {
Desktop.getDesktop().open(new File(LIVESTREAMER_CONFIG_PATH_WIN));
} catch (final Exception e) {
LOGGER.error("settings dialog: open config folder failed: ", e);
}
});
}
return btLivestreamerCfg;
}
public Label getLbChrome() {
if (lbChrome == null) {
lbChrome = new Label("Chrome executable");
}
return lbChrome;
}
public TextField getTfChrome() {
if (tfChrome == null) {
tfChrome = new TextField(state.getExecutableChrome());
tfChrome.setPrefColumnCount(25);
}
return tfChrome;
}
public Button getBtSkadiLog() {
if (btSkadiLog == null) {
btSkadiLog = new Button("Open Skadi log");
btSkadiLog.setOnAction(event -> {
try {
Desktop.getDesktop().open(new File(PersistenceHandler.PERSISTENCE_DIRECTORY + "skadi.log"));
} catch (final Exception e) {
LOGGER.error("settings dialog: open log failed: ", e);
}
});
}
return btSkadiLog;
}
public VBox getBoxSkadiLog() {
if (boxSkadiLog == null) {
boxSkadiLog = new VBox(10, getBtSkadiLog());
}
return boxSkadiLog;
}
public Label getLbAuthUser() {
if (lbAuthUser == null) {
lbAuthUser = new Label("Authorized for user: ");
}
return lbAuthUser;
}
public ProgressIndicator getPi() {
if (pi == null) {
pi = new ProgressIndicator();
pi.setPrefSize(16, 16);
pi.setMaxSize(16, 16);
pi.setMinSize(16, 16);
}
return pi;
}
public Label getValueAuthUser() {
if (valueAuthUser == null) {
valueAuthUser = new Label("", getPi());
runCheckAuthService();
}
return valueAuthUser;
}
private void runCheckAuthService() {
final CheckAuthService service = new CheckAuthService();
service.setOnSucceeded(event -> {
final RootBox result = (RootBox) event.getSource().getValue();
if (result.getToken().isValid()) {
valueAuthUser.setText(result.getToken().getUserName());
} else {
LOGGER.warn("invalid token response: " + result.toString());
valueAuthUser.setText("none/invalid token");
}
valueAuthUser.setGraphic(null);
});
service.setOnFailed(event -> {
valueAuthUser.setText("failed to check auth. see log for details");
valueAuthUser.setGraphic(null);
});
service.start();
}
public Button getBtChangeAuth() {
if (btChangeAuth == null) {
btChangeAuth = new Button("Change Authorization");
btChangeAuth.setOnAction(event -> {
final AuthorizationDialog authDialog = new AuthorizationDialog();
authDialog.initModality(Modality.APPLICATION_MODAL);
authDialog.initOwner(getOwner());
final Optional<String> result = authDialog.showAndWait();
if (result.isPresent()) {
if (result.get() != null && !result.get().isEmpty()) {
state.setAuthToken(result.get());
persistenceHandler.saveState(state);
TwitchUtil.init(result.get());
runCheckAuthService();
}
}
});
}
return btChangeAuth;
}
public GridPane getContentPane() {
if (contentPane == null) {
contentPane = new GridPane();
contentPane.setHgap(10);
contentPane.setVgap(10);
contentPane.add(getLbLivestreamer(), 0, 0);
contentPane.add(getTfLivestreamer(), 1, 0);
if (SystemUtils.IS_OS_WINDOWS) {
contentPane.add(getBtLivestreamerCfg(), 2, 0);
}
contentPane.add(getLbChrome(), 0, 1);
contentPane.add(getTfChrome(), 1, 1);
contentPane.add(new Separator(), 0, 2, 3, 1);
contentPane.add(getCbShowNotifications(), 0, 3);
contentPane.add(getCbMinimizeToTray(), 0, 4);
contentPane.add(getCbDarkTheme(), 0, 5);
contentPane.add(new Separator(), 0, 6, 3, 1);
contentPane.add(getLbAuthUser(), 0, 7);
contentPane.add(getValueAuthUser(), 1, 7);
contentPane.add(getBtChangeAuth(), 2, 7);
contentPane.add(new Separator(), 0, 8, 3, 1);
contentPane.add(getBoxSkadiLog(), 0, 9);
}
return contentPane;
}
}