package gui.visualgraph;

import com.mxgraph.layout.hierarchical.mxHierarchicalLayout;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.view.mxGraph;

import javax.swing.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Patrick Petrovic
 *
 *         Panel used to display the visual graph.
 */
public class VisualGraphPanel extends JPanel {
    private List<UIBasicBlock> basicBlocks;
    private List<UIEdge> edges;
    private mxGraphComponent graphComponent;
    private JButton jumpToAction;
    private JButton graphExport;
    private mxGraph graph;
    private JLayeredPane buttonPane;

    /**
     * Creates a new {@code VisualGraphPanel}.
     */
    public VisualGraphPanel() {
        this.basicBlocks = new ArrayList<>();
        this.edges = new ArrayList<>();
        this.graph = new RestrictedMxGraph();

        // TODO: Make these buttons look nice
        // TODO: Add listeners to buttons
        // TODO: Find a replacement for GlassPane to make buttons visible
        jumpToAction = new JButton("Jump to Action");
        graphExport = new JButton("Export Graph");
    }

    /**
     * Inserts a given {@code UIBasicBlock} which will be rendered when {@code renderGraph()} is called.
     *
     * @param block
     *         the block to be added
     */
    public void insertBasicBlock(UIBasicBlock block) {
        basicBlocks.add(block);
    }

    /**
     * Inserts a given {@code UIEdge} which will be rendered when {@code renderGraph()} is called.
     *
     * @param edge
     *         the edge to be added
     */
    public void insertEdge(UIEdge edge) {
        edges.add(edge);
    }

    /**
     * Renders all previously inserted blocks and edges.
     *
     * @param applyLayout
     *         If {@code true}, the auto-layouter is called after inserting all parent blocks. Used on first render.
     */
    public void renderGraph(boolean applyLayout) {
        graph.getModel().beginUpdate();

        for (UIBasicBlock block : basicBlocks) {
            block.render();
        }

        for (UIEdge edge : edges) {
            edge.render();
        }

        // Apply layout before rendering child blocks, so that the layouter doesn't mess with them.
        if (applyLayout) {
            autoLayout();
        }

        for (UIBasicBlock block : basicBlocks) {
            block.renderChildren();
        }

        graph.getModel().endUpdate();
    }

    /**
     * Makes the currently shown graph invisible and deletes it.
     */
    public void deleteGraph() {
        initialGraphState();
    }

    /**
     * Increases the graph's zoom level.
     */
    public void zoomIn() {
        graphComponent.zoomIn();
    }

    /**
     * Decreases the graph's zoom level.
     */
    public void zoomOut() {
        graphComponent.zoomIn();
    }

    /**
     * Applies the auto-layouter on the graph and adds the graph component to this panel to make it visible.
     */
    public void autoLayout() {
        new mxHierarchicalLayout(graph).execute(graph.getDefaultParent());
        graphComponent = new mxGraphComponent(graph);
        graphComponent.setVisible(true);
        graphComponent.doLayout();
        add(graphComponent);
    }

    /**
     * Returns a list of {@code BasicBlock}s in the graph.
     *
     * @return list of {@code BasicBlock}s
     */
    public List<UIBasicBlock> getBasicBlocks() {
        return basicBlocks;
    }

    /**
     * Returns this panel's {@code mxGraph}.
     *
     * @return {@code mxGraph}
     */
    public mxGraph getMxGraph() {
        return graph;
    }

    private void initialGraphState() {
        basicBlocks = new ArrayList<>();
        edges = new ArrayList<>();
        graph = new RestrictedMxGraph();
        remove(graphComponent);
        graphComponent = null;
    }
}

@@ -2852,382 +2852,237 @@
   * 
-Applies the auto-layouter on the g
+Sets the %7B@code VisualG
 raph
- and adds the graph component to this panel to make it visible.
+Panel%7D's activation state
 %0A     *
-/
 %0A    
-public void autoLayout() %7B%0A        new mxHierarchicalLayout(graph).execute(graph.getDefaultParent());%0A        graphComponent = new mxGraphComponent(graph);%0A        graphComponent.setVisible(true);%0A        graphComponent.doLayout();%0A        add(graphCompon
+ * @param activated%0A     *         Iff %7B@code true%7D, user interaction is allowed.%0A     */%0A    public void setActivated(boolean activated) %7B%0A        // TODO implem
 ent
-);
 %0A   
@@ -3452,24 +3452,297 @@
 aph;%0A    %7D%0A%0A
+    private void autoLayout() %7B%0A        new mxHierarchicalLayout(graph).execute(graph.getDefaultParent());%0A        graphComponent = new mxGraphComponent(graph);%0A        graphComponent.setVisible(true);%0A        graphComponent.doLayout();%0A        add(graphComponent);%0A    %7D%0A%0A
     private 

Add missing method to VisualGraphPanel and make autoLayout() private