001package jmri.jmrit.display.layoutEditor;
002
003import jmri.Block;
004
005/**
006 * TrackNode is a memo object specifying and returning track node
007 * information
008 * <p>
009 * Used in conjunction with ConnectivityUtil.java to return information about
010 * track nodes following a search of layout connectivity.
011 * <p>
012 * Track nodes are nodes in the layout connectivity diagram. They may be:
013 * positionable points - either anchor points that define a block boundary or
014 * end bumpers (end of a track), turnouts, -OR_ level crossings
015 * <p>
016 * The components of a TrackNode are: Node Object - the object reached by
017 * searching connectivity Node Type - connection types defined in Layout Editor,
018 * for example, TURNOUT_A, indicates a turnout connected at A (the throat of a
019 * RH, LH, or WYE turnout) Track Segment - the track segment connected at the
020 * connection point specified in Node Type Reached End Bumper - 'true' if the
021 * connectivity search has reached an end bumper (the end of the search track)
022 * before reaching a Node Object. 'false' otherwise. Node State - if the Node
023 * Object can have multiple states, for example, a turnout, this gives the state
024 * it was when finding this track node.
025 * <p>
026 * Actually you could think of an End Bumper as a 'Node', but End Bumpers are
027 * treated differently here. When an End Bumper is reached during a connectivity
028 * search, Track Segment is returned, Reached End Bumper is set true, and Node
029 * Object and Node Type, are not returned.
030 *
031 * @author Dave Duchamp Copyright (C) 2009
032 * @author George Warner Copyright (c) 2017-2018
033 */
034public class TrackNode {
035
036    public TrackNode(LayoutTrack node, HitPointType nodeType, TrackSegment segment, boolean endBumper,
037            int nodeState) {
038        _Node = node;
039        _NodeType = nodeType;
040        _TrackSegment = segment;
041        _ReachedEndBumper = endBumper;
042        _NodeState = nodeState;
043    }
044
045    // instance variables
046    LayoutTrack _Node = null;
047    HitPointType _NodeType = HitPointType.NONE;
048    TrackSegment _TrackSegment = null;
049    boolean _ReachedEndBumper = false;
050    int _NodeState = 0;
051
052    /**
053     * Set the node.
054     * @param node the layout track node.
055     */
056    public void setNode(LayoutTrack node) {
057        _Node = node;
058    }
059
060    public LayoutTrack getNode() {
061        return _Node;
062    }
063
064    public void setNodeType(HitPointType type) {
065        _NodeType = type;
066    }
067
068    public HitPointType getNodeType() {
069        return _NodeType;
070    }
071
072    public void setTrackSegment(TrackSegment s) {
073        _TrackSegment = s;
074    }
075
076    public TrackSegment getTrackSegment() {
077        return _TrackSegment;
078    }
079
080    public void setReachedEndBumper(boolean end) {
081        _ReachedEndBumper = end;
082    }
083
084    public boolean reachedEndOfTrack() {
085        return _ReachedEndBumper;
086    }
087
088    public int getNodeState() {
089        return _NodeState;
090    }
091
092    /*
093      Operational methods
094     */
095    /**
096     * Get the node block.
097     * @return the Block of the node Object at the nodeType position, may be null.
098     */
099    public Block getNodeBlock() {
100        if (HitPointType.POS_POINT == _NodeType) {
101            return _TrackSegment.getLayoutBlock().getBlock();
102        } else if (HitPointType.TURNOUT_A == _NodeType) {
103            return ((LayoutTurnout) _Node).getLayoutBlock().getBlock();
104        } else if (HitPointType.TURNOUT_B == _NodeType) {
105            return ((LayoutTurnout) _Node).getLayoutBlockB().getBlock();
106        } else if (HitPointType.TURNOUT_C == _NodeType) {
107            return ((LayoutTurnout) _Node).getLayoutBlockC().getBlock();
108        } else if (HitPointType.TURNOUT_D == _NodeType) {
109            return ((LayoutTurnout) _Node).getLayoutBlockD().getBlock();
110        } else if ((HitPointType.LEVEL_XING_A == _NodeType)
111                || (HitPointType.LEVEL_XING_C == _NodeType)) {
112            return ((LevelXing) _Node).getLayoutBlockAC().getBlock();
113        } else if ((HitPointType.LEVEL_XING_B == _NodeType)
114                || (HitPointType.LEVEL_XING_D == _NodeType)) {
115            return ((LevelXing) _Node).getLayoutBlockBD().getBlock();
116        }
117        return null;
118    }
119}