/*                                                                      *\
**                    SICU Stress Measurement System                    **
**                      Project P04  |  C380 Team A                     **
**          EBME 380: Biomedical Engineering Design Experience          **
**                    Case Western Reserve University                   **
**                          2016 Fall Semester                          **
\*                                                                      */

package edu.cwru.sicu_sms;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.control.ToggleButton;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executors;

/**
 * The controller for the front-end program.
 *
 * @since October 13, 2016
 * @author Ted Frohlich <ttf10@case.edu>
 * @author Abby Walker <amw138@case.edu>
 */
public class Controller {
    
    @FXML private ToggleButton recordButton;
    
    public Controller() {
        
    }
    
    @FXML
    private void confirmExit() throws Exception {
        Stage dialog = new Stage();
        dialog.initStyle(StageStyle.UNDECORATED);
        dialog.setScene(new Scene(FXMLLoader.load(
                getClass().getResource("dialog/exit_dialog.fxml")
        )));
        dialog.show();
    }
    
    @FXML
    private void onMouseEnteredRecordButton() {
        recordButton.setText((isRecording() ? "Stop" : "Start") + " Recording");
    }
    
    @FXML
    private void onMouseExitedRecordButton() {
        recordButton.setText("Record" + (isRecording() ? "ing..." : ""));
    }
    
    @FXML
    private void onMousePressedRecordButton() {
        recordButton.setStyle("-fx-background-color: darkred");
    }
    
    @FXML
    private void onMouseReleasedRecordButton() {
        recordButton.setStyle("-fx-background-color: red");
    }
    
    @FXML
    private void record() {
        if (isRecording()) {  // start recording...
            //TODO: Run thread for saving data to file.
        }
        else {  // stop recording...
            //TODO: End thread for saving data to file.
        }
        onMouseEnteredRecordButton();  // indicate what next click would do
    }
    
    private boolean isRecording() {
        return recordButton.isSelected();
    }
    
    
    /**
     * A controller for the EEG tab.
     */
    private class EEGController {
    
        @FXML private LineChart<String, Number>
                leftRostralChart, rightRostralChart,
                leftCaudalChart,  rightCaudalChart;
    
        private CategoryAxis xAxis;
        private NumberAxis yAxis;
        private ObservableList<String> xAxisCategories;
        
        private LineChart.Series<String, Number>[] electrodes;
        
        private ObservableList<LineChart.Data<String, Number>>
                leftRostralList, rightRostralList,
                leftCaudalList,  rightCaudalList;
    
        private int lastObservedChangelistSize, changesBeforeUpdate = 10;
        private Task<Date> chartUpdateTask;
    
        private EEGController() {
            initObservableLists();
            getObservableLists().forEach(list ->
                    list.addListener(dataListChangeListener()));
            
            initAxes();
            xAxis.setCategories(xAxisCategories);
//            xAxis.setAutoRanging(false);
            
            //TODO: instantiate and add data series
            
            initChartUpdateTask();
            Executors.newSingleThreadExecutor().submit(chartUpdateTask);
        }
        
        private void initAxes() {
            xAxis = new CategoryAxis();     yAxis = new NumberAxis();
            xAxis.setLabel("Time (sec)");   yAxis.setLabel("Relative Amplitude");
        }
        
        private void initChartUpdateTask() {
            chartUpdateTask = new Task<Date>() {
                @Override
                protected Date call() throws Exception {
                    while (true) {
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException ie) {
                            Thread.currentThread().interrupt();
                        }
                        if (isCancelled()) break;
                        updateValue(new Date());
                    }
                    return new Date();
                }
            };
            chartUpdateTask.valueProperty().addListener(new ChangeListener<Date>() {
                SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");  //TODO: eventually just want seconds
                Random random = new Random();
                @Override
                public void changed(ObservableValue<? extends Date> observableDate, Date oldDate, Date newDate) {
                    String strDate = dateFormat.format(newDate);
                    xAxisCategories.add(strDate);
                    getObservableLists().forEach(list ->
                            list.add(new LineChart.Data(strDate, newDate.getMinutes() + random.nextInt(100500))));
                }
            });
        }
        
        private void initObservableLists() {
            leftRostralList = rightRostralList = leftCaudalList = rightCaudalList
                    = FXCollections.observableArrayList();
            xAxisCategories
                    = FXCollections.observableArrayList();
        }
        
        private List<LineChart<String, Number>> getCharts() {
            List<LineChart<String, Number>> charts = Collections.emptyList();
            charts.add(leftRostralChart);   charts.add(rightRostralChart);
            charts.add(leftCaudalChart);    charts.add(rightCaudalChart);
            return charts;
        }
    
        private List<ObservableList<LineChart.Data<String, Number>>> getObservableLists() {
            List<ObservableList<LineChart.Data<String, Number>>> lists = Collections.emptyList();
            lists.add(leftRostralList);   lists.add(rightRostralList);
            lists.add(leftCaudalList);    lists.add(rightCaudalList);
            return lists;
        }
        
        private ListChangeListener<LineChart.Data<String, Number>> dataListChangeListener() {
            return change -> {
                if (change.getList().size() - lastObservedChangelistSize > changesBeforeUpdate) {
                    lastObservedChangelistSize += changesBeforeUpdate;
                    xAxis.getCategories().remove(0, changesBeforeUpdate);
                }
            };
        }
        
    }
    
    
    /**
     * A controller for the EKG tab.
     */
    private class EKGController {
        
        //TODO:
        
    }
    
}

@@ -547,16 +547,52 @@
 u_sms;%0A%0A
+import javafx.application.Platform;%0A
 import j
@@ -857,66 +857,8 @@
 ML;%0A
-import javafx.fxml.FXMLLoader;%0Aimport javafx.scene.Scene;%0A
 impo
@@ -996,28 +996,21 @@
 control.
-ToggleButton
+Alert
 ;%0Aimport
@@ -1022,50 +1022,73 @@
 fx.s
-tage.Stage;%0Aimport javafx.stage.StageStyle
+cene.control.ButtonType;%0Aimport javafx.scene.control.ToggleButton
 ;%0A%0Ai
@@ -1626,136 +1626,165 @@
     
-Stage dialog = new Stage();%0A        dialog.initStyle(StageStyle.UNDECORATED);%0A        dialog.setScene(new Scene(FXMLLoader.load(
+Alert alert = new Alert(Alert.AlertType.CONFIRMATION);%0A        alert.setTitle(%22Confirm Exit%22);%0A        alert.setHeaderText(%22Are you sure you want to exit?%22);
 %0A   
@@ -1788,24 +1788,25 @@
         
+%0A
         
 getClass
@@ -1801,93 +1801,152 @@
     
-getClass().getResource(%22dialog/exit_dialog.fxml%22)%0A        )));%0A        dialog.show();
+ButtonType result = alert.showAndWait().orElse(ButtonType.CANCEL);%0A        if (result == ButtonType.OK) %7B%0A            Platform.exit();%0A        %7D
 %0A   

Rewrite 'confirmExit' method to make use of the 'Alert' class