001package jmri;
002
003import java.util.ArrayList;
004import org.slf4j.Logger;
005import org.slf4j.LoggerFactory;
006
007/**
008 * This class holds information and options for a Section when assigned to a
009 * Transit. Corresponds to an allocatable "Section" of track assigned to a
010 * Transit.
011 * <p>
012 * A TransitSection holds the following information: Section ID Section
013 * Direction Sequence number of Section within the Transit Special actions list
014 * for train in this Section, if requested (see TransitSectionAction.java)
015 * Whether this Section is a primary section or an alternate section
016 * <p>
017 * A TransitSection is referenced via a list in its parent Transit, and is
018 * stored on disk when its parent Transit is stored.
019 * <p>
020 * Provides for delayed initialization of Section when loading panel files, so
021 * that this is not dependent on order of items in the panel file.
022 *
023 * @author Dave Duchamp Copyright (C) 2008
024 */
025public class TransitSection {
026
027    /**
028     * Create a TransitSection. This calls the alternate constructor with false
029     * for the alt value.
030     *
031     * @param s         the section to add to the transit
032     * @param seq       the sequence number of the section in the transit
033     * @param direction the direction of travel within the transit
034     */
035    public TransitSection(jmri.Section s, int seq, int direction) {
036        this(s, seq, direction, false);
037    }
038
039    /**
040     * Create an alternate or primary TransitSection.
041     *
042     * @param s         the section to add to the transit
043     * @param seq       the sequence number of the section in the transit
044     * @param direction the direction of travel within the transit
045     * @param alt       true if the section is an alternate; false if section is
046     *                  primary or has no alternates
047     */
048    public TransitSection(jmri.Section s, int seq, int direction, boolean alt) {
049        mSection = s;
050        mSequence = seq;
051        mDirection = direction;
052        mAlternate = alt;
053    }
054
055    /**
056     * Create an alternate or primary TransitSection, and defined as safe or not
057     *
058     * @param s         the section to add to the transit
059     * @param seq       the sequence number of the section in the transit
060     * @param direction the direction of travel within the transit
061     * @param alt       true if the section is an alternate; false if section is
062     *                  primary or has no alternates
063     * @param safe      true if this is a safe section. When dispatcher by safe sections
064     *                  a train is dispatched safe section to safe section with all intervening sections available.
065     * @param stopAllocatingSensorName If this sensor is present, valid, and Active allocation will stop until
066     *                  it is no longer Active.
067     */
068    public TransitSection(jmri.Section s, int seq, int direction, boolean alt, boolean safe, String stopAllocatingSensorName) {
069        mSection = s;
070        mSequence = seq;
071        mDirection = direction;
072        mAlternate = alt;
073        mSafe = safe;
074        mStopAllocatingSensorName = stopAllocatingSensorName;
075    }
076
077    /**
078     * Create an alternate or primary TransitSection with a delayed
079     * initialization.
080     *
081     * @param secName   the name of the section to add to the transit
082     * @param seq       the sequence number of the section in the transit
083     * @param direction the direction of travel within the transit
084     * @param alt       true if the section is an alternate; false if section is
085     *                  primary or has no alternates
086     */
087    public TransitSection(String secName, int seq, int direction, boolean alt) {
088        tSectionName = secName;
089        mSequence = seq;
090        mDirection = direction;
091        mAlternate = alt;
092        needsInitialization = true;
093    }
094
095    /**
096     * Create an alternate or primary TransitSection with a delayed
097     * initialization.
098     *
099     * @param secName   the name of the section to add to the transit
100     * @param seq       the sequence number of the section in the transit
101     * @param direction the direction of travel within the transit
102     * @param alt       true if the section is an alternate; false if section is
103     *                  primary or has no alternates
104     * @param safe      true if this is a safe section. When dispatcher by safe sections
105     *                  a train is dispatched safe section to safe section with all intervening sections available.
106     * @param stopAllocatingSensorName If this sensor is present, valid, and Active allocation will stop until
107     *                  it is no longer Active.
108     */
109    public TransitSection(String secName, int seq, int direction, boolean alt, boolean safe, String stopAllocatingSensorName) {
110        tSectionName = secName;
111        mSequence = seq;
112        mDirection = direction;
113        mAlternate = alt;
114        mSafe = safe;
115        mStopAllocatingSensorName = stopAllocatingSensorName;
116        needsInitialization = true;
117    }
118
119    // instance variables
120    private Section mSection = null;
121    private int mSequence = 0;
122    private int mDirection = 0;
123    private final ArrayList<TransitSectionAction> mTransitSectionActionList = new ArrayList<>();
124    private boolean mAlternate = false;
125    private boolean mSafe = false;
126    private String mStopAllocatingSensorName = "";
127
128    // temporary variables and method for delayed initialization of Section
129    private String tSectionName = "";
130    private boolean needsInitialization = false;
131
132    private void initialize() {
133        if (tSectionName.equals("null")) {
134            log.error("Null Section Name when initializing a TransitSection");
135        } else {
136            mSection = InstanceManager.getDefault(jmri.SectionManager.class).getSection(tSectionName);
137            if (mSection == null) {
138                log.error("Missing Section - {} - when initializing a TransitSection", tSectionName);
139            }
140        }
141        needsInitialization = false;
142    }
143
144    private boolean temporary = false;
145
146    public void setTemporary(boolean boo) {
147        temporary = boo;
148    }
149
150    public boolean isTemporary() {
151        return temporary;
152    }
153
154    /**
155     * Get the associated section.
156     *
157     * @return the section or null if no section is associated with this
158     *         TransitSection
159     */
160    public Section getSection() {
161        if (needsInitialization) {
162            initialize();
163        }
164        return mSection;
165    }
166
167    public String getSectionName() {
168        if (needsInitialization) {
169            initialize();
170        }
171        String s = mSection.getSystemName();
172        String u = mSection.getUserName();
173        if ((u != null) && (!u.isEmpty())) {
174            return (s + "( " + u + " )");
175        }
176        return s;
177    }
178
179    // Note: once TransitSection is created, Section and its sequence and direction may not be changed.
180    public int getDirection() {
181        return mDirection;
182    }
183
184    public int getSequenceNumber() {
185        return mSequence;
186    }
187
188    public void addAction(TransitSectionAction act) {
189        mTransitSectionActionList.add(act);
190    }
191
192    public boolean isAlternate() {
193        return mAlternate;
194    }
195
196    public void setAlternate(boolean alt) {
197        mAlternate = alt;
198    }
199
200    public boolean isSafe() {
201        return mSafe;
202    }
203
204    public void setSafe(boolean safe) {
205        mSafe = safe;
206    }
207
208    public String getStopAllocatingSensor() {
209        return mStopAllocatingSensorName;
210    }
211
212    public void setStopAllocatingSensor(String stopAllocatingSensor ) {
213        mStopAllocatingSensorName = stopAllocatingSensor;
214    }
215
216
217    /**
218     * Get a list of the actions for this TransitSection
219     *
220     * @return a list of actions or an empty list if there are no actions
221     */
222    public ArrayList<TransitSectionAction> getTransitSectionActionList() {
223        return new ArrayList<>(mTransitSectionActionList);
224    }
225
226    private final static Logger log = LoggerFactory.getLogger(TransitSection.class);
227}