package SW9.controllers;

import SW9.HUPPAAL;
import SW9.abstractions.Component;
import SW9.abstractions.Query;
import SW9.abstractions.QueryState;
import SW9.backend.BackendException;
import SW9.backend.UPPAALDriver;
import SW9.presentations.QueryPresentation;
import SW9.utility.helpers.DropShadowHelper;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXRippler;
import com.sun.javaws.exceptions.InvalidArgumentException;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.collections.ListChangeListener;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.util.Duration;

import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;

public class QueryPaneController implements Initializable {

    public Label toolbarTitle;
    public JFXButton addQueryButton;
    public AnchorPane toolbar;
    public JFXRippler runAllQueriesButton;
    public JFXRippler clearAllQueriesButton;
    public VBox queriesList;
    public StackPane root;
    public ScrollPane scrollPane;

    private Map<Query, QueryPresentation> queryPresentationMap = new HashMap<>();

    @Override
    public void initialize(final URL location, final ResourceBundle resources) {

        // We need to register these event manually this way because JFXButton overrides onPressed and onRelease to handle rippler effect
        addQueryButton.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> addQueryButtonPressed());
        addQueryButton.addEventHandler(MouseEvent.MOUSE_RELEASED, event -> addQueryButtonReleased());

        HUPPAAL.getProject().getQueries().addListener(new ListChangeListener<Query>() {
            @Override
            public void onChanged(final Change<? extends Query> c) {
                while (c.next()) {
                    for (final Query removeQuery : c.getRemoved()) {
                        queriesList.getChildren().remove(queryPresentationMap.get(removeQuery));
                        queryPresentationMap.remove(removeQuery);
                    }

                    for (final Query newQuery : c.getAddedSubList()) {
                        final QueryPresentation newQueryPresentation = new QueryPresentation(newQuery);
                        queryPresentationMap.put(newQuery, newQueryPresentation);
                        queriesList.getChildren().add(newQueryPresentation);
                    }
                }
            }
        });

        for (final Query newQuery : HUPPAAL.getProject().getQueries()) {
            queriesList.getChildren().add(new QueryPresentation(newQuery));
        }
    }

    @FXML
    private void addQueryButtonClicked() {
        HUPPAAL.getProject().getQueries().add(new Query("", "", QueryState.UNKNOWN));
    }

    @FXML
    private void addQueryButtonPressed() {
        addQueryButton.setEffect(DropShadowHelper.generateElevationShadow(12));
    }

    @FXML
    private void addQueryButtonReleased() {
        addQueryButton.setEffect(DropShadowHelper.generateElevationShadow(6));
    }

    @FXML
    private void runAllQueriesButtonClicked() {
        final int interval = 50;
        final int[] counter = {0};

        final Component mainComponent = HUPPAAL.getProject().getMainComponent();

        if (mainComponent == null) {
            return; // We cannot generate a UPPAAL file without a main component
        }

        HUPPAAL.getProject().getQueries().forEach(query -> {
            // Reset the status of the query
            query.setQueryState(QueryState.UNKNOWN);
            query.setQueryState(QueryState.RUNNING);

            final Timeline timeline = new Timeline(new KeyFrame(
                    Duration.millis(1 + counter[0] * interval),
                    ae -> {
                        try {
                            UPPAALDriver.buildHUPPAALDocument();
                            UPPAALDriver.verify(query.getQuery(),
                                    aBoolean -> {
                                        if (aBoolean) {
                                            query.setQueryState(QueryState.SUCCESSFUL);
                                        } else {
                                            query.setQueryState(QueryState.ERROR);
                                        }
                                    },
                                    e -> {
                                        query.setQueryState(QueryState.SYNTAX_ERROR);
                                }
                            ).start();
                        } catch (InvalidArgumentException | BackendException e) {
                            e.printStackTrace();
                        }
                    }
            ));
            timeline.play();

            counter[0]++;
        });
    }

    @FXML
    private void clearAllQueriesButtonClicked() {
        HUPPAAL.getProject().getQueries().forEach(query -> query.setQueryState(QueryState.UNKNOWN));
    }
}

@@ -43,43 +43,8 @@
 AL;%0A
-import SW9.abstractions.Component;%0A
 impo
@@ -70,16 +70,16 @@
 .Query;%0A
+
 import S
@@ -407,76 +407,8 @@
 on;%0A
-import javafx.animation.KeyFrame;%0Aimport javafx.animation.Timeline;%0A
 impo
@@ -694,24 +694,24 @@
 .StackPane;%0A
+
 import javaf
@@ -734,37 +734,8 @@
 Box;
-%0Aimport javafx.util.Duration;
 %0A%0Aim
@@ -3218,288 +3218,8 @@
 ) %7B%0A
-        final int interval = 50;%0A        final int%5B%5D counter = %7B0%7D;%0A%0A        final Component mainComponent = HUPPAAL.getProject().getMainComponent();%0A%0A        if (mainComponent == null) %7B%0A            return; // We cannot generate a UPPAAL file without a main component%0A        %7D%0A%0A
     
@@ -3443,192 +3443,14 @@
     
-final Timeline timeline = new Timeline(new KeyFrame(%0A                    Duration.millis(1 + counter%5B0%5D * interval),%0A                    ae -%3E %7B%0A                        try %7B%0A         
+try %7B%0A
     
@@ -3453,35 +3453,32 @@
                 
-   
 UPPAALDriver.bui
@@ -3510,36 +3510,24 @@
             
-         
-   
 UPPAALDriver
@@ -3576,28 +3576,16 @@
         
-        
-    
 aBoolean
@@ -3586,36 +3586,24 @@
 oolean -%3E %7B%0A
-            
             
@@ -3662,36 +3662,24 @@
             
-       
-     
 query.setQue
@@ -3738,28 +3738,16 @@
         
-            
 %7D else %7B
@@ -3775,36 +3775,24 @@
             
-      
-      
 query.setQue
@@ -3846,34 +3846,18 @@
         
-            %7D%0A    
+%7D%0A
         
@@ -3876,27 +3876,11 @@
     
-        %7D,%0A        
+%7D,%0A
     
@@ -3903,31 +3903,15 @@
     
-    
 e -%3E %7B%0A
-            
     
@@ -4004,32 +4004,18 @@
         
-        %7D%0A      
+%7D%0A
         
@@ -4022,22 +4022,16 @@
         
-      
 ).start(
@@ -4029,36 +4029,24 @@
  ).start();%0A
-            
             
@@ -4119,28 +4119,16 @@
         
-     
-       
 e.printS
@@ -4156,115 +4156,9 @@
     
-            %7D%0A                    %7D%0A            ));%0A            timeline.play();%0A%0A            counter%5B0%5D++;
+%7D
 %0A   

Refactor the query pane to now wait in between running queries