/*
 * Copyright (c) 2014 Paul Scherrer Institute. All rights reserved.
 */

import ch.psi.pshell.core.Context;
import ch.psi.pshell.device.Device;
import ch.psi.pshell.device.DeviceAdapter;
import ch.psi.pshell.device.DeviceListener;
import ch.psi.pshell.epics.Scienta;
import ch.psi.pshell.plot.LinePlotSeries;
import ch.psi.pshell.plot.RangeSelectionPlot.RangeSelection;
import ch.psi.pshell.ui.Panel;
import ch.psi.utils.IO;
import ch.psi.utils.State;
import ch.psi.utils.swing.SwingUtils;
import ch.psi.pshell.core.JsonSerializer;
import ch.psi.utils.Convert;
import java.awt.Component;
import java.io.File;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Level;
import javax.swing.JFileChooser;
import javax.swing.SwingUtilities;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.DefaultTableModel;

/**
 *
 */
public class XPSSpectrum extends Panel {
            
    boolean detailedScan;
    boolean running;
    Scienta scienta;  
    
    public XPSSpectrum() {
        initComponents();
        buttonSkip.setVisible(false);                     
        rangeSelectionPanel.setAditionalColumns(new String[]{"Time", "Size", "Iter"}, new Class[]{Double.class, Double.class, Integer.class});
        final DefaultTableModel model = (DefaultTableModel) rangeSelectionPanel.getTable().getModel();
        model.addTableModelListener(new TableModelListener() {
            @Override
            public void tableChanged(TableModelEvent e) {
                if (e.getType() == TableModelEvent.INSERT) {
                    final int row = e.getFirstRow();
                    SwingUtilities.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            if (row > 0) {
                                for (int col = 3; col < 6; col++) {
                                    model.setValueAt(model.getValueAt(row - 1, col), row, col);
                                }
                            } else {
                                model.setValueAt(valueTime.getValue(), row, 3);
                                model.setValueAt(valueSize.getValue(), row, 4);
                                model.setValueAt((int)valueIterations.getValue(), row, 5);
                            }
                        }
                    });
                }
            }
        });
        setPersistedComponents(new Component[]{valueLow, valueHigh, valueTime, valueSize, valueIterations,comboPass, txt, sp, ck });
    }    

    @Override
    public void onInitialize(int runCount) {
        scienta = (Scienta) getDevice("scienta");
        scienta.getTotalChannels().addListener(progressListener);
        scienta.getCurrentChannel().addListener(progressListener);
    }
    
    @Override
    public void onStateChange(State state, State former) {
        setEnabled(state == State.Ready);
        if (!state.isProcessing()){
            buttonSkip.setVisible(false);
            if (running){
                stopTimer();
                running = false;
                getView().getStatusBar().setProgress(-1); 
            }
        }
    }

    @Override
    public void onExecutedFile(String fileName, Object result) {
        String script = IO.getPrefix(fileName);
        if (script != null) {
            switch (script) {
                case "XPSSpectrum":
                    if (result instanceof Exception) {
                        //SwingUtils.showMessage(getComponent(), "Error in " + fileName, exception.getMessage());
                    } else {
                        if (detailedScan) {

                        } else {
                            Object[] ret = (Object[]) ((Object[]) result)[0];
                            if (ret.length > 0) {
                                //double[] data = (double[]) Convert.wrapperArrayToPrimitiveArray(ret[0], Double.class);
                                double[] xdata = (double[]) ret[0];
                                double[] ydata = (double[]) ret[1];
                                
                                //double[] data = new double[]{1.0,1.0,1.0,1.0,1.0};
                                LinePlotSeries series = new LinePlotSeries("Data");
                                rangeSelectionPanel.setSeries(series);
                                series.setData(xdata, ydata);
                            }
                        }
                    }
                    break;
            }
        }
        detailedScan = false;
        updateButtons();
    }

    @Override
    public void setEnabled(boolean value) {
        super.setEnabled(value);
        rangeSelectionPanel.setEnabled(value);
        valueLow.setEnabled(value);
        valueHigh.setEnabled(value);
        valueTime.setEnabled(value);
        valueSize.setEnabled(value);
        valueIterations.setEnabled(value);
        comboPass.setEnabled(value);                
        updateButtons();
    }

    void updateButtons() {
        buttonInitialScan.setEnabled(isEnabled());
        buttonDetailedScan.setEnabled(isEnabled() && rangeSelectionPanel.getPlot().getSelectedRanges().length > 0);
        btLoad.setEnabled(isEnabled());
        btSave.setEnabled(buttonDetailedScan.isEnabled());        
    }
        
    DeviceListener progressListener = new DeviceAdapter() {

        @Override
        public void onValueChanged(Device device, Object o, Object o1) {
            if (running){
                getView().getStatusBar().setProgress(scienta.getProgress());        
            }            
        }
    };
    public final String CURRERNT_RANGE_VAR =  "cur_range";
    public final String CURRERNT_ITERATION_VAR =  "cur_iteration";
    int currentScanIndex ;
    RangeSelection[] scanRanges;
            
    @Override
    protected void onTimer() {
        try{
            Object index = XPSSpectrum.this.eval(CURRERNT_RANGE_VAR, true);
            if ((index!=null) && (index instanceof Integer) && ((Integer)index >= 0)){
                int scanIndex = (Integer)index;
                if (scanIndex!=currentScanIndex){
                    buttonSkip.setEnabled(true);
                }
                currentScanIndex = scanIndex;

                int current_iteration = (Integer) XPSSpectrum.this.eval(CURRERNT_ITERATION_VAR, true);
                int iterations = (Integer)scanRanges[currentScanIndex].getVars()[2];

                buttonSkip.setVisible((iterations>1) && (current_iteration < (iterations-1)));                

                if (detailedScan){
                    RangeSelection range = rangeSelectionPanel.getRangesOrdered()[scanIndex];                
                    for (int row = 0; row< rangeSelectionPanel.getTable().getRowCount(); row++){
                        if (range.equals((Double)rangeSelectionPanel.getTable().getValueAt(row, 0), (Double)rangeSelectionPanel.getTable().getValueAt(row, 2))){
                            rangeSelectionPanel.getTable().setRowSelectionInterval(row, row);
                            break;
                        }
                        if (row == (rangeSelectionPanel.getTable().getRowCount()-1)){
                            rangeSelectionPanel.getTable().clearSelection();
                        }
                    }                                
                }
            } else {
                rangeSelectionPanel.getTable().clearSelection();
            }
        } catch (Exception ex){
            getLogger().log(Level.FINE, null, ex);
        }
    } 
    
    void start() throws Context.ContextStateException{
            HashMap<String, Object> args = new HashMap<>();
            args.put("ranges", scanRanges);
            args.put("pass_energy", Integer.valueOf(comboPass.getSelectedItem().toString()));
                        
            currentScanIndex = -1;
            runAsync("XPSSpectrum", args);
            startTimer(500,10);
            running = true;        
    }
    
    
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        valueIterations = new ch.psi.pshell.swing.ValueSelection();
        jLabel9 = new javax.swing.JLabel();
        valueTime = new ch.psi.pshell.swing.ValueSelection();
        comboPass = new javax.swing.JComboBox();
        valueSize = new ch.psi.pshell.swing.ValueSelection();
        jLabel11 = new javax.swing.JLabel();
        valueLow = new ch.psi.pshell.swing.ValueSelection();
        jLabel2 = new javax.swing.JLabel();
        valueHigh = new ch.psi.pshell.swing.ValueSelection();
        jLabel8 = new javax.swing.JLabel();
        jLabel17 = new javax.swing.JLabel();
        buttonScientaSetup = new javax.swing.JButton();
        txt = new javax.swing.JTextField();
        sp = new javax.swing.JSpinner();
        ck = new javax.swing.JCheckBox();
        jPanel2 = new javax.swing.JPanel();
        btLoad = new javax.swing.JButton();
        btSave = new javax.swing.JButton();
        buttonInitialScan = new javax.swing.JButton();
        buttonDetailedScan = new javax.swing.JButton();
        rangeSelectionPanel = new ch.psi.pshell.swing.RangeSelectionPanel() {
            protected void onSeriesChanged() {
                updateButtons();
            }
            protected void onSelectionChanged() {
                updateButtons();
            }
        }
        ;
        buttonAbort = new javax.swing.JButton();
        buttonSkip = new javax.swing.JButton();

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Arguments"));

        jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
        jLabel1.setText("Low:");

        valueIterations.setDecimals(0);
        valueIterations.setMaxValue(1000.0);
        valueIterations.setMinValue(0.0);
        valueIterations.setShowButtons(false);
        valueIterations.setValue(1.0);

        jLabel9.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
        jLabel9.setText("Size:");

        valueTime.setDecimals(2);
        valueTime.setMaxValue(1000.0);
        valueTime.setMinValue(0.0);
        valueTime.setShowButtons(false);
        valueTime.setValue(1.0);

        comboPass.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "2", "5", "10", "20", "50", "100", "200" }));
        comboPass.setToolTipText("");

        valueSize.setDecimals(2);
        valueSize.setMaxValue(1000.0);
        valueSize.setMinValue(0.0);
        valueSize.setShowButtons(false);
        valueSize.setValue(1.0);

        jLabel11.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
        jLabel11.setText("Pass:");

        valueLow.setDecimals(2);
        valueLow.setMaxValue(1000.0);
        valueLow.setMinValue(0.0);
        valueLow.setShowButtons(false);
        valueLow.setValue(0.0);

        jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
        jLabel2.setText("High:");

        valueHigh.setDecimals(2);
        valueHigh.setMaxValue(1000.0);
        valueHigh.setMinValue(0.0);
        valueHigh.setShowButtons(false);
        valueHigh.setValue(100.0);

        jLabel8.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
        jLabel8.setText("Time:");

        jLabel17.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
        jLabel17.setText("Iter:");

        buttonScientaSetup.setText("Scienta Setup");
        buttonScientaSetup.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonScientaSetupActionPerformed(evt);
            }
        });

        txt.setText("jTextField1");

        sp.setModel(new javax.swing.SpinnerNumberModel(5.0d, 0.0d, 5.0d, 1.0d));

        ck.setText("jCheckBox1");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(ck))
                    .addComponent(buttonScientaSetup, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addComponent(jLabel1)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(valueLow, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addComponent(jLabel2)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(valueHigh, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addComponent(jLabel8)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(valueTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addComponent(jLabel9)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(valueSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addComponent(jLabel17)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(valueIterations, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addComponent(jLabel11)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(comboPass, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(txt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                                .addComponent(sp, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(1, 1, 1)))
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );

        jPanel1Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {comboPass, valueHigh, valueIterations, valueLow, valueSize, valueTime});

        jPanel1Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jLabel1, jLabel11, jLabel17, jLabel2, jLabel8, jLabel9});

        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                    .addComponent(valueLow, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                    .addComponent(jLabel2)
                    .addComponent(valueHigh, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel8)
                    .addComponent(valueTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel9)
                    .addComponent(valueSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel17)
                    .addComponent(valueIterations, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                    .addComponent(jLabel11)
                    .addComponent(comboPass, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(txt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(sp, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(ck)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(buttonScientaSetup)
                .addGap(24, 24, 24))
        );

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Scan Control"));

        btLoad.setText("Load");
        btLoad.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btLoadActionPerformed(evt);
            }
        });

        btSave.setText("Save");
        btSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btSaveActionPerformed(evt);
            }
        });

        buttonInitialScan.setText("Simple Scan");
        buttonInitialScan.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonInitialScanActionPerformed(evt);
            }
        });

        buttonDetailedScan.setText("Detailed Scan");
        buttonDetailedScan.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonDetailedScanActionPerformed(evt);
            }
        });

        buttonAbort.setText("Stop");
        buttonAbort.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonAbortActionPerformed(evt);
            }
        });

        buttonSkip.setText("Skip");
        buttonSkip.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonSkipActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGap(342, 349, Short.MAX_VALUE)
                        .addComponent(btLoad)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(btSave))
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel2Layout.createSequentialGroup()
                        .addGap(20, 20, 20)
                        .addComponent(buttonInitialScan)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(buttonDetailedScan, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(buttonSkip)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(buttonAbort))
                    .addComponent(rangeSelectionPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );

        jPanel2Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {btLoad, btSave, buttonAbort, buttonDetailedScan, buttonInitialScan, buttonSkip});

        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(buttonInitialScan)
                    .addComponent(buttonDetailedScan)
                    .addComponent(buttonAbort)
                    .addComponent(buttonSkip))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(rangeSelectionPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 286, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(btLoad, javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(btSave, javax.swing.GroupLayout.Alignment.TRAILING))
                .addContainerGap())
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents

    private void buttonAbortActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonAbortActionPerformed
        try {
            abort();
            scienta.stop();
        } catch (Exception ex) {
            showException(ex);
        }        
    }//GEN-LAST:event_buttonAbortActionPerformed

    private void buttonInitialScanActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonInitialScanActionPerformed
        try {
            rangeSelectionPanel.clear();
            detailedScan = false;
                        
            RangeSelection initialRange = new RangeSelection(valueLow.getValue(),valueHigh.getValue());
            int iterations = (int)valueIterations.getValue();
            initialRange.setVars(new Object[]{valueSize.getValue(),valueTime.getValue(),iterations});
            scanRanges = new RangeSelection[]{initialRange};

            start();
        } catch (Exception ex) {
            showException(ex);
        }

    }//GEN-LAST:event_buttonInitialScanActionPerformed

    private void buttonDetailedScanActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonDetailedScanActionPerformed
        try {
            detailedScan = true;         
            scanRanges = rangeSelectionPanel.getRangesOrdered();
            start();
        } catch (Exception ex) {
            showException(ex);
        }
    }//GEN-LAST:event_buttonDetailedScanActionPerformed

    private void btSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btSaveActionPerformed
        try {
            JFileChooser chooser = new JFileChooser(getContext().getSetup().getContextPath());
            FileNameExtensionFilter filter = new FileNameExtensionFilter("XPS Spectrum scan definition file", "xps");
            chooser.setFileFilter(filter);
            int rVal = chooser.showSaveDialog(this);
            if (rVal == JFileChooser.APPROVE_OPTION) {
                File f = chooser.getSelectedFile();
                if (IO.getExtension(f).isEmpty()){
                    f = new File(f.getPath() + ".xps");
                }
                Object[] obj = new Object[]{SwingUtils.getTableData(rangeSelectionPanel.getTable()),
                                            rangeSelectionPanel.getPlot().getSeries(0).getX(),
                                            rangeSelectionPanel.getPlot().getSeries(0).getY()};
                //Files.write(f.toPath(), Serializer.encode(obj, Serializer.EncoderType.bin));
                Files.write(f.toPath(), JsonSerializer.encode(obj, true).getBytes());
                
            }
        } catch (Exception ex) {
            showException(ex);
        }
        
    }//GEN-LAST:event_btSaveActionPerformed

    private void btLoadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btLoadActionPerformed
        try {
            JFileChooser chooser = new JFileChooser(getContext().getSetup().getContextPath());
            FileNameExtensionFilter filter = new FileNameExtensionFilter("XPS Spectrum scan definition file", "xps");
            chooser.setFileFilter(filter);
            int rVal = chooser.showOpenDialog(this);
            if (rVal == JFileChooser.APPROVE_OPTION) {
                rangeSelectionPanel.removeAllRanges();
                //Object[] obj =  (Object[])Serializer.decode(Files.readAllBytes(chooser.getSelectedFile().toPath()), Serializer.EncoderType.bin);
                Object aux =  (Object[])JsonSerializer.decode(new String(Files.readAllBytes(chooser.getSelectedFile().toPath())), Object[].class);                
                Object[] obj = (Object[]) aux;                
                ArrayList<ArrayList> table = (ArrayList) obj[0];                
                if (!rangeSelectionPanel.getPlot().hasData()){
                    double[] x = (double[]) Convert.toPrimitiveArray(((ArrayList) obj[1]).toArray(new Double[0]));
                    double[] y = (double[]) Convert.toPrimitiveArray(((ArrayList) obj[2]).toArray(new Double[0]));
                    LinePlotSeries series = new LinePlotSeries("Data");                    
                    rangeSelectionPanel.setSeries(series);
                    series.setData(x, y);
                }
                //SwingUtils.showMessage(null, "ad", aux.getClass().getName());
                
                for (ArrayList<Double> row:table){
                    rangeSelectionPanel.getPlot().addRange(row.get(0), row.get(2));
                }
                
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {                            
                        for (int row = 0; row < table.size(); row++) {
                            for (int col = 3; col < 6; col++) {
                                rangeSelectionPanel.getTable().setValueAt(table.get(row).get(col), row , col);
                            }
                        }
                    }
                });
            }
        } catch (Exception ex) {
            showException(ex);
        }
    }//GEN-LAST:event_btLoadActionPerformed

    private void buttonSkipActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonSkipActionPerformed
        try {
            this.eval("skip_iteration = True", true);
            buttonSkip.setEnabled(false);
        } catch (Exception ex) {
            showException(ex);
        }
    }//GEN-LAST:event_buttonSkipActionPerformed

    private void buttonScientaSetupActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonScientaSetupActionPerformed
        try{
            showDevicePanel("scienta");
        } catch (Exception ex){
            SwingUtils.showException(this, ex);
        }
    }//GEN-LAST:event_buttonScientaSetupActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btLoad;
    private javax.swing.JButton btSave;
    private javax.swing.JButton buttonAbort;
    private javax.swing.JButton buttonDetailedScan;
    private javax.swing.JButton buttonInitialScan;
    private javax.swing.JButton buttonScientaSetup;
    private javax.swing.JButton buttonSkip;
    private javax.swing.JCheckBox ck;
    private javax.swing.JComboBox comboPass;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel17;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private ch.psi.pshell.swing.RangeSelectionPanel rangeSelectionPanel;
    private javax.swing.JSpinner sp;
    private javax.swing.JTextField txt;
    private ch.psi.pshell.swing.ValueSelection valueHigh;
    private ch.psi.pshell.swing.ValueSelection valueIterations;
    private ch.psi.pshell.swing.ValueSelection valueLow;
    private ch.psi.pshell.swing.ValueSelection valueSize;
    private ch.psi.pshell.swing.ValueSelection valueTime;
    // End of variables declaration//GEN-END:variables
}
