001package jmri.jmrix.loconet.uhlenbrock;
002
003import java.util.ArrayList;
004import java.util.List;
005
006import jmri.jmrix.loconet.LncvDevicesManager;
007import org.slf4j.Logger;
008import org.slf4j.LoggerFactory;
009
010import javax.annotation.concurrent.GuardedBy;
011
012/**
013 * Manage an array of LncvDevice items. See {@link LncvDevicesManager}
014 * Based on Lnsvf2Devices by B. Milhaupt
015 * @author Egbert Broerse 2020
016 */
017public class LncvDevices {
018
019    @GuardedBy("this")
020    private final List<LncvDevice> deviceList;
021
022    public LncvDevices() {
023        deviceList = new ArrayList<>();
024    }
025
026    /**
027     * Add a device that responded to a PROG_START request to the list of LNCV Devices.
028     *
029     * @param d the device object, containing its properties
030     * @return true if device was added, false if not eg it was already in the list
031     */
032    public synchronized boolean addDevice(LncvDevice d) {
033        if (!deviceExists(d)) {
034            deviceList.add(d);
035            log.debug("added device with prod {}, addr {}",
036                    d.getProductID(), d.getDestAddr());
037            return true;
038        } else {
039            log.debug("device already in list: prod {}, addr {}",
040                    d.getProductID(), d.getDestAddr());
041            return false;
042        }
043    }
044
045    public synchronized void removeAllDevices() {
046        deviceList.clear();
047    }
048
049    /**
050     * Get index of device with matching Mfg, ProdID, Num and
051     * Device Address.
052     * Where a deviceToBeFound parameter is -1, that parameter is not compared.
053     *
054     * @param deviceToBeFound Device we try to find in known LNCV devices list
055     * @return index of found device, else -1 if matching device not found
056     */
057    public synchronized int isDeviceExistant(LncvDevice deviceToBeFound) {
058        log.debug("Looking for a known LNCV device which matches characteristics: article {}, addr {}.",
059                deviceToBeFound.getProductID(),
060                deviceToBeFound.getDestAddr());
061        for (int i = 0; i < deviceList.size(); ++i) {
062            LncvDevice dev = deviceList.get(i);
063            log.trace("Comparing against known device: article {}, addr {}.",
064                    dev.getProductID(),
065                    deviceToBeFound.getDestAddr());
066            if ((deviceToBeFound.getProductID() == -1) ||
067                    (dev.getProductID() == deviceToBeFound.getProductID())) {
068                if ((deviceToBeFound.getDestAddr() == -1) ||
069                        (dev.getDestAddr() == deviceToBeFound.getDestAddr())) {
070                    log.debug("Match Found! Searched device matched against known device: article {}, addr {}.",
071                            dev.getProductID(),
072                            dev.getDestAddr());
073                    return i;
074                }
075            }
076        }
077        log.debug("No matching known device was found!");
078        return -1;
079    }
080
081    public boolean deviceExists(LncvDevice d) {
082        int i = isDeviceExistant(d);
083        log.debug("deviceExists found {}", i);
084        return (i >= 0);
085    }
086
087    public synchronized LncvDevice getDevice(int index) {
088        return deviceList.get(index);
089    }
090
091    public synchronized LncvDevice[] getDevices() {
092        LncvDevice[] d = {};
093        return deviceList.toArray(d);
094    }
095    public synchronized int size() {
096        return deviceList.size();
097    }
098
099    private final static Logger log = LoggerFactory.getLogger(LncvDevices.class);
100
101}