001package jmri.jmrix.openlcb;
002
003import java.util.HashMap;
004import java.util.Map;
005
006import jmri.InstanceManager;
007import jmri.ShutDownManager;
008import jmri.jmrix.openlcb.configurexml.OlcbEventNameStoreXml;
009
010import org.openlcb.EventID;
011import org.openlcb.EventNameStore;
012
013/**
014 * JMRI's implementation of part of the OpenLcb EventNameStore interface.
015 *
016 * @author Bob Jacobsen Copyright (C) 2024
017 */
018public final class OlcbEventNameStore implements EventNameStore {
019
020    public OlcbEventNameStore() {
021
022        readDetails();
023        
024        initShutdownTask();
025    }
026
027    private Map<String, EventID> nameToId = new HashMap<String, EventID>();
028    private Map<EventID, String> idToName = new HashMap<EventID, String>();
029    public boolean dirty = false;
030            
031    /**
032     * @param eventID The EventID being searched for
033     * @return The name associated with that EventID or the event ID in dotted hex
034     */
035    public String getEventName(EventID eventID) {
036        var name = idToName.get(eventID);
037        if (name == null || name.isEmpty()) return eventID.toShortString();
038        return name;
039    }
040    
041    /**
042     * @param eventID The EventID being searched for
043     * @return true if there is an associated name
044     */
045    public boolean hasEventName(EventID eventID) {
046        var name = idToName.get(eventID);
047        if (name == null || name.isEmpty()) return false;
048        return true;
049    }
050
051    /**
052     * @param name The event name being searched for
053     * @return The EventID associated with that name or an event ID constructed from the input
054     */
055    public EventID getEventID(String name) {
056        var eid = nameToId.get(name);
057        if (eid == null) return new EventID(name);
058        return eid;    
059    }
060        
061    /**
062     * @param name The event name being searched for
063     * @return true if an EventID is associated with that name
064     */
065    public boolean hasEventID(String name) {
066        var eid = nameToId.get(name);
067        if (eid == null) return false;
068        return true;    
069    }
070        
071    /**
072     * Create a new name to/from EventID association
073     * @param eventID associated EventID
074     * @param name  associated name
075     */
076    public void addMatch(EventID eventID, String name) {
077        nameToId.put(name, eventID);
078        idToName.put(eventID, name);
079        log.trace("setting dirty true");
080        dirty = true;
081    }
082    
083    /**
084     * Get all the EventIDs available
085     * @return Set of all available EventIDs
086     */
087    public java.util.Set<EventID> getMatches() {
088        return idToName.keySet();        
089    }
090
091    public void readDetails() {
092        log.debug("reading Event Name Details");
093        new OlcbEventNameStoreXml(this,"EventNames.xml").load();  // NOI18N
094        log.debug("...done reading Event Name details");
095    }
096
097    private Runnable shutDownTask = null;
098
099    protected void initShutdownTask(){
100        // Create shutdown task to save
101        log.debug("Register ShutDown task");
102        if (this.shutDownTask == null) {
103            this.shutDownTask = () -> {
104                // Save event name details prior to exit, if necessary
105                log.debug("Start writing event name details...");
106                try {
107                    writeEventNameDetails();
108                } catch (java.io.IOException ioe) {
109                    log.error("Exception writing event name", ioe);
110                }
111            };
112            InstanceManager.getDefault(ShutDownManager.class).register(this.shutDownTask);
113        }
114    }
115
116    public void writeEventNameDetails() throws java.io.IOException {
117        log.debug("storing event name map {}", dirty);
118        if (this.dirty) {
119            new OlcbEventNameStoreXml(this,"EventNames.xml").store();  // NOI18N
120            this.dirty = false;
121            log.debug("...done writing event name details");
122        }
123    }
124
125
126    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(OlcbEventNameStore.class);
127
128}