package dashgraph;

import edu.wpi.first.smartdashboard.gui.StaticWidget;
import edu.wpi.first.smartdashboard.properties.Property;
import edu.wpi.first.smartdashboard.robot.Robot;
import javax.swing.JTextField;
import org.jfree.chart.JFreeChart;
import org.jfree.data.xy.XYSeriesCollection;
import edu.wpi.first.wpilibj.tables.ITable;
import edu.wpi.first.wpilibj.tables.ITableListener;
import edu.wpi.first.wpilibj.tables.TableKeyNotDefinedException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.ParallelGroup;
import javax.swing.GroupLayout.SequentialGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYSeries;

public class DashGraph extends StaticWidget {

    JFreeChart chart;
    XYSeriesCollection data;

    JLabel addLabel;
    JTextField addVarField;
    JLabel removeLabel;
    JTextField removeVarField;

    JButton clearButton;
    JRadioButton enableButton;

    ITable robotTable;

    LinkedList<String> graphedVars;

    JPanel holder;
    ChartPanel chartPanel;

    boolean enabled = true;

    public DashGraph() {
        data = new XYSeriesCollection();
        chart = ChartFactory.createXYLineChart("Grapher", "category", "value", data, PlotOrientation.VERTICAL, true, true, true);

        addLabel = new JLabel("Add a variable: ");
        addVarField = new JTextField();
        addVarField.addActionListener(new AddVarListener());

        removeLabel = new JLabel("Remove a variable: ");
        removeVarField = new JTextField();
        removeVarField.addActionListener(new RemoveVarListener());
        
        robotTable = Robot.getTable();
        

        clearButton = new JButton("clear graph");
        clearButton.addActionListener(new ClearListener());

        enableButton = new JRadioButton("enable graph");
        enableButton.addActionListener(new EnableListener());
        enableButton.setSelected(true);

        graphedVars = new LinkedList();
    }

    @Override
    public void init() {
        chartPanel = new ChartPanel(chart);
        chartPanel.setSize(600, 600);
        chartPanel.setVisible(true);

        holder = new JPanel();
        //holder.setSize(600, 600);
        holder.setLayout(buildLayout(holder));
        
        robotTable.addTableListener(new TimeListener());
        
        add(holder);
    }

    public GroupLayout buildLayout(JPanel p) {
        GroupLayout layout = new GroupLayout(p);

        SequentialGroup bottomHorizontalGroup = layout.createSequentialGroup();
        bottomHorizontalGroup.addComponent(addLabel).addComponent(addVarField, 90, 90, 90).addComponent(removeLabel).addComponent(removeVarField, 90, 90, 90).addComponent(enableButton).addComponent(clearButton);
        ParallelGroup bottomVerticalGroup = layout.createParallelGroup();
        bottomVerticalGroup.addComponent(addLabel).addComponent(addVarField, 18, 18, 18).addComponent(removeLabel).addComponent(removeVarField, 18, 18, 18).addComponent(enableButton).addComponent(clearButton);
        layout.setHorizontalGroup(layout.createParallelGroup().addComponent(chartPanel, 600, 600, 600).addGroup(bottomHorizontalGroup));
        layout.setVerticalGroup(layout.createSequentialGroup().addComponent(chartPanel, 400, 400, 400).addGroup(bottomVerticalGroup));

        return layout;
    }

    @Override
    public void propertyChanged(Property prprt) {
    }

    private class ClearListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            for (String s : graphedVars) {
                DashGraph.this.data.getSeries(s).clear();
            }
            System.out.println("Cleared graph");
        }
    }

    private class EnableListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println(DashGraph.this.enableButton.isSelected());
            DashGraph.this.enabled = DashGraph.this.enableButton.isSelected();
        }
    }

    private class AddVarListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent event) {
            String newVar = addVarField.getText();
            addVarField.setText("");

            try {
                robotTable.getNumber(newVar);

                if (!graphedVars.contains(newVar)) {
                    graphedVars.add(newVar);
                    data.addSeries(new XYSeries(newVar));
                }
            } catch (TableKeyNotDefinedException exception) {
                System.out.println("Tried to add nonexistant key");
            }
        }
    }

    private class RemoveVarListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            String removedVar = removeVarField.getText();
            removeVarField.setText("");
            
            if (graphedVars.remove(removedVar)) {
                System.out.println("Removed var");
                data.removeSeries(data.getSeries(removedVar));
            } else {
                System.out.println("Could not remove var");
            }
        }
    }

    private class TimeListener implements ITableListener {
        
        @Override
        public void valueChanged(ITable source, String key, Object value, boolean isNew) {
            if (DashGraph.this.enabled && key.equals("Time")) {
                for (String s : graphedVars) {
                    try {
                        data.getSeries(s).add((double) value, robotTable.getNumber(s));
                    } catch (TableKeyNotDefinedException e) {
                        System.out.println("Attempted to graph nonexistant key");
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        DashGraph g = new DashGraph();
        g.init();
        g.showInWindow();

        
        int x = 0;
        while (x < 5000) {
            Robot.getTable().putNumber("Time", x);
            Robot.getTable().putNumber("test", x);
            x = x + 1;
            try {
                Thread.sleep(1);
            } catch (InterruptedException ex) {
                Logger.getLogger(DashGraph.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        System.out.println("done");
    }

    public void showInWindow() {
        JFrame f = new JFrame();
        f.add(holder);
        f.setSize(1000, 600);
        f.setVisible(true);
    }
}

@@ -551,73 +551,8 @@
 st;%0A
-import java.util.logging.Level;%0Aimport java.util.logging.Logger;%0A
 impo
@@ -705,35 +705,8 @@
 on;%0A
-import javax.swing.JFrame;%0A
 impo
@@ -1953,15 +1953,15 @@
 on(%22
-c
+C
 lear 
-g
+G
 raph
@@ -2070,20 +2070,21 @@
 on(%22
-enable graph
+Graph Enabled
 %22);%0A
@@ -2427,44 +2427,8 @@
 ();%0A
-        //holder.setSize(600, 600);%0A
     
@@ -6004,725 +6004,7 @@
    %7D
-%0A%0A    public static void main(String%5B%5D args) %7B%0A        DashGraph g = new DashGraph();%0A        g.init();%0A        g.showInWindow();%0A%0A        %0A        int x = 0;%0A        while (x %3C 5000) %7B%0A            Robot.getTable().putNumber(%22Time%22, x);%0A            Robot.getTable().putNumber(%22test%22, x);%0A            x = x + 1;%0A            try %7B%0A                Thread.sleep(1);%0A            %7D catch (InterruptedException ex) %7B%0A                Logger.getLogger(DashGraph.class.getName()).log(Level.SEVERE, null, ex);%0A            %7D%0A        %7D%0A        System.out.println(%22done%22);%0A    %7D%0A%0A    public void showInWindow() %7B%0A        JFrame f = new JFrame();%0A        f.add(holder);%0A        f.setSize(1000, 600);%0A        f.setVisible(true);%0A    %7D
 %0A%7D%0A

clean up some stuff