001package jmri.jmrix.can.cbus.swing;
002
003import java.awt.event.ActionEvent;
004import javax.swing.*;
005import jmri.jmrix.can.swing.CanPanel;
006import jmri.jmrix.can.cbus.CbusEvent;
007import jmri.util.swing.ValidationNotifications;
008
009// import org.slf4j.Logger;
010// import org.slf4j.LoggerFactory;
011
012/**
013 * Panel for CBUS Console to Send CBUS Events
014 * 
015 * @author Andrew Crosland Copyright (C) 2008
016 * @author Steve Young Copyright (C) 2018
017 */
018public class CbusSendEventPane extends JPanel {
019    
020    private final CanPanel _mainPane;
021    
022    private JRadioButton onButton;
023    private JRadioButton offButton;
024    private JRadioButton requestButton;
025    private ButtonGroup onOffGroup;
026    private ButtonGroup dataGroup;
027    private JTextField nnField;
028    private JTextField evField;
029    private JButton sendEvButton;
030    private JCheckBox showEventData;
031    private JCheckBox decimalCheckBoxC;
032    private JPanel eventDataPanel;
033    private JTextField[] data;
034    private JRadioButton select0Data;
035    private JRadioButton select1Data;
036    private JRadioButton select2Data;
037    private JRadioButton select3Data;
038    private int _selectedData = 0;
039    
040    public CbusSendEventPane(CanPanel mainPane){
041        super();
042        _mainPane = mainPane;
043        init();
044    }
045    
046    private void init() {
047    
048        onButton = new JRadioButton();
049        offButton = new JRadioButton();
050        requestButton = new JRadioButton();
051        showEventData = new JCheckBox();
052        onOffGroup = new ButtonGroup();
053        dataGroup = new ButtonGroup();
054        sendEvButton = new JButton();
055        decimalCheckBoxC = new JCheckBox();
056    
057        initButtons();
058        addToPanel();
059        
060    }
061
062    private void addToPanel() {
063        
064        JPanel mainEventPanel = new JPanel();
065        
066        // mainEventPanel.setLayout(new BoxLayout(mainEventPanel, BoxLayout.X_AXIS));
067    
068        setBorder(BorderFactory.createTitledBorder(
069            BorderFactory.createEtchedBorder(), Bundle.getMessage("ButtonSendEvent")));
070
071        nnField.setBorder(BorderFactory.createTitledBorder(
072                BorderFactory.createEtchedBorder(), Bundle.getMessage("CbusNode")));
073        mainEventPanel.add(nnField);
074
075        
076        evField.setBorder(BorderFactory.createTitledBorder(
077                BorderFactory.createEtchedBorder(), Bundle.getMessage("CbusEvent")));
078        mainEventPanel.add(evField);
079        
080        mainEventPanel.add(decimalCheckBoxC);
081
082        onOffGroup.add(onButton);
083        onOffGroup.add(offButton);
084        onOffGroup.add(requestButton);
085        
086        JPanel group = new JPanel();
087        group.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder()));
088        
089        group.add(onButton);
090        group.add(offButton);
091        group.add(requestButton);
092        
093        mainEventPanel.add(group);
094        
095        mainEventPanel.add(sendEvButton);
096        
097        mainEventPanel.add(showEventData);
098        
099        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
100        add(mainEventPanel);
101        eventDataPanel = getNewDataPanel();
102        add(eventDataPanel);
103        
104        dataSelectTypePerformed(null); // reset data panel
105        
106    }
107    
108    private void initButtons() {
109    
110        onButton.setText(Bundle.getMessage("InitialStateOn"));
111        onButton.setToolTipText(Bundle.getMessage("TooltipSendOnEvent"));
112        onButton.setSelected(true);
113
114        offButton.setText(Bundle.getMessage("InitialStateOff"));
115        offButton.setToolTipText(Bundle.getMessage("TooltipSendOffEvent"));
116        
117        requestButton.setText(Bundle.getMessage("CbusEventRequest"));
118        requestButton.setToolTipText(Bundle.getMessage("TooltipSendRequestEvent"));
119
120        sendEvButton.setText(Bundle.getMessage("ButtonSend"));
121        sendEvButton.setToolTipText(Bundle.getMessage("TooltipSendEvent"));
122    
123        decimalCheckBoxC.setText(Bundle.getMessage("ButtonDecimal"));
124        decimalCheckBoxC.setToolTipText(Bundle.getMessage("TooltipDecimal"));
125        decimalCheckBoxC.setSelected(true);
126        
127        showEventData.setText("Event Data");
128        showEventData.setToolTipText("Show / hide Event Data Input");
129        
130        addButtonListeners();
131    
132    }
133    
134    private JPanel getNewDataPanel(){
135    
136        initDataPanelInputs();
137        
138        JPanel dataPanel = new JPanel();
139        
140        JPanel group = new JPanel();
141        group.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder()));
142        
143        group.add(select0Data);
144        group.add(select1Data);
145        group.add(select2Data);
146        group.add(select3Data);
147        
148        data = new JTextField[3];
149        
150        for (int i = 0; i < 3; i++) {
151            data[i] = new JTextField("0", 10); // binary input
152            data[i].setBorder(BorderFactory.createTitledBorder(
153                BorderFactory.createEtchedBorder(), Bundle.getMessage("OPC_DA") + (i+1)));
154            data[i].setToolTipText(Bundle.getMessage("TooltipDbX", i+1));
155            dataPanel.add(data[i]);
156        }
157        
158        dataPanel.add(group);
159    
160        dataPanel.setVisible(false);
161        return dataPanel;
162    }
163    
164    private void initDataPanelInputs(){
165    
166        select0Data = new JRadioButton();
167        select1Data = new JRadioButton();
168        select2Data = new JRadioButton();
169        select3Data = new JRadioButton();
170        
171        select0Data.setText("No Data");
172        select1Data.setText("1 byte");
173        select2Data.setText("2 bytes");
174        select3Data.setText("3 bytes");
175        
176        dataGroup.add(select0Data);
177        dataGroup.add(select1Data);
178        dataGroup.add(select2Data);
179        dataGroup.add(select3Data);
180        
181        select0Data.setSelected(true);
182        _selectedData = 0;
183        
184        select0Data.addActionListener(this::dataSelectTypePerformed);
185        select1Data.addActionListener(this::dataSelectTypePerformed);
186        select2Data.addActionListener(this::dataSelectTypePerformed);
187        select3Data.addActionListener(this::dataSelectTypePerformed);
188    
189    }
190    
191    private void addButtonListeners() {
192        
193        nnField = new JTextField("0", 5);
194        nnField.setToolTipText("<html>" + Bundle.getMessage("ToolTipNodeNumber") + "<br>" +
195            Bundle.getMessage("ToolTipPrefix") + "</html>");
196        
197        evField = new JTextField("0", 5);
198        evField.setToolTipText("<html>" + Bundle.getMessage("ToolTipEvent") + "<br>" +
199            Bundle.getMessage("ToolTipPrefix") + "</html>");
200        
201        nnField.addActionListener(this::sendEvButtonActionPerformed);        
202        evField.addActionListener(this::sendEvButtonActionPerformed);
203        sendEvButton.addActionListener(this::sendEvButtonActionPerformed);
204        
205        showEventData.addActionListener((ActionEvent e) -> {
206            eventDataPanel.setVisible(showEventData.isSelected());
207        });
208        
209        onButton.addActionListener(this::dataSelectTypePerformed);
210        offButton.addActionListener(this::dataSelectTypePerformed);
211        requestButton.addActionListener(this::dataSelectTypePerformed);
212    
213    }
214    
215    private void dataSelectTypePerformed(java.awt.event.ActionEvent e) {
216        
217        select0Data.setEnabled(!requestButton.isSelected());
218        select1Data.setEnabled(!requestButton.isSelected());
219        select2Data.setEnabled(!requestButton.isSelected());
220        select3Data.setEnabled(!requestButton.isSelected());
221        
222        if (requestButton.isSelected() || select0Data.isSelected()){
223            _selectedData = 0;
224        }
225        else if (select1Data.isSelected()) {
226            _selectedData = 1;
227        }
228        else if (select2Data.isSelected()) {
229            _selectedData = 2;
230        }
231        else if (select3Data.isSelected()) {
232            _selectedData = 3;
233        }
234        setWhichDataEnabled(_selectedData);
235    }
236    
237    private void setWhichDataEnabled(int numData) {
238        for (int i = 0; i < 3; i++) {
239            data[i].setEnabled(numData>i);
240        }
241    }
242    
243    private void sendEvButtonActionPerformed(java.awt.event.ActionEvent e) {
244
245        int nn = ValidationNotifications.parseBinDecHexByte(nnField.getText().trim(), 65535, decimalCheckBoxC.isSelected(), 
246            Bundle.getMessage("SendEventNodeError"),_mainPane);
247        if (nn == -1) { return; }
248        int ev = ValidationNotifications.parseBinDecHexByte(evField.getText().trim(), 65535, decimalCheckBoxC.isSelected(), 
249            Bundle.getMessage("SendEventInvalidError"),_mainPane);
250        if (ev == -1) { return; }
251        
252        CbusEvent event = new CbusEvent(_mainPane.getMemo(),nn,ev);
253        if (!checkData(event)){
254            return;
255        }
256        
257        if (onButton.isSelected()) {
258            event.sendOn();
259        }
260        else if (offButton.isSelected()){
261            event.sendOff();
262        }
263        else {
264            event.sendRequest();
265        }
266
267    }
268    
269    private boolean checkData( CbusEvent event ) {
270        event.setNumElements(_selectedData);
271        for (int i = 0; i < _selectedData; i++) {
272            int dat = ValidationNotifications.parseBinDecHexByte(data[i].getText().trim(), 256, 
273                decimalCheckBoxC.isSelected(), Bundle.getMessage("DbxErrorDialog",i+1),_mainPane);
274            if (dat == -1) { return false; }
275            event.setData(i+1, dat);
276        }
277        return true;
278    }
279
280    // private final static Logger log = LoggerFactory.getLogger(CbusSendEventPane.class);
281}