001package jmri.jmrit.etcs;
002
003import java.util.Date;
004import java.util.Random;
005
006import javax.annotation.CheckForNull;
007import javax.annotation.Nonnull;
008
009import jmri.InstanceManager;
010
011import org.apiguardian.api.API;
012
013/**
014 * Class to represent a CabMessage to send to the ERTMS DMI.
015 * @author Steve Young Copyright (C) 2024
016 */
017@API(status=API.Status.EXPERIMENTAL)
018public class CabMessage {
019
020    private String message;
021    private final Date sentDate;
022    private final int intValue;
023    private boolean ackRequired;
024    private Date confirmedDate = null;
025    private final String messageId;
026
027    private static Random random = new Random();
028    private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
029
030    /**
031     * Create a new CabMessage.
032     * @param msg String of message value
033     * @param intValue 1 if system status / important, 2 for auxiliary messages.
034     * @param ackReqd true if an acknowledgement is required, else false.
035     */
036    public CabMessage(String msg, int intValue, boolean ackReqd) {
037        this(generatedId(), msg, intValue, ackReqd );
038    }
039
040    /**
041     * Create a new CabMessage.
042     * @param messageId unique ID String.
043     * @param msg String of message value
044     * @param intValue 1 if system status / important, 2 for auxiliary messages.
045     * @param ackReqd true if an acknowledgement is required, else false.
046     */
047    public CabMessage(@Nonnull String messageId, String msg, int intValue, boolean ackReqd) {
048        this.messageId = messageId;
049        this.message = msg;
050        this.sentDate = InstanceManager.getDefault(jmri.Timebase.class).getTime();
051        this.intValue = intValue;
052        ackRequired = ackReqd;
053    
054    }
055
056    /**
057     * Get the Message String.
058     * @return String of the Message.
059     */
060    public String getMessage() {
061        return message;
062    }
063
064    /**
065     * Get the unique Message ID.
066     * @return the Message ID.
067     */
068    public String getMessageId() {
069        return messageId;
070    }
071
072    /**
073     * Get the Date that the Message was Sent.
074     * @return the date of message creation.
075     */
076    public Date getSentTime() {
077        return new Date(sentDate.getTime());
078    }
079
080    /**
081     * Get the Time the message was confirmed by the driver.
082     * @return time confirmed, else null if unconfirmed.
083     */
084    @CheckForNull
085    public Date getConfirmedTime() {
086        return new Date(confirmedDate.getTime());
087    }
088
089    /**
090     * Set the CabMessage as confirmed.
091     * Sets the confirmed time.
092     */
093    public void setConfirmed() {
094        confirmedDate = InstanceManager.getDefault(jmri.Timebase.class).getTime();
095        ackRequired = false;
096    }
097
098    /**
099     * Get if a driver acknowledgement is required for this message.
100     * @return true if acknowledgement required, else false.
101     */
102    public boolean getAckRequired() {
103        return ackRequired;
104    }
105
106    /**
107     * Get Message Group.
108     * 1 - system status messages and the important plain/fixed text messages
109     *         received from track-side.
110     * 2 - auxiliary plain/fixed text messages received from track-side.
111     * @return the group this message is in.
112     */
113    public int getGroup() {
114        return intValue;
115    }
116
117    private static String generatedId(){
118        int length = 20;
119        StringBuilder sb = new StringBuilder(length);
120        for (int i = 0; i < length; i++) {
121            int randomIndex = random.nextInt(CHARACTERS.length());
122            char randomChar = CHARACTERS.charAt(randomIndex);
123            sb.append(randomChar);
124        }
125        return sb.toString();
126    }
127
128}