/// <summary>
        /// Determine where exactly the current trainpath node is on the track node
        /// </summary>
        /// <param name="startNode">The start node</param>
        /// <param name="nextNode">The next node (so also the direction can be understood)</param>
        /// <param name="tn">The tracknode connecting the startNode and nextNode</param>
        /// <param name="isForward">Output: whether going from startNode to nextNode is in the forward direction of the track</param>
        /// <param name="tvsiStart">Output: the track vector section index of where the startNode is</param>
        /// <param name="sectionOffsetStart">Output: the offset in the section (in the direction of the tracknode, not necessarily in the direction from startNode to nextNode)</param>
        private void DetermineSectionDetails(TrainpathNode startNode, TrainpathNode nextNode, TrackNode tn, out bool isForward, out int tvsiStart, out float sectionOffsetStart)
        {
            TrainpathVectorNode   currentNodeAsVector   = startNode as TrainpathVectorNode;
            TrainpathJunctionNode currentNodeAsJunction = startNode as TrainpathJunctionNode;

            if (currentNodeAsJunction != null)
            {   // we start at a junction node
                isForward = (currentNodeAsJunction.JunctionIndex == tn.JunctionIndexAtStart());
                if (isForward)
                {
                    tvsiStart          = 0;
                    sectionOffsetStart = 0;
                }
                else
                {
                    tvsiStart          = tn.TrVectorNode.TrVectorSections.Count() - 1;
                    sectionOffsetStart = SectionLengthAlongTrack(tn, tvsiStart);
                }
            }
            else
            {   // we start at a vector node
                isForward          = currentNodeAsVector.IsEarlierOnTrackThan(nextNode);
                tvsiStart          = currentNodeAsVector.TrackVectorSectionIndex;
                sectionOffsetStart = currentNodeAsVector.TrackSectionOffset;
            }
        }
        /// <summary>
        /// Add information from Trainpaths
        /// </summary>
        /// <param name="trackViewer"></param>
        private void AddTrainpathStatus(TrackViewer trackViewer)
        {
            if (Properties.Settings.Default.statusShowTrainpath && (trackViewer.PathEditor != null))
            {
                if (trackViewer.PathEditor.HasValidPath)
                {
                    //gather some info on path status
                    List <string> statusItems = new List <string>();

                    if (trackViewer.PathEditor.HasEndingPath)
                    {
                        statusItems.Add("good end");
                    }
                    if (trackViewer.PathEditor.HasBrokenPath)
                    {
                        statusItems.Add("broken");
                    }
                    if (trackViewer.PathEditor.HasModifiedPath)
                    {
                        statusItems.Add("modified");
                    }
                    if (trackViewer.PathEditor.HasStoredTail)
                    {
                        statusItems.Add("stored tail");
                    }

                    string pathStatus = String.Join(", ", statusItems.ToArray());

                    ORTS.TrackViewer.Editing.TrainpathNode curNode = trackViewer.PathEditor.CurrentNode;

                    statusAdditional.Text += string.Format(System.Globalization.CultureInfo.CurrentCulture,
                                                           " {0} ({4}): TVNs=[{1} {2}] (type={3})",
                                                           trackViewer.PathEditor.FileName, curNode.NextMainTvnIndex, curNode.NextSidingTvnIndex,
                                                           curNode.NodeType, pathStatus);

                    if (curNode.IsBroken)
                    {
                        statusAdditional.Text += string.Format(System.Globalization.CultureInfo.CurrentCulture,
                                                               " Broken: {0} ", curNode.BrokenStatusString());
                    }
                    TrainpathVectorNode curVectorNode = curNode as TrainpathVectorNode;
                    if (curVectorNode != null && curNode.NodeType == TrainpathNodeType.Stop)
                    {
                        statusAdditional.Text += string.Format(System.Globalization.CultureInfo.CurrentCulture,
                                                               " (wait-time={0}s)",
                                                               curVectorNode.WaitTimeS);
                    }
                }
                else
                {
                    statusAdditional.Text += "Invalid path";
                }
            }
        }
        /// <summary>
        /// Determine if the path from currentNode to nextNode is in the forward direction of the track (along main path)
        /// </summary>
        private bool DetermineIfForward(TrainpathNode currentNode, TrainpathNode nextNode)
        {   // It would be nice if we could separate this into different classes for vector and junction, but this would mean creating three additional classes for only a few methods
            TrainpathVectorNode currentNodeAsVector = currentNode as TrainpathVectorNode;

            if (currentNodeAsVector != null)
            {
                return(currentNodeAsVector.IsEarlierOnTrackThan(nextNode));
            }
            else
            {
                TrainpathJunctionNode currentNodeAsJunction = currentNode as TrainpathJunctionNode;
                return(currentNodeAsJunction.JunctionIndex == trackDB.TrackNodes[currentNode.NextMainTvnIndex].JunctionIndexAtStart());
            }
        }
        /// <summary>
        /// Determine the index of the trackvectorsection of the node in the track defined by the track vector node
        /// </summary>
        /// <param name="node">The node for which to determine the track vector section index</param>
        /// <param name="tvn">Track vector index of which we want to find the section</param>
        /// <returns></returns>
        private int DetermineTrackVectorSection(TrainpathNode node, int tvn)
        { // It would be nice if we could separate this into different classes for vector and junction, but this would mean creating three additional classes for only a few methods
            TrainpathVectorNode nodeAsVector = node as TrainpathVectorNode;

            if (nodeAsVector != null)
            {
                return(nodeAsVector.TrackVectorSectionIndex);
            }
            else
            {
                TrainpathJunctionNode currentNodeAsJunction = node as TrainpathJunctionNode;
                if (currentNodeAsJunction.JunctionIndex == trackDB.TrackNodes[node.NextMainTvnIndex].JunctionIndexAtStart())
                {
                    return(0);
                }
                else
                {
                    return(trackDB.TrackNodes[node.NextMainTvnIndex].TrVectorNode.TrVectorSections.Count() - 1);
                }
            }
        }