001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.history;
003
004import java.util.ArrayList;
005import java.util.List;
006import java.util.concurrent.atomic.AtomicInteger;
007import java.util.stream.IntStream;
008
009import javax.swing.table.AbstractTableModel;
010
011import org.openstreetmap.josm.gui.history.TwoColumnDiff.Item.DiffItemType;
012
013/**
014 * Simple model storing "diff cells" in a list. Could probably have
015 * used a {@link javax.swing.table.DefaultTableModel} instead.
016 */
017class DiffTableModel extends AbstractTableModel {
018    private transient List<TwoColumnDiff.Item> rows = new ArrayList<>();
019    private transient int[] rowNumbers;
020    private boolean reversed;
021
022    public void setRows(List<TwoColumnDiff.Item> rows, boolean reversed) {
023        this.rows = rows;
024        this.reversed = reversed;
025        computeRowNumbers();
026        fireTableDataChanged();
027    }
028
029    @Override
030    public int getRowCount() {
031        return rows.size();
032    }
033
034    @Override
035    public int getColumnCount() {
036        return 1;
037    }
038
039    public boolean isReversed() {
040        return reversed;
041    }
042
043    @Override
044    public TwoColumnDiff.Item getValueAt(int rowIndex, int columnIndex) {
045        return rows.get(rowIndex);
046    }
047
048    public int getFirstChange() {
049        return IntStream.range(0, rows.size())
050                .filter(i -> rows.get(i).state != DiffItemType.SAME)
051                .findFirst().orElse(-1);
052    }
053
054    void computeRowNumbers() {
055        AtomicInteger rowNumber = new AtomicInteger(reversed ? rows.size() : 1);
056        rowNumbers = rows.stream().mapToInt(item -> {
057            if (item.state == DiffItemType.EMPTY) {
058                return -1;
059            } else if (reversed) {
060                return rowNumber.getAndDecrement();
061            } else {
062                return rowNumber.getAndIncrement();
063            }
064        }).toArray();
065    }
066
067    public int getRowNumber(int rowIndex) {
068        return rowNumbers[rowIndex];
069    }
070}