001package jmri.jmrix.can.cbus.node;
002
003import java.beans.PropertyChangeListener;
004import java.beans.PropertyChangeEvent;
005import javax.swing.JButton;
006import jmri.jmrix.can.CanSystemConnectionMemo;
007import jmri.jmrix.can.cbus.CbusNameService;
008import jmri.jmrix.can.cbus.swing.nodeconfig.NodeConfigToolPane;
009import jmri.util.ThreadingUtil;
010
011import org.slf4j.Logger;
012import org.slf4j.LoggerFactory;
013
014/**
015 * Table data model for display of CBUS Nodes
016 *
017 * @author Steve Young (c) 2019
018 * 
019 */
020public class CbusNodeEventTableDataModel extends javax.swing.table.AbstractTableModel 
021    implements PropertyChangeListener {
022
023    private final CbusNameService nameService;
024    private CbusNode nodeOfInterest;
025    private final NodeConfigToolPane _mainpane;
026    
027    // column order needs to match list in column tooltips
028    static public final int NODE_NUMBER_COLUMN = 0;
029    static public final int EVENT_NUMBER_COLUMN = 1;
030    static public final int NODE_EDIT_BUTTON_COLUMN = 2;
031    static public final int NODE_NAME_COLUMN = 3;
032    static public final int EVENT_NAME_COLUMN = 4;
033    static public final int EV_VARS_COLUMN = 5;
034    static public final int EV_INDEX_COLUMN = 6;
035    static public final int MAX_COLUMN = 7;
036    
037    private final CanSystemConnectionMemo _memo;
038
039    public CbusNodeEventTableDataModel( NodeConfigToolPane mainpane, CanSystemConnectionMemo memo, int row, int column) {
040        
041        log.debug("Starting MERG CBUS Node Event Table");
042        _mainpane = mainpane;
043        _memo = memo;
044        nameService = new CbusNameService(memo);
045    }
046    
047    /**
048     * {@inheritDoc}
049     */
050    @Override
051    public int getRowCount() {
052        try {
053            return Math.max(0,nodeOfInterest.getNodeEventManager().getTotalNodeEvents() );
054        } catch (NullPointerException e) { // in case no node loaded
055            return 0;
056        }
057    }
058    
059    /**
060     * {@inheritDoc}
061     */
062    @Override
063    public int getColumnCount() {
064        return MAX_COLUMN;
065    }
066
067    /**
068     * {@inheritDoc}
069     */
070    @Override
071    public String getColumnName(int col) { // not in any order
072        switch (col) {
073            case EVENT_NUMBER_COLUMN:
074                return ("Event Number");
075            case NODE_NUMBER_COLUMN:
076                return ("Node Number");
077            case NODE_EDIT_BUTTON_COLUMN:
078                return ("Edit");
079            case NODE_NAME_COLUMN:
080                return ("Node Name");
081            case EVENT_NAME_COLUMN:
082                return ("Event Name");
083            case EV_VARS_COLUMN:
084                return ("Event Variables");
085            case EV_INDEX_COLUMN:
086                return ("Index");
087            default:
088                return "unknown " + col; // NOI18N
089        }
090    }
091    
092    /**
093     * {@inheritDoc}
094     */
095    @Override
096    public Class<?> getColumnClass(int col) {
097        switch (col) {
098            case EVENT_NUMBER_COLUMN:
099            case NODE_NUMBER_COLUMN:
100            case EV_INDEX_COLUMN:
101                return Integer.class;
102            case NODE_NAME_COLUMN:
103            case EVENT_NAME_COLUMN:
104            case EV_VARS_COLUMN:
105                return String.class;
106            case NODE_EDIT_BUTTON_COLUMN:
107                return JButton.class;
108            default:
109                return null;
110        }
111    }
112    
113    /**
114     * {@inheritDoc}
115     */
116    @Override
117    public boolean isCellEditable(int row, int col) {
118        switch (col) {
119            case NODE_EDIT_BUTTON_COLUMN:
120                return true;
121            default:
122                return false;
123        }
124    }
125
126    /**
127     * {@inheritDoc}
128     */
129    @Override
130    public Object getValueAt(int row, int col) {
131        
132        if ( nodeOfInterest == null ){
133            return null;
134        }
135        CbusNodeEvent toFetch = nodeOfInterest.getNodeEventManager().getNodeEventByArrayID(row);
136        if (toFetch==null){
137            return null;
138        }
139        
140        switch (col) {
141            case NODE_NUMBER_COLUMN:
142                return toFetch.getNn();
143            case EVENT_NUMBER_COLUMN:
144                return toFetch.getEn();
145            case NODE_EDIT_BUTTON_COLUMN:
146                return "Edit";
147            case NODE_NAME_COLUMN:
148                if ( !toFetch.getTempFcuNodeName().isEmpty() ) {
149                    return toFetch.getTempFcuNodeName();
150                }
151                else {
152                    return nameService.getNodeName( toFetch.getNn() );
153                }
154            case EVENT_NAME_COLUMN:
155                if ( !toFetch.getName().isEmpty() ) {
156                    return toFetch.getName();
157                }
158                else {
159                    return nameService.getEventName( toFetch.getNn(), toFetch.getEn()  );
160                }
161            case EV_VARS_COLUMN:
162                return toFetch.getEvVarString();
163            case EV_INDEX_COLUMN:
164                return toFetch.getIndex();
165            default:
166                return null;
167        }
168    }
169    
170    /**
171     * {@inheritDoc}
172     */
173    @Override
174    public void setValueAt(Object value, int row, int col) {
175        if (col == NODE_EDIT_BUTTON_COLUMN && _mainpane!=null) {
176            CbusNodeEvent ndEv = nodeOfInterest.getNodeEventManager().getNodeEventByArrayID(row);
177            ThreadingUtil.runOnGUIDelayed( ()->{
178                _mainpane.getEditEvFrame().initComponents(_memo, ndEv );                
179            },10);
180        }
181    }
182    
183    public void setNode( CbusNode node){
184        
185        if (node == nodeOfInterest){
186            return;
187        }
188        if ( nodeOfInterest != null ){
189            nodeOfInterest.removePropertyChangeListener(this);
190        }
191        nodeOfInterest = node;
192        if ( nodeOfInterest != null ){
193            nodeOfInterest.addPropertyChangeListener(this);
194        }
195        fireTableDataChanged();
196        
197    }
198    
199    /** {@inheritDoc} */
200    @Override
201    public void propertyChange(PropertyChangeEvent ev){
202        if (ev.getPropertyName().equals("SINGLEEVUPDATE")) {
203            int newValue = (Integer) ev.getNewValue();
204            fireTableRowsUpdated(newValue,newValue);
205        }
206        else if (ev.getPropertyName().equals("ALLEVUPDATE")) {
207            fireTableDataChanged();
208        }
209    }
210    
211    /**
212     * Removes Node Listener if still monitoring a Node.
213     */
214    public void dispose(){
215        setNode( null);
216    }
217    
218    /**
219     * Remove Row from table
220     * @param row int row number
221     */    
222    void removeRow(int row) {
223    //   _mainArray.remove(row);
224        ThreadingUtil.runOnGUI( ()->{ fireTableRowsDeleted(row,row); });
225    }
226    
227    private final static Logger log = LoggerFactory.getLogger(CbusNodeEventTableDataModel.class);
228}