001package jmri.jmrix.can.cbus.swing.nodeconfig;
002
003import java.beans.PropertyChangeEvent;
004import java.beans.PropertyChangeListener;
005import java.util.Date;
006import javax.annotation.CheckForNull;
007import javax.swing.JTextField;
008import jmri.jmrix.can.cbus.node.CbusNode;
009import jmri.jmrix.can.cbus.node.CbusNodeFromBackup;
010import jmri.jmrix.can.cbus.node.CbusNodeConstants.BackupType;
011
012import org.slf4j.Logger;
013import org.slf4j.LoggerFactory;
014
015/**
016 * Table model for Backup Files.
017 * @author Steve Young Copyright (C) 2019
018 */
019public class CbusNodeBackupTableModel extends javax.swing.table.AbstractTableModel implements PropertyChangeListener  {
020
021    private CbusNode _nodeOfInterest;
022
023    public static final int DATE_COLUMN = 0;
024    public static final int STATUS_COLUMN = 1;
025    public static final int BYTES_COLUMN = 2;
026    public static final int COMMENT_COLUMN = 3;
027    public static final int DESCRIPTION_COLUMN = 4;
028
029    /**
030     * Create a new CbusNode Backup Table Model.
031     * @param nodeOfInterest Node containing the backups.
032     */
033    public CbusNodeBackupTableModel(CbusNode nodeOfInterest) {
034        super();
035        _nodeOfInterest = nodeOfInterest;
036    }
037    
038    public void setNode(CbusNode newNode){
039        _nodeOfInterest = newNode;
040        fireTableDataChanged();
041    }
042    
043    /** {@inheritDoc} */
044    @Override
045    public void propertyChange(PropertyChangeEvent ev){
046        if (ev.getPropertyName().equals("BACKUPS")) {
047            fireTableDataChanged();
048        }
049    }
050
051    /** {@inheritDoc} */
052    @Override
053    public Class<?> getColumnClass(int c) {
054        switch (c) {
055            case DATE_COLUMN:
056                return Date.class;
057            case STATUS_COLUMN:
058                return BackupType.class;
059            case BYTES_COLUMN:
060                return Integer.class;
061            case COMMENT_COLUMN:
062            case DESCRIPTION_COLUMN:
063            default:
064                return String.class;
065        }
066    }
067
068    /** {@inheritDoc} */
069    @Override
070    public int getColumnCount() {
071        return DESCRIPTION_COLUMN + 1;
072    }
073
074    /** {@inheritDoc} */
075    @Override
076    public int getRowCount() {
077        if ( _nodeOfInterest==null ){
078            return 0;
079        }
080        return (_nodeOfInterest.getNodeBackupManager().getBackups().size());
081    }
082
083    /** {@inheritDoc} */
084    @Override
085    public boolean isCellEditable(int r, int c) {
086        return c == COMMENT_COLUMN;
087    }
088
089    /** {@inheritDoc} */
090    @Override
091    public String getColumnName(int col) {
092        switch (col) {
093            case DATE_COLUMN:
094                return ("Date / Time");
095            case STATUS_COLUMN:
096                return ("Backup Integrity");
097            case BYTES_COLUMN:
098                return Bundle.getMessage("TotalBytes");
099            case COMMENT_COLUMN:
100                return Bundle.getMessage("ColumnComment");
101            default:
102                return "";
103        }
104    }
105
106    public static int getPreferredWidth(int col) {
107        switch (col) {
108            case DATE_COLUMN:
109                return new JTextField(20).getPreferredSize().width;
110            case STATUS_COLUMN:
111                return new JTextField(60).getPreferredSize().width;
112            case BYTES_COLUMN:
113                return new JTextField(8).getPreferredSize().width;
114            case COMMENT_COLUMN:
115                return new JTextField(80).getPreferredSize().width;
116            case DESCRIPTION_COLUMN:
117                return new JTextField(70).getPreferredSize().width;
118            default:
119                // fall through
120                break;
121        }
122        return new JTextField(8).getPreferredSize().width;
123    }
124
125    /** {@inheritDoc} */
126    @Override
127    public Object getValueAt(int r, int c) {
128        if (r > _nodeOfInterest.getNodeBackupManager().getBackups().size()) {
129            c = -1;
130        }
131        CbusNodeFromBackup lc = _nodeOfInterest.getNodeBackupManager().getBackups().get(r);
132        switch (c) {
133            case DATE_COLUMN:
134                return ((lc.getBackupTimeStamp()));
135            case STATUS_COLUMN:
136                return (lc.getBackupResult());
137            case BYTES_COLUMN:
138                return lc.getNodeStats().totalNodeFileBytes();
139            case COMMENT_COLUMN:
140                return (lc.getBackupComment());
141            case DESCRIPTION_COLUMN:
142                return getDescription(r, lc);
143            default:
144                return null;
145        }
146    }
147    
148    /**
149     * Get a description of the backup.
150     * 1st backup on file, not on network, else comparison with previous backup.
151     * @param r index of position in main array.
152     * @param lc the single backup.
153     * @return String with backup description.
154     */
155    private String getDescription(int r, CbusNodeFromBackup lc) {
156        if ( r == _nodeOfInterest.getNodeBackupManager().getBackups().size()-1 ){
157            return ("First Backup on File");
158        }
159        if (lc.getBackupResult() == BackupType.NOTONNETWORK) {
160            return BackupType.NOTONNETWORK.toString();
161        }
162        return lc.compareWithString(getPreviousBackup(r+1));
163    }
164    
165    /** 
166     * Get the previous actual backup to this one in array order, else null
167     */
168    @CheckForNull
169    private CbusNodeFromBackup getPreviousBackup(int arrayIndex){
170        for (int i = arrayIndex; i < _nodeOfInterest.getNodeBackupManager().getBackups().size()-1; i++) {
171            if (_nodeOfInterest.getNodeBackupManager().getBackups().get(i).getBackupResult() != BackupType.NOTONNETWORK) {
172                return _nodeOfInterest.getNodeBackupManager().getBackups().get(i);
173            }
174        }
175        return null;
176    }
177
178    /**
179     * If Backup Comment changes, update backup and save XML
180     * {@inheritDoc}
181     */
182    @Override
183    public void setValueAt(Object value, int row, int col) {
184        if (col == COMMENT_COLUMN) {
185            _nodeOfInterest.getNodeBackupManager().getBackups().get(row).setBackupComment(String.valueOf(value));
186            if(!_nodeOfInterest.getNodeBackupManager().doStore(false, _nodeOfInterest.getNodeStats().hasLoadErrors())){
187                log.error("Unable to save Backup User Comment to File");
188            }
189        }
190    }
191
192    private final static Logger log = LoggerFactory.getLogger(CbusNodeBackupTableModel.class);
193    
194}