001package jmri.jmrit.etcs;
002
003import java.util.*;
004import java.util.concurrent.CopyOnWriteArrayList;
005
006import javax.annotation.Nonnull;
007
008import org.apiguardian.api.API;
009
010/**
011 * Class to represent DMI Track Points of Interest,
012 * i.e. Announcements and Orders.
013 * @author Steve Young Copyright (C) 2024
014 */
015@API(status=API.Status.EXPERIMENTAL)
016public class TrackSection {
017
018    /**
019     * Create a new TrackSection.
020     * @param sectionLength the Section Length.
021     * @param sectionSpeed the Section Speed.
022     * @param sectionGradient the Section Gradient.
023     */
024    public TrackSection(int sectionLength, int sectionSpeed, int sectionGradient){
025        length = sectionLength;
026        speed = sectionSpeed;
027        gradient = sectionGradient;
028        accouncements = new CopyOnWriteArrayList<>();
029    }
030
031    private final CopyOnWriteArrayList<TrackCondition> accouncements;
032    private int length;
033    private final int speed;
034    private final int gradient;
035
036    /**
037     * Get the Section Length.
038     * @return section length.
039     */
040    public int getLength(){
041        return length;
042    }
043
044    protected void setLength(int newLength) {
045        length = newLength;
046    }
047
048    /**
049     * Get the maximum speed for Section.
050     * @return maximum speed.
051     */
052    public int getSpeed(){
053        return speed;
054    }
055
056    /**
057     * Get the Section Gradient.
058     * @return gradient percentage for the Track Section.
059     */
060    public int getGradient(){
061        return gradient;
062    }
063
064    /**
065     * Add an Announcement to the Track Section.
066     * @param ac the Announcement to add.
067     * @throws  IllegalArgumentException if the Announcement
068     *          does not fit into the TrackSection.
069     */
070    public void addAnnouncement(@Nonnull TrackCondition ac ) {
071        if ( ac.getDistanceFromStart() >= this.getLength() ){
072            throw new IllegalArgumentException("Announcement " + ac.toString() +
073                " does not fit into track section");
074        }
075        accouncements.add(ac);
076    }
077
078    /**
079     * Get the List of Announcements for the Section.
080     * @return List of Announcements related to the TrackSection.
081     */
082    public List<TrackCondition> getAnnouncements() {
083        return new ArrayList<>(accouncements);
084        // return Collections.unmodifiableList(accouncements);
085        // return accouncements;
086    }
087
088    protected void advanceAnnouncements(int distance){
089        for (TrackCondition ac : accouncements) {
090            ac.setDistanceFromStart(ac.getDistanceFromStart()-distance);
091            if ( ac.getDistanceFromStart() < 0 ) {
092                accouncements.remove(ac);
093            }
094        }
095    }
096
097    @Override
098    public String toString(){
099        return "TrackSection Length:"+getLength()+" Speed:"+getSpeed()+" Gradient:"+getGradient();
100    }
101
102}