package at.jku.pervasive.ecg;

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.ValueMarker;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.Range;
import org.jfree.data.time.Millisecond;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.time.TimeSeriesDataItem;
import org.jfree.data.xy.XYDataset;

public class ECGMonitor extends JFrame {
  private class ListenForUpdates extends Thread implements IHeartManListener {

    private final List<TimeSeriesDataItem> buffer;
    private final long last = 0;
    private final TimeSeries series;

    public ListenForUpdates(TimeSeries series) {
      super();
      this.series = series;
      this.buffer = Collections
          .synchronizedList(new LinkedList<TimeSeriesDataItem>());
    }

    @Override
    public void dataReceived(String address, long timestamp, double value) {
      if (!filter || (value < 4.0 && value > -2.0)) {
        Millisecond now = new Millisecond(new Date(timestamp));
        this.buffer.add(new TimeSeriesDataItem(now, value));
        // last = timestamp;
      }
    }

    @Override
    public void run() {
      while (!isInterrupted()) {
        try {
          Thread.sleep(40);
          // tell plot to repaint
          if (doUpdate) {
            series.setNotify(false);
            synchronized (buffer) {
              for (TimeSeriesDataItem dataItem : buffer) {
                series.add(dataItem);
              }
              buffer.clear();
            }
            series.fireSeriesChanged();
            series.setNotify(true);
          }
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }

  }

  public static void main(String[] args) throws Exception {
    HeartManDiscovery heartManDiscovery = new HeartManDiscovery();
    // heartManDiscovery.discoverHeartManDevices();

    String heartman = "00A096203DCB"; // C102
    // heartman = "00A096203DD1"; // C157
    RemoteDevice remoteDevice = heartManDiscovery.pingDevice(heartman);
    List<ServiceRecord> services = heartManDiscovery
        .searchServices(remoteDevice);
    ServiceRecord serviceRecord = services.get(0);

    ECGMonitor monitor = new ECGMonitor();
    monitor.setVisible(true);

    IHeartManListener hml = monitor.getHeartManListener();
    heartManDiscovery.startListening(heartman, hml, serviceRecord);
  }

  private boolean doUpdate = true;
  private boolean filter = true;
  private final ListenForUpdates listenForUpdates;

  public ECGMonitor() {
    super();

    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setLayout(new BorderLayout());

    TimeSeries timeSeries = new TimeSeries("ecg");
    timeSeries.setMaximumItemAge(TimeUnit.SECONDS.toMillis(5));

    XYDataset dataset = new TimeSeriesCollection(timeSeries);
    JFreeChart chart = ChartFactory.createTimeSeriesChart("ecg", "time", "mV",
        dataset, false, true, false);

    XYPlot xyPlot = (XYPlot) chart.getPlot();
    ValueMarker baselineMarker = new ValueMarker(0.0D, Color.BLACK,
        new BasicStroke());
    xyPlot.addRangeMarker(baselineMarker);

    xyPlot.getRangeAxis().setRange(new Range(-1.0, 3.0));

    ChartPanel chartPanel = new ChartPanel(chart);
    add(chartPanel, BorderLayout.CENTER);

    JPanel settingsPanel = createSettingsPanel();
    add(settingsPanel, BorderLayout.SOUTH);

    listenForUpdates = new ListenForUpdates(timeSeries);
    listenForUpdates.start();

    pack();

    // center on screen
    setLocationRelativeTo(null);
  }

  public IHeartManListener getHeartManListener() {
    return listenForUpdates;
  }

  private JPanel createSettingsPanel() {
    JPanel panel = new JPanel(new FlowLayout());

    JCheckBox updateCheckBox = new JCheckBox("update ecg?");
    updateCheckBox.setSelected(this.doUpdate);
    updateCheckBox.addChangeListener(new ChangeListener() {
      @Override
      public void stateChanged(ChangeEvent evt) {
        JCheckBox checkBox = (JCheckBox) evt.getSource();
        doUpdate = checkBox.isSelected();
      }
    });
    panel.add(updateCheckBox);

    JCheckBox doFilterCheckBox = new JCheckBox("do Filter?");
    doFilterCheckBox.setSelected(this.filter);
    doFilterCheckBox.addChangeListener(new ChangeListener() {
      @Override
      public void stateChanged(ChangeEvent evt) {
        JCheckBox checkBox = (JCheckBox) evt.getSource();
        filter = checkBox.isSelected();
      }
    });
    panel.add(doFilterCheckBox);

    return panel;
  }
}

@@ -282,83 +282,8 @@
 t;%0A%0A
-import javax.bluetooth.RemoteDevice;%0Aimport javax.bluetooth.ServiceRecord;%0A
 impo
@@ -308,16 +308,16 @@
 eckBox;%0A
+
 import j
@@ -908,16 +908,17 @@
 Frame %7B%0A
+%0A
   privat
@@ -1044,41 +1044,8 @@
 er;%0A
-    private final long last = 0;%0A
     
@@ -2192,21 +2192,22 @@
 %0A  p
-ublic
+rivate
  static 
 void
@@ -2206,680 +2206,59 @@
 tic 
-void main(String%5B%5D args) throws Exception %7B%0A    HeartManDiscovery heartManDiscovery = new HeartManDiscovery();%0A    // heartManDiscovery.discoverHeartManDevices();%0A%0A    String heartman = %2200A
+final long serialVersionUID = 7543
 09
+5
 620
-3DCB%22; // C102%0A    // heartman = %2200A096203DD1%22; // C157%0A    RemoteDevice remoteDevice = heartManDiscovery.pingDevice(heartman);%0A    List%3CServiceRecord%3E services = heartManDiscovery%0A        .searchServices(remoteDevice);%0A    ServiceRecord serviceRecord = services.get(0);%0A%0A    ECGMonitor monitor = new ECGMonitor();%0A    monitor.setVisible(true);%0A%0A    IHeartManListener hml = monitor.getHeartManListener();%0A    heartManDiscovery.startListening(heartman, hml, serviceRecord);%0A  %7D
+229093879L;
 %0A%0A  

remove main method from ECGMonitor