<commit_before>/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package jace;

import com.sun.glass.ui.Application;
import jace.core.Card;
import jace.core.Computer;
import jace.core.Utility;
import jace.library.MediaCache;
import jace.library.MediaConsumer;
import jace.library.MediaConsumerParent;
import jace.library.MediaEntry;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.beans.binding.NumberBinding;
import javafx.beans.binding.When;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.ImageView;
import javafx.scene.input.DragEvent;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.StringConverter;

/**
 *
 * @author blurry
 */
public class JaceUIController {

    @FXML
    private URL location;

    @FXML
    private AnchorPane rootPane;

    @FXML
    private StackPane stackPane;

    @FXML
    private HBox notificationBox;

    @FXML
    private ImageView appleScreen;

    @FXML
    private BorderPane controlOverlay;

    @FXML
    private Slider speedSlider;

    Computer computer;

    private final BooleanProperty aspectRatioCorrectionEnabled = new SimpleBooleanProperty(false);

    @FXML
    void initialize() {
        assert rootPane != null : "fx:id=\"rootPane\" was not injected: check your FXML file 'JaceUI.fxml'.";
        assert stackPane != null : "fx:id=\"stackPane\" was not injected: check your FXML file 'JaceUI.fxml'.";
        assert notificationBox != null : "fx:id=\"notificationBox\" was not injected: check your FXML file 'JaceUI.fxml'.";
        assert appleScreen != null : "fx:id=\"appleScreen\" was not injected: check your FXML file 'JaceUI.fxml'.";
        controlOverlay.setVisible(false);
        NumberBinding aspectCorrectedWidth = rootPane.heightProperty().multiply(3.0).divide(2.0);
        NumberBinding width = new When(
                aspectRatioCorrectionEnabled.and(aspectCorrectedWidth.lessThan(rootPane.widthProperty()))
        ).then(aspectCorrectedWidth).otherwise(rootPane.widthProperty());
        appleScreen.fitWidthProperty().bind(width);
        appleScreen.fitHeightProperty().bind(rootPane.heightProperty());
        appleScreen.setVisible(false);
        rootPane.setOnDragEntered(this::processDragEnteredEvent);
        rootPane.setOnDragExited(this::processDragExitedEvent);
        rootPane.setBackground(new Background(new BackgroundFill(Color.BLACK, null, null)));
        rootPane.setOnMouseEntered(this::showControlOverlay);
        rootPane.setOnMouseExited(this::hideControlOverlay);
    }

    private void showControlOverlay(MouseEvent evt) {
        if (!evt.isPrimaryButtonDown() && !evt.isSecondaryButtonDown()) {
            controlOverlay.setVisible(true);
        }
    }

    private void hideControlOverlay(MouseEvent evt) {
        controlOverlay.setVisible(false);
    }
    
    private double convertSpeedToRatio(Double setting) {
        if (setting < 1.0) {
            return 0.5;
        } else if (setting == 1.0) {
            return 1.0;
        } else if (setting >= 10) {
            return Double.MAX_VALUE;
        } else {
            double val = Math.pow(2.0, (setting - 1.0)/1.5);
            val = Math.floor(val * 2.0) / 2.0;
            if (val > 2.0) {
                val = Math.floor(val);
            }
            return val;
        }
    }

    private void connectControls(Stage primaryStage) {
        connectButtons(controlOverlay);
        if (computer.getKeyboard() != null) {
            EventHandler<KeyEvent> keyboardHandler = computer.getKeyboard().getListener();
            primaryStage.setOnShowing(evt -> computer.getKeyboard().resetState());
            rootPane.setOnKeyPressed(keyboardHandler);
            rootPane.setOnKeyReleased(keyboardHandler);
            rootPane.setFocusTraversable(true);
        }
        speedSlider.setValue(1.0);
        speedSlider.setMinorTickCount(0);
        speedSlider.setMajorTickUnit(1);
        speedSlider.setLabelFormatter(new StringConverter<Double>() {
            @Override
            public String toString(Double val) {
                if (val < 1.0) {
                    return "Half";
                } else if (val >= 10.0) {
                    return "∞";
                }
                double v = convertSpeedToRatio(val);
                if (v != Math.floor(v)) {
                    return String.valueOf(v) + "x";
                } else {
                    return String.valueOf((int) v) + "x";                    
                }
            }

            @Override
            public Double fromString(String string) {
                return 1.0;
            }
        });
        speedSlider.valueProperty().addListener((val,oldValue,newValue) -> setSpeed(newValue.doubleValue()));
    }
    
    private void connectButtons(Node n) {
        if (n instanceof Button) {
            Button button = (Button) n;
            Runnable action = Utility.getNamedInvokableAction(button.getText());
            button.setOnMouseClicked(evt -> action.run());
        } else if (n instanceof Parent) {
            for (Node child : ((Parent) n).getChildrenUnmodifiable()) {
                connectButtons(child);
            }
        }
    }
    
    private void setSpeed(double speed) {
        double speedRatio = convertSpeedToRatio(speed);
        if (speedRatio > 100.0) {
            Emulator.computer.getMotherboard().maxspeed = true;
        } else {
            Emulator.computer.getMotherboard().maxspeed = false;
            Emulator.computer.getMotherboard().speedRatio = (int) (speedRatio * 100);
        }
        Emulator.computer.getMotherboard().reconfigure();
    }

    public void toggleAspectRatio() {
        setAspectRatioEnabled(aspectRatioCorrectionEnabled.not().get());
    }

    public void setAspectRatioEnabled(boolean enabled) {<commit_msg>Speed tweaks for 40x and infinite speeds -- noticably faster now<commit_after>/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package jace;

import com.sun.glass.ui.Application;
import jace.core.Card;
import jace.core.Computer;
import jace.core.Motherboard;
import jace.core.Utility;
import jace.library.MediaCache;
import jace.library.MediaConsumer;
import jace.library.MediaConsumerParent;
import jace.library.MediaEntry;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.beans.binding.NumberBinding;
import javafx.beans.binding.When;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.ImageView;
import javafx.scene.input.DragEvent;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.StringConverter;

/**
 *
 * @author blurry
 */
public class JaceUIController {

    @FXML
    private URL location;

    @FXML
    private AnchorPane rootPane;

    @FXML
    private StackPane stackPane;

    @FXML
    private HBox notificationBox;

    @FXML
    private ImageView appleScreen;

    @FXML
    private BorderPane controlOverlay;

    @FXML
    private Slider speedSlider;

    Computer computer;

    private final BooleanProperty aspectRatioCorrectionEnabled = new SimpleBooleanProperty(false);

    @FXML
    void initialize() {
        assert rootPane != null : "fx:id=\"rootPane\" was not injected: check your FXML file 'JaceUI.fxml'.";
        assert stackPane != null : "fx:id=\"stackPane\" was not injected: check your FXML file 'JaceUI.fxml'.";
        assert notificationBox != null : "fx:id=\"notificationBox\" was not injected: check your FXML file 'JaceUI.fxml'.";
        assert appleScreen != null : "fx:id=\"appleScreen\" was not injected: check your FXML file 'JaceUI.fxml'.";
        controlOverlay.setVisible(false);
        NumberBinding aspectCorrectedWidth = rootPane.heightProperty().multiply(3.0).divide(2.0);
        NumberBinding width = new When(
                aspectRatioCorrectionEnabled.and(aspectCorrectedWidth.lessThan(rootPane.widthProperty()))
        ).then(aspectCorrectedWidth).otherwise(rootPane.widthProperty());
        appleScreen.fitWidthProperty().bind(width);
        appleScreen.fitHeightProperty().bind(rootPane.heightProperty());
        appleScreen.setVisible(false);
        rootPane.setOnDragEntered(this::processDragEnteredEvent);
        rootPane.setOnDragExited(this::processDragExitedEvent);
        rootPane.setBackground(new Background(new BackgroundFill(Color.BLACK, null, null)));
        rootPane.setOnMouseEntered(this::showControlOverlay);
        rootPane.setOnMouseExited(this::hideControlOverlay);
    }

    private void showControlOverlay(MouseEvent evt) {
        if (!evt.isPrimaryButtonDown() && !evt.isSecondaryButtonDown()) {
            controlOverlay.setVisible(true);
        }
    }

    private void hideControlOverlay(MouseEvent evt) {
        controlOverlay.setVisible(false);
    }

    private double convertSpeedToRatio(Double setting) {
        if (setting < 1.0) {
            return 0.5;
        } else if (setting == 1.0) {
            return 1.0;
        } else if (setting >= 10) {
            return Double.MAX_VALUE;
        } else {
            double val = Math.pow(2.0, (setting - 1.0) / 1.5);
            val = Math.floor(val * 2.0) / 2.0;
            if (val > 2.0) {
                val = Math.floor(val);
            }
            return val;
        }
    }

    private void connectControls(Stage primaryStage) {
        connectButtons(controlOverlay);
        if (computer.getKeyboard() != null) {
            EventHandler<KeyEvent> keyboardHandler = computer.getKeyboard().getListener();
            primaryStage.setOnShowing(evt -> computer.getKeyboard().resetState());
            rootPane.setOnKeyPressed(keyboardHandler);
            rootPane.setOnKeyReleased(keyboardHandler);
            rootPane.setFocusTraversable(true);
        }
        speedSlider.setValue(1.0);
        speedSlider.setMinorTickCount(0);
        speedSlider.setMajorTickUnit(1);
        speedSlider.setLabelFormatter(new StringConverter<Double>() {
            @Override
            public String toString(Double val) {
                if (val < 1.0) {
                    return "Half";
                } else if (val >= 10.0) {
                    return "∞";
                }
                double v = convertSpeedToRatio(val);
                if (v != Math.floor(v)) {
                    return String.valueOf(v) + "x";
                } else {
                    return String.valueOf((int) v) + "x";
                }
            }

            @Override
            public Double fromString(String string) {
                return 1.0;
            }
        });
        speedSlider.valueProperty().addListener((val, oldValue, newValue) -> setSpeed(newValue.doubleValue()));
    }

    private void connectButtons(Node n) {
        if (n instanceof Button) {
            Button button = (Button) n;
            Runnable action = Utility.getNamedInvokableAction(button.getText());
            button.setOnMouseClicked(evt -> action.run());
        } else if (n instanceof Parent) {
            for (Node child : ((Parent) n).getChildrenUnmodifiable()) {
                connectButtons(child);
            }
        }
    }

    private void setSpeed(double speed) {
        double speedRatio = convertSpeedToRatio(speed);
        if (speedRatio > 100.0) {
            Emulator.computer.getMotherboard().maxspeed = true;
            Motherboard.cpuPerClock = 3;
        } else {
            if (speedRatio > 25) {
                Motherboard.cpuPerClock = 2;
            } else {
                Motherboard.cpuPerClock = 1;
            }
            Emulator.computer.getMotherboard().maxspeed = false;
            Emulator.computer.getMotherboard().speedRatio = (int) (speedRatio * 100);
        }
        Emulator.computer.getMotherboard().reconfigure();
    }

    public void toggleAspectRatio() {
        setAspectRatioEnabled(aspectRatioCorrectionEnabled.not().get());
    }

    public void setAspectRatioEnabled(boolean enabled) {
{'fraction_non_alphanumeric': 0.10567184334908845, 'fraction_numerical': 0.006414584740040513, 'mean_word_length': 2.7976923076923077, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 10}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3834990', 'n_tokens_mistral': 4251, 'n_tokens_neox': 4157, 'n_words': 864}