<commit_before>package tugraz.ivis.parcoord.chart;

import javafx.beans.value.ChangeListener;
import javafx.geometry.Insets;
import javafx.scene.chart.NumberAxis;
import javafx.scene.control.Button;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import org.controlsfx.control.RangeSlider;

import java.util.Map;

public class ParallelCoordinatesAxis {
    private int id;
    private int axisIndex;
    private NumberAxis axis;
    private boolean inverted = false;
    private String label;
    private HBox labelBox;
    private RangeSlider filterSlider;
    private double filterHigh;
    private double filterLow;
    private Button btnInvert;
    private Button btnLeft;
    private Button btnRight;

    /**
     * A basic constructor which allows for initial creation of the object
     *
     * @param axisIndex
     */
    public ParallelCoordinatesAxis(int axisIndex) {
        this.id = axisIndex;
        this.axisIndex = axisIndex;
    }

    public ParallelCoordinatesAxis(int axisIndex, NumberAxis axis, String label, HBox labelBox, RangeSlider filterSlider, Button btnInvert, Button btnLeft, Button btnRight) {
        this(axisIndex);
        initialize(axis, label, labelBox, filterSlider, btnInvert, btnLeft, btnRight);
    }

    /**
     * supports the basic constructor by setting the values AFTER already creating the axis
     * for now, this is the approach which is used when calling bindAxes in the chart
     * TODO moveAxes: not sure if this is needed or can be replaced when refactoring for performance
     *
     * @param axis
     * @param label
     * @param labelBox
     * @param filterSlider
     * @param btnInvert
     * @param btnLeft
     * @param btnRight
     */
    public void initialize(NumberAxis axis, String label, HBox labelBox, RangeSlider filterSlider, Button btnInvert, Button btnLeft, Button btnRight) {
        this.axis = axis;
        this.label = label;
        this.labelBox = labelBox;
        this.filterSlider = filterSlider;

        if (filterSlider != null) {
            filterHigh = filterSlider.getHighValue();
            filterLow = filterSlider.getLowValue();
        }

        this.btnInvert = btnInvert;
        this.btnLeft = btnLeft;
        this.btnRight = btnRight;

        setTickLabelFormatter();
    }

    public void registerDragAndDropListener(ParallelCoordinatesChart chart, ParallelCoordinatesChart.DragAndDropLabel labelDragAndDrop) {
        /* === set filter slider drag and drops === */
        filterSlider.setOnDragDetected(event -> {
            /* drag was detected, start a drag-and-drop gesture*/
            /* allow any transfer mode */
            Dragboard db = axis.startDragAndDrop(TransferMode.MOVE);

            /* Put a string on a dragboard */
            ClipboardContent content = new ClipboardContent();
            content.putString(axisIndex + "");
            db.setContent(content);
            System.out.println("drag started from:" + axisIndex);

            highlightAxis(true);
            //  event.consume();
        });

        // this is needed to register which transfer modes are allowed
        filterSlider.setOnDragOver(event -> {
            /* data is dragged over the target */
            /* if it has a string data */
            if (event.getDragboard().hasString()) {
                /* allow for both copying and moving, whatever user chooses */
                event.acceptTransferModes(TransferMode.MOVE);
            }

            // event.consume();
        });


        filterSlider.setOnDragEntered(event -> {
            highlightAxis(true);
        });

        filterSlider.setOnDragExited(event -> {
            String oldAxisAsString = event.getDragboard().getString();
            if (event.getDragboard().hasString() && oldAxisAsString != null) {
                System.out.println("drag exited at:" + axisIndex + " from " + oldAxisAsString);

                int oldAxisIndex = Integer.parseInt(oldAxisAsString);
                if (oldAxisIndex != axisIndex) {
                    highlightAxis(false);
                }
            }

            // event.consume();
        });

        filterSlider.setOnDragDropped(event -> {
            /* data dropped */
            /* if there is a string data on dragboard, read it and use it */
            boolean success = false;
            String oldAxisAsString = event.getDragboard().getString();
            if (event.getDragboard().hasString() && oldAxisAsString != null) {
                int oldAxisIndex = Integer.parseInt(oldAxisAsString);
                highlightAxis(false);

                chart.getAxisByIndex(oldAxisIndex).highlightAxis(false);
                success = true;
                System.out.println("drag dropped at:" + axisIndex + " from " + oldAxisAsString);


                if (oldAxisIndex != axisIndex) {
                    chart.swapAxes(oldAxisIndex, axisIndex);
                }
            }


            /* let the source know whether the string was successfully
             * transferred and used */
            event.setDropCompleted(success);
            //  event.consume();
        });

        labelDragAndDrop.setOnDragOver(event -> {
            /* data is dragged over the target */
            /* if it has a string data */
            if (event.getDragboard().hasString()) {
                /* allow for both copying and moving, whatever user chooses */
                event.acceptTransferModes(TransferMode.MOVE);
            }

            // event.consume();
        });

        /* ==== set label drag and drops === */
        labelDragAndDrop.setOnDragEntered(event -> {
            labelDragAndDrop.show(true);
        });

        labelDragAndDrop.setOnDragExited(event -> {
            labelDragAndDrop.show(false);
        });


        labelDragAndDrop.setOnDragDropped(event -> {
          /* data dropped */<commit_msg>fixed drag and drop<commit_after>package tugraz.ivis.parcoord.chart;

import javafx.beans.value.ChangeListener;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.chart.NumberAxis;
import javafx.scene.control.Button;
import javafx.scene.input.*;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import org.controlsfx.control.RangeSlider;

import java.util.Map;

public class ParallelCoordinatesAxis {
    private int id;
    private int axisIndex;
    private NumberAxis axis;
    private boolean inverted = false;
    private String label;
    private HBox labelBox;
    private RangeSlider filterSlider;
    private double filterHigh;
    private double filterLow;
    private Button btnInvert;
    private Button btnLeft;
    private Button btnRight;

    /**
     * A basic constructor which allows for initial creation of the object
     *
     * @param axisIndex
     */
    public ParallelCoordinatesAxis(int axisIndex) {
        this.id = axisIndex;
        this.axisIndex = axisIndex;
    }

    public ParallelCoordinatesAxis(int axisIndex, NumberAxis axis, String label, HBox labelBox, RangeSlider filterSlider, Button btnInvert, Button btnLeft, Button btnRight) {
        this(axisIndex);
        initialize(axis, label, labelBox, filterSlider, btnInvert, btnLeft, btnRight);
    }

    /**
     * supports the basic constructor by setting the values AFTER already creating the axis
     * for now, this is the approach which is used when calling bindAxes in the chart
     * TODO moveAxes: not sure if this is needed or can be replaced when refactoring for performance
     *
     * @param axis
     * @param label
     * @param labelBox
     * @param filterSlider
     * @param btnInvert
     * @param btnLeft
     * @param btnRight
     */
    public void initialize(NumberAxis axis, String label, HBox labelBox, RangeSlider filterSlider, Button btnInvert, Button btnLeft, Button btnRight) {
        this.axis = axis;
        this.label = label;
        this.labelBox = labelBox;
        this.filterSlider = filterSlider;

        if (filterSlider != null) {
            filterHigh = filterSlider.getHighValue();
            filterLow = filterSlider.getLowValue();
        }

        this.btnInvert = btnInvert;
        this.btnLeft = btnLeft;
        this.btnRight = btnRight;

        setTickLabelFormatter();
    }

    public void registerDragAndDropListener(ParallelCoordinatesChart chart, ParallelCoordinatesChart.DragAndDropLabel labelDragAndDrop) {
        /* === set filter slider drag and drops === */
        EventHandler<MouseEvent> handlerDragDetected = event -> {
            /* drag was detected, start a drag-and-drop gesture*/
            /* allow any transfer mode */
            Dragboard db = axis.startDragAndDrop(TransferMode.MOVE);

            /* Put a string on a dragboard */
            ClipboardContent content = new ClipboardContent();
            content.putString(axisIndex + "");
            db.setContent(content);
            //System.out.println("drag started from:" + axisIndex);

            ParallelCoordinatesAxis.this.highlightAxis(true);
            //  event.consume();
        };
        btnInvert.setOnDragDetected(handlerDragDetected);
        btnLeft.setOnDragDetected(handlerDragDetected);
        btnRight.setOnDragDetected(handlerDragDetected);
        labelBox.setOnDragDetected(handlerDragDetected);

        // this is needed to register which transfer modes are allowed
        EventHandler<DragEvent> handlerDragOver = event -> {
            /* data is dragged over the target */
            /* if it has a string data */
            if (event.getDragboard().hasString()) {
            /* allow for both copying and moving, whatever user chooses */
                event.acceptTransferModes(TransferMode.MOVE);
            }

            // event.consume();
        };

        btnInvert.setOnDragOver(handlerDragOver);
        btnLeft.setOnDragOver(handlerDragOver);
        btnRight.setOnDragOver(handlerDragOver);
        labelBox.setOnDragOver(handlerDragOver);
        filterSlider.setOnDragOver(handlerDragOver);

        EventHandler<DragEvent> handlerDragEntered = event -> ParallelCoordinatesAxis.this.highlightAxis(true);

        btnInvert.setOnDragEntered(handlerDragEntered);
        btnLeft.setOnDragEntered(handlerDragEntered);
        btnRight.setOnDragEntered(handlerDragEntered);
        labelBox.setOnDragEntered(handlerDragEntered);
        filterSlider.setOnDragEntered(handlerDragEntered);


        EventHandler<DragEvent> handlerDragExited = event -> {
            String oldAxisAsString = event.getDragboard().getString();
            if (event.getDragboard().hasString() && oldAxisAsString != null) {
                // System.out.println("drag exited at:" + axisIndex + " from " + oldAxisAsString);

                int oldAxisIndex = Integer.parseInt(oldAxisAsString);
                if (oldAxisIndex != axisIndex) {
                    ParallelCoordinatesAxis.this.highlightAxis(false);
                }
            }

            // event.consume();
        };

        btnInvert.setOnDragExited(handlerDragExited);
        btnLeft.setOnDragExited(handlerDragExited);
        btnRight.setOnDragExited(handlerDragExited);
        labelBox.setOnDragExited(handlerDragExited);
        filterSlider.setOnDragExited(handlerDragExited);

        EventHandler<DragEvent> dropHandlerAxis = event -> {
        /* data dropped */
        /* if there is a string data on dragboard, read it and use it */
            boolean success = false;
            String oldAxisAsString = event.getDragboard().getString();
            if (event.getDragboard().hasString() && oldAxisAsString != null) {
                int oldAxisIndex = Integer.parseInt(oldAxisAsString);
                ParallelCoordinatesAxis.this.highlightAxis(false);

                chart.getAxisByIndex(oldAxisIndex).highlightAxis(false);
                success = true;
                //  System.out.println("drag dropped at:" + axisIndex + " from " + oldAxisAsString);


                if (oldAxisIndex != axisIndex) {
                    chart.swapAxes(oldAxisIndex, axisIndex);
                }
            }


        /* let the source know whether the string was successfully
         * transferred and used */
            event.setDropCompleted(success);
            //  event.consume();
        };

        filterSlider.setOnDragDropped(dropHandlerAxis);
        labelBox.setOnDragDropped(dropHandlerAxis);
        btnInvert.setOnDragDropped(dropHandlerAxis);
        btnLeft.setOnDragDropped(dropHandlerAxis);
        btnRight.setOnDragDropped(dropHandlerAxis);

        /* ==== set label drag and drops === */
        labelDragAndDrop.setOnDragOver(event -> {
            /* data is dragged over the target */
            /* if it has a string data */
            if (event.getDragboard().hasString()) {
                /* allow for both copying and moving, whatever user chooses */
                event.acceptTransferModes(TransferMode.MOVE);
            }

            // event.consume();
        });

        labelDragAndDrop.setOnDragEntered(event -> {
            labelDragAndDrop.show(true);
        });

        labelDragAndDrop.setOnDragExited(event -> {
            labelDragAndDrop.show(false);
        });


        labelDragAndDrop.setOnDragDropped(event -> {
          /* data dropped */
{'fraction_non_alphanumeric': 0.09078956979037324, 'fraction_numerical': 0.0, 'mean_word_length': 2.3257226135535585, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '1216028', 'n_tokens_mistral': 3629, 'n_tokens_neox': 3547, 'n_words': 859}