001package jmri.jmrix.can.cbus.eventtable;
002
003import java.util.ArrayList;
004import javax.annotation.Nonnull;
005import jmri.jmrix.can.CanSystemConnectionMemo;
006import jmri.jmrix.can.cbus.CbusEvent;
007import jmri.jmrix.can.cbus.CbusNameService;
008import org.slf4j.Logger;
009import org.slf4j.LoggerFactory;
010
011/**
012 * Class to provide access to the EventTableData.xml file.
013 * @author Steve Young Copyright (C) 2019
014 */
015public class CbusBasicEventTableModel extends javax.swing.table.AbstractTableModel {
016
017    static public final int NODE_COLUMN = 0;
018    static public final int EVENT_COLUMN = 1;
019    static public final int NAME_COLUMN = 2;
020    static public final int NODENAME_COLUMN = 3;
021    static public final int COMMENT_COLUMN = 4;
022    static public final int STATE_COLUMN = 5;
023
024    static public final int TOGGLE_BUTTON_COLUMN = 6;
025    static public final int ON_BUTTON_COLUMN = 7;
026    static public final int OFF_BUTTON_COLUMN = 8;
027    static public final int CANID_COLUMN = 9;
028    static public final int LATEST_TIMESTAMP_COLUMN = 10;
029    static public final int STATUS_REQUEST_BUTTON_COLUMN = 11;
030
031    static public final int SESSION_TOTAL_COLUMN = 12;
032    static public final int SESSION_ON_COLUMN = 13;
033    static public final int SESSION_OFF_COLUMN = 14;
034    static public final int SESSION_IN_COLUMN = 15;
035    static public final int SESSION_OUT_COLUMN = 16;
036
037    static public final int ALL_TOTAL_COLUMN = 17;
038    static public final int ALL_ON_COLUMN = 18;
039    static public final int ALL_OFF_COLUMN = 19;
040    static public final int ALL_IN_COLUMN = 20;
041    static public final int ALL_OUT_COLUMN = 21;
042
043    static public final int DELETE_BUTTON_COLUMN = 22;
044    static public final int STLR_ON_COLUMN = 23;
045    static public final int STLR_OFF_COLUMN = 24;
046
047    public final static int EVENT_DAT_1 = 25;
048    public final static int EVENT_DAT_2 = 26;
049    public final static int EVENT_DAT_3 = 27;
050
051    static public final int MAX_COLUMN = 28;
052
053    protected final CanSystemConnectionMemo _memo;
054    protected ArrayList<CbusTableEvent> _mainArray;
055    public final CbusEventTableAction ta;
056    public final static int[] INITIAL_COLS = new int[]{ 0,1,2,4,5,6,23,24 };
057
058    // list of Columns which may update on receipt of CanFrame.
059    static final int[] canFrameCols = new int[]{
060        CANID_COLUMN, LATEST_TIMESTAMP_COLUMN, STATE_COLUMN, TOGGLE_BUTTON_COLUMN,
061        SESSION_TOTAL_COLUMN, SESSION_IN_COLUMN, SESSION_OUT_COLUMN, SESSION_OFF_COLUMN, SESSION_ON_COLUMN,
062        ALL_TOTAL_COLUMN, ALL_ON_COLUMN, ALL_OFF_COLUMN, ALL_IN_COLUMN, ALL_OUT_COLUMN,
063        EVENT_DAT_1, EVENT_DAT_2, EVENT_DAT_3 };
064
065    public CbusBasicEventTableModel(CanSystemConnectionMemo memo) {
066        this(memo, 1);
067    }
068
069    public CbusBasicEventTableModel(CanSystemConnectionMemo memo, int initialRowSize) {
070        super();
071        _memo = memo;
072        _mainArray = new ArrayList<>(initialRowSize);
073        ta = new CbusEventTableAction( this);
074    }
075
076    /**
077     * {@inheritDoc}
078     */
079    @Override
080    public int getColumnCount() {
081        return MAX_COLUMN;
082    }
083
084    /**
085     * {@inheritDoc}
086     */
087    @Override
088    public int getRowCount() {
089        return _mainArray.size();
090    }
091
092    /**
093     * {@inheritDoc}
094     */
095    @Override
096    public Object getValueAt(int row, int col) {
097        switch (col) {
098            case NODE_COLUMN:
099                return _mainArray.get(row).getNn();
100            case EVENT_COLUMN:
101                return _mainArray.get(row).getEn();
102            case NAME_COLUMN:
103                return _mainArray.get(row).getName();
104            case NODENAME_COLUMN:
105                return new CbusNameService(_memo).getNodeName( _mainArray.get(row).getNn() );
106            case COMMENT_COLUMN:
107                return _mainArray.get(row).getComment();
108            case STATE_COLUMN:
109                return _mainArray.get(row).getState();
110            default:
111                return getValueAtPt2(row,col);
112        }
113    }
114
115    private Object getValueAtPt2(int row, int col) {
116        switch (col) {
117            case TOGGLE_BUTTON_COLUMN:  // on or off event  1 is on, 0 is off, null unknown
118                if ( _mainArray.get(row).getState()==CbusTableEvent.EvState.OFF ) {
119                    return Bundle.getMessage("CbusSendOn"); // NOI18N
120                } else {
121                    return Bundle.getMessage("CbusSendOff"); // NOI18N
122                }
123            case ON_BUTTON_COLUMN:
124                return Bundle.getMessage("CbusSendOn"); // NOI18N
125            case OFF_BUTTON_COLUMN:
126                return Bundle.getMessage("CbusSendOff");
127            case CANID_COLUMN:
128                return _mainArray.get(row).getEventCanId();
129            case LATEST_TIMESTAMP_COLUMN:
130                return _mainArray.get(row).getDate();
131            default:
132                return getValueAtPt3(row,col);
133        }
134    }
135
136    private Object getValueAtPt3(int row, int col) {
137        switch (col) {
138            case SESSION_TOTAL_COLUMN:
139                return (_mainArray.get(row).getSessionOnOff(true) + _mainArray.get(row).getSessionOnOff(false) );
140            case SESSION_ON_COLUMN:
141                return _mainArray.get(row).getSessionOnOff(true);
142            case SESSION_OFF_COLUMN:
143                return _mainArray.get(row).getSessionOnOff(false);
144            case SESSION_IN_COLUMN:
145                return _mainArray.get(row).getSessionInOut(true);
146            case SESSION_OUT_COLUMN:
147                return _mainArray.get(row).getSessionInOut(false);
148            default:
149                return getValueAtPt4(row,col);
150        }
151    }
152
153    private Object getValueAtPt4(int row, int col) {
154        switch (col) {
155            case ALL_TOTAL_COLUMN:
156                return (_mainArray.get(row).getTotalInOut(true) + _mainArray.get(row).getTotalInOut(false) );
157            case ALL_ON_COLUMN:
158                return _mainArray.get(row).getTotalOnOff(true);
159            case ALL_OFF_COLUMN:
160                return _mainArray.get(row).getTotalOnOff(false);
161            case ALL_IN_COLUMN:
162                return _mainArray.get(row).getTotalInOut(true);
163            case ALL_OUT_COLUMN:
164                return _mainArray.get(row).getTotalInOut(false);
165            default:
166                return getValueAtPt5(row,col);
167        }
168    }
169
170    private Object getValueAtPt5(int row, int col) {
171        switch (col) {
172            case STATE_COLUMN:
173                return _mainArray.get(row).getState();
174            case STATUS_REQUEST_BUTTON_COLUMN:
175                return Bundle.getMessage("StatusButton"); // NOI18N
176            case DELETE_BUTTON_COLUMN:
177                return Bundle.getMessage("ButtonDelete"); // NOI18N
178            case STLR_ON_COLUMN:
179                return _mainArray.get(row).getBeans(CbusTableEvent.EvState.ON);
180            case STLR_OFF_COLUMN:
181                return _mainArray.get(row).getBeans(CbusTableEvent.EvState.OFF);
182            default:
183                return getValueAtPt6(row,col);
184        }
185    }
186
187    private Object getValueAtPt6(int row, int col) {
188        switch (col) {
189            case EVENT_DAT_1:
190                return _mainArray.get(row).getData(1);
191            case EVENT_DAT_2:
192                return _mainArray.get(row).getData(2);
193            case EVENT_DAT_3:
194                return _mainArray.get(row).getData(3);
195            default:
196                return null;
197        }
198    }
199
200    /**
201     * {@inheritDoc}
202     */
203    @Override
204    public void setValueAt(Object value, int row, int col) {
205        switch (col) {
206            case NAME_COLUMN:
207                _mainArray.get(row).setName( (String) value );
208                break;
209            case COMMENT_COLUMN:
210                _mainArray.get(row).setComment( (String) value );
211                break;
212            case ON_BUTTON_COLUMN:
213                _mainArray.get(row).sendEvent(CbusTableEvent.EvState.ON);
214                break;
215            case OFF_BUTTON_COLUMN:
216                _mainArray.get(row).sendEvent(CbusTableEvent.EvState.OFF);
217                break;
218            default:
219                setValueAt2( value,  row,  col);
220        }
221    }
222
223    public void setValueAt2(Object value, int row, int col) {
224        switch (col) {
225            case TOGGLE_BUTTON_COLUMN:
226                _mainArray.get(row).sendEvent(CbusTableEvent.EvState.TOGGLE);
227                ta.updateGuiCell(row,col);
228                break;
229            case STATUS_REQUEST_BUTTON_COLUMN:
230                _mainArray.get(row).sendEvent(CbusTableEvent.EvState.REQUEST);
231                break;
232            default:
233                log.error("Invalid Column {}",col);
234                break;
235        }
236    }
237
238
239
240    /**
241     * Provide a new Event and add to Table.
242     * @param nn Node Number
243     * @param en Event Number
244     * @return New or existing table event.
245     */
246    @Nonnull
247    public CbusTableEvent provideEvent(int nn, int en){
248        if (getEventTableRow(nn,en)>-1){
249            return _mainArray.get(getEventTableRow(nn,en));
250        }
251        // not existing so creating new
252        CbusTableEvent newtabev = new CbusTableEvent(_memo,nn,en );
253        _mainArray.add(newtabev);
254        fireTableDataChanged();
255        return newtabev;
256    }
257
258    /**
259     * Do Node + Event check, returns -1 if not on table, otherwise the row id
260     * @since 4.13.3
261     * @param event int
262     * @param node int
263     * @return int of row, otherwise -1
264     */
265    public int getEventTableRow( int node, int event) {
266        return _mainArray.indexOf(new CbusEvent(node,event));
267    }
268
269    /**
270     * Get event name for an event in the table
271     * @param event int
272     * @param node int
273     * @return String of event name, empty string if not present.
274     */
275    @Nonnull
276    public String getEventName( int node, int event ) {
277        int row = getEventTableRow(node,event);
278        if (row > -1 ) {
279            return _mainArray.get(row).getName();
280        }
281        return "";
282    }
283
284    /**
285     * Get event String for an event in the table
286     * @param event int
287     * @param node int
288     * @return String of event name, empty string if not present.
289     */
290    @Nonnull
291    public String getEventString( int node, int event ) {
292        int row = getEventTableRow(node,event);
293        if (row > -1 ) {
294            return _mainArray.get(row).toString();
295        }
296        return("");
297    }
298
299    /**
300     * Get the core list containing all table events
301     * @return actual array of events
302     */
303    @Nonnull
304    public ArrayList<CbusTableEvent> getEvents() {
305        return new ArrayList<>(_mainArray);
306    }
307
308    private final static Logger log = LoggerFactory.getLogger(CbusBasicEventTableModel.class);
309
310}