package dc3.rugosa.plugin;

import docking.widgets.ScrollableTextArea;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.table.GTable;

import javax.swing.*;
import java.awt.*;

public class EmulatorForm {
    public JLabel status;
    public JButton runButton;
    public JButton stepOverButton;
    public JButton stepIntoButton;
    public JButton stepOutButton;
    public JPanel operandsTab;
    public JPanel registersTab;
    public JPanel memoryTab;
    public JPanel variablesTab;
    public JPanel functionArgumentsTab;
    public JPanel callHistoryTab;
    public JPanel actionsTab;
    public JPanel stdoutTab;
    public JSpinner traceDepth;
    public JSpinner callDepth;
    public GCheckBox followLoopsCheckBox;
    public JTextField memoryStart;
    public JSpinner memorySize;
    public JButton memoryExportButton;
    public JButton memoryLoadButton;
    public JLabel instruction;
    public JLabel functionSignature;
    public JSpinner numArgs;
    public ScrollableTextArea stdoutTextDump;
    public JButton stdoutExportButton;
    public JPanel mainPanel;
    public GTable operandsTable;
    public GCheckBox exhaustiveCheckBox;
    public GTable registersTable;
    public ScrollableTextArea memoryHexDump;
    public GTable variablesTable;
    public GTable functionArgumentsTable;
    public GTable callHistoryTable;
    public GTable memoryBlocksTable;
    public RugosaTabbedPane tabs;
    public GTable actionsFieldsTable;
    public GTable actionsSideTable;

    {
// GUI initializer generated by IntelliJ IDEA GUI Designer
// >>> IMPORTANT!! <<<
// DO NOT EDIT OR ADD ANY CODE HERE!
        $$$setupUI$$$();
    }

    /**
     * Method generated by IntelliJ IDEA GUI Designer
     * >>> IMPORTANT!! <<<
     * DO NOT edit this method OR call it in your code!
     *
     * @noinspection ALL
     */
    private void $$$setupUI$$$() {
        createUIComponents();
        mainPanel = new JPanel();
        mainPanel.setLayout(new BorderLayout(0, 0));
        final JPanel panel1 = new JPanel();
        panel1.setLayout(new BorderLayout(0, 0));
        mainPanel.add(panel1, BorderLayout.NORTH);
        final JPanel panel2 = new JPanel();
        panel2.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
        panel1.add(panel2, BorderLayout.CENTER);
        runButton = new JButton();
        runButton.setText("Run");
        runButton.setToolTipText("Emulate up to the current highlighted instruction");
        panel2.add(runButton);
        stepOverButton = new JButton();
        stepOverButton.setEnabled(false);
        stepOverButton.setText("Step Over");
        stepOverButton.setToolTipText("Emulate the next instruction");
        panel2.add(stepOverButton);
        stepIntoButton = new JButton();
        stepIntoButton.setEnabled(false);
        stepIntoButton.setText("Step Into");
        stepIntoButton.setToolTipText("Not Supported Yet");
        panel2.add(stepIntoButton);
        stepOutButton = new JButton();
        stepOutButton.setEnabled(false);
        stepOutButton.setText("Step Out");
        stepOutButton.setToolTipText("Not Supported Yet");
        panel2.add(stepOutButton);
        final JPanel panel3 = new JPanel();
        panel3.setLayout(new BorderLayout(0, 0));
        panel1.add(panel3, BorderLayout.NORTH);
        final JPanel panel4 = new JPanel();
        panel4.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
        panel3.add(panel4, BorderLayout.WEST);
        final JLabel label1 = new JLabel();
        label1.setText("Trace Depth");
        label1.setToolTipText("Number of levels of parent callers to emulate");
        panel4.add(label1);
        traceDepth.setToolTipText("Number of levels of parent callers to emulate");
        panel4.add(traceDepth);
        final JLabel label2 = new JLabel();
        label2.setText("Call Depth");
        label2.setToolTipText("Number of call levels deep to emulate");
        panel4.add(label2);
        callDepth.setToolTipText("Number of call levels deep to emulate");
        panel4.add(callDepth);
        final JPanel panel5 = new JPanel();
        panel5.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
        panel3.add(panel5, BorderLayout.EAST);
        exhaustiveCheckBox = new GCheckBox();
        exhaustiveCheckBox.setText("Exhaustive");
        exhaustiveCheckBox.setToolTipText("Whether to also follow loops for parent callers");
        exhaustiveCheckBox.putClientProperty("html.disable", Boolean.TRUE);
        panel5.add(exhaustiveCheckBox);
        followLoopsCheckBox = new GCheckBox();
        followLoopsCheckBox.setText("Follow Loops");
        followLoopsCheckBox.setToolTipText("Whether to emulate loops instead of forcing a downward path");
        followLoopsCheckBox.putClientProperty("html.disable", Boolean.TRUE);
        panel5.add(followLoopsCheckBox);
        instruction = new JLabel();
        instruction.setText("<instruction>");
        instruction.setToolTipText("Current instruction emulated up to.");
        panel1.add(instruction, BorderLayout.SOUTH);
        status = new JLabel();
        status.setText("<status>");
        mainPanel.add(status, BorderLayout.SOUTH);
        tabs.setTabLayoutPolicy(1);
        mainPanel.add(tabs, BorderLayout.CENTER);
        operandsTab = new JPanel();
        operandsTab.setLayout(new BorderLayout(0, 0));
        operandsTab.setToolTipText("Contents of the operands of the current instruction");
        tabs.addTab("Operands", operandsTab);
        final JScrollPane scrollPane1 = new JScrollPane();
        operandsTab.add(scrollPane1, BorderLayout.CENTER);
        operandsTable = new GTable();
        operandsTable.setAutoCreateRowSorter(true);
        operandsTable.setAutoResizeMode(4);
        operandsTable.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);
        scrollPane1.setViewportView(operandsTable);
        registersTab = new JPanel();
        registersTab.setLayout(new BorderLayout(0, 0));
        registersTab.setToolTipText("Content of the registers");
        tabs.addTab("Registers", registersTab);
        final JScrollPane scrollPane2 = new JScrollPane();
        registersTab.add(scrollPane2, BorderLayout.CENTER);
        registersTable = new GTable();
        registersTable.setAutoCreateRowSorter(true);
        registersTable.setAutoResizeMode(4);
        registersTable.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);
        scrollPane2.setViewportView(registersTable);
        memoryTab = new JPanel();
        memoryTab.setLayout(new BorderLayout(0, 0));
        memoryTab.setToolTipText("Contents of memory");
        tabs.addTab("Memory", memoryTab);
        final JPanel panel6 = new JPanel();
        panel6.setLayout(new BorderLayout(0, 0));
        memoryTab.add(panel6, BorderLayout.NORTH);
        final JPanel panel7 = new JPanel();
        panel7.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
        panel6.add(panel7, BorderLayout.WEST);
        final JLabel label3 = new JLabel();
        label3.setText("Start Address");
        panel7.add(label3);
        memoryStart = new JTextField();
        memoryStart.setPreferredSize(new Dimension(100, 30));
        memoryStart.setText("0x401000");
        panel7.add(memoryStart);
        final JLabel label4 = new JLabel();
        label4.setText("Size");
        panel7.add(label4);
        memorySize.setPreferredSize(new Dimension(90, 30));
        panel7.add(memorySize);
        memoryLoadButton = new JButton();
        memoryLoadButton.setText("Load");
        panel7.add(memoryLoadButton);
        final JPanel panel8 = new JPanel();
        panel8.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
        panel6.add(panel8, BorderLayout.EAST);
        memoryExportButton = new JButton();
        memoryExportButton.setText("Export");
        panel8.add(memoryExportButton);
        memoryTab.add(memoryHexDump, BorderLayout.CENTER);
        final JScrollPane scrollPane3 = new JScrollPane();
        scrollPane3.setPreferredSize(new Dimension(453, 100));
        memoryTab.add(scrollPane3, BorderLayout.SOUTH);
        memoryBlocksTable = new GTable();
        memoryBlocksTable.setAutoCreateRowSorter(true);
        memoryBlocksTable.setAutoResizeMode(4);
        memoryBlocksTable.setToolTipText("Currently mapped memory blocks");
        memoryBlocksTable.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);
        scrollPane3.setViewportView(memoryBlocksTable);
        variablesTab = new JPanel();
        variablesTab.setLayout(new BorderLayout(0, 0));
        variablesTab.setToolTipText("Contents of labeled data");
        tabs.addTab("Variables", variablesTab);
        final JScrollPane scrollPane4 = new JScrollPane();
        variablesTab.add(scrollPane4, BorderLayout.CENTER);
        variablesTable = new GTable();
        variablesTable.setAutoCreateRowSorter(true);
        variablesTable.setAutoResizeMode(4);
        variablesTable.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);
        scrollPane4.setViewportView(variablesTable);
        functionArgumentsTab = new JPanel();
        functionArgumentsTab.setLayout(new BorderLayout(0, 0));
        functionArgumentsTab.setToolTipText("Contents of arguments if current instruction is a function call");
        tabs.addTab("Function Arguments", functionArgumentsTab);
        final JPanel panel9 = new JPanel();
        panel9.setLayout(new BorderLayout(0, 0));
        functionArgumentsTab.add(panel9, BorderLayout.NORTH);
        final JPanel panel10 = new JPanel();
        panel10.setLayout(new BorderLayout(0, 0));
        panel9.add(panel10, BorderLayout.WEST);
        functionSignature = new JLabel();
        functionSignature.setText("<function signature>");
        functionSignature.setToolTipText("Function signature of called function");
        panel10.add(functionSignature, BorderLayout.CENTER);
        final JPanel panel11 = new JPanel();
        panel11.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
        panel9.add(panel11, BorderLayout.EAST);
        final JLabel label5 = new JLabel();
        label5.setText("Number of Arguments");
        label5.setToolTipText("Adjust the number of arguments for the function call");
        panel11.add(label5);
        numArgs.setToolTipText("Adjust the number of arguments for the function call");
        panel11.add(numArgs);
        final JScrollPane scrollPane5 = new JScrollPane();
        functionArgumentsTab.add(scrollPane5, BorderLayout.CENTER);
        functionArgumentsTable = new GTable();
        functionArgumentsTable.setAutoCreateRowSorter(true);
        functionArgumentsTable.setAutoResizeMode(4);
        functionArgumentsTable.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);
        scrollPane5.setViewportView(functionArgumentsTable);
        callHistoryTab = new JPanel();
        callHistoryTab.setLayout(new BorderLayout(0, 0));
        callHistoryTab.setToolTipText("Function calls observed during emulation");
        tabs.addTab("Call History", callHistoryTab);
        final JScrollPane scrollPane6 = new JScrollPane();
        callHistoryTab.add(scrollPane6, BorderLayout.CENTER);
        callHistoryTable = new GTable();
        callHistoryTable.setAutoCreateRowSorter(true);
        callHistoryTable.setAutoResizeMode(4);
        callHistoryTable.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);
        scrollPane6.setViewportView(callHistoryTable);
        actionsTab = new JPanel();
        actionsTab.setLayout(new BorderLayout(0, 0));
        actionsTab.setToolTipText("Interesting actions observed during emulation");
        tabs.addTab("Actions", actionsTab);
        final JPanel panel12 = new JPanel();
        panel12.setLayout(new BorderLayout(0, 0));
        actionsTab.add(panel12, BorderLayout.CENTER);
        final JScrollPane scrollPane7 = new JScrollPane();
        panel12.add(scrollPane7, BorderLayout.CENTER);
        actionsFieldsTable = new GTable();
        actionsFieldsTable.setAutoCreateRowSorter(true);
        actionsFieldsTable.setAutoResizeMode(4);
        actionsFieldsTable.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);
        scrollPane7.setViewportView(actionsFieldsTable);
        final JScrollPane scrollPane8 = new JScrollPane();
        scrollPane8.setPreferredSize(new Dimension(250, 428));
        panel12.add(scrollPane8, BorderLayout.WEST);
        actionsSideTable = new GTable();
        actionsSideTable.setAutoCreateRowSorter(true);
        actionsSideTable.setAutoResizeMode(4);
        actionsSideTable.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);
        scrollPane8.setViewportView(actionsSideTable);
        stdoutTab = new JPanel();
        stdoutTab.setLayout(new BorderLayout(0, 0));
        stdoutTab.setToolTipText("Current contents of the stdout stream");
        tabs.addTab("Stdout", stdoutTab);
        stdoutTab.add(stdoutTextDump, BorderLayout.CENTER);
        final JPanel panel13 = new JPanel();
        panel13.setLayout(new BorderLayout(0, 0));
        stdoutTab.add(panel13, BorderLayout.NORTH);
        final JPanel panel14 = new JPanel();
        panel14.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
        panel13.add(panel14, BorderLayout.EAST);
        stdoutExportButton = new JButton();
        stdoutExportButton.setText("Export");
        panel14.add(stdoutExportButton);
        label1.setLabelFor(traceDepth);
        label2.setLabelFor(callDepth);
        label3.setLabelFor(memoryStart);
        label4.setLabelFor(memorySize);
        label5.setLabelFor(numArgs);
    }

    /**
     * @noinspection ALL
     */
    public JComponent $$$getRootComponent$$$() {
        return mainPanel;
    }

    /*
     * This is where we do custom initializations for some widgets.
     */
    private void createUIComponents() {
        tabs = new RugosaTabbedPane();

        // Manually create text areas so we can set it to not be editable.
        // Necessary because ScrollableTextArea is technically a ScrollPane with a wrapped TextArea.
        memoryHexDump = new ScrollableTextArea();
        memoryHexDump.setEditable(false);
        stdoutTextDump = new ScrollableTextArea();
        stdoutTextDump.setEditable(false);

        // Set spinners to not allow negative numbers.
        traceDepth = new JSpinner(new SpinnerNumberModel(0, 0, 20, 1));
        callDepth = new JSpinner(new SpinnerNumberModel(0, 0, 20, 1));
        numArgs = new JSpinner(new SpinnerNumberModel(0, 0, 20, 1));
        memorySize = new JSpinner(new SpinnerNumberModel(1024, 0, 65535, 1));
    }
}
