private LinkedComplexGap xGetCarIdx(LinkedComplexGap head, int carIdx)
        {
            LinkedComplexGap ret =
                xFind(head, i => i.CarIdx == carIdx, i => i.NextPosition, i => i.PreviousPosition);

            return(ret);
        }
        private LinkedComplexGap xGetLap(LinkedComplexGap head, int lapIndexToFind)
        {
            LinkedComplexGap ret =
                xFind(head, i => i.LapIndex == lapIndexToFind, i => i.NextLap, i => i.PreviousLap);

            return(ret);
        }
            private LinkedComplexGap CreateComplexGapForDriver(int lapNumber, int positionIndex)
            {
                LapCrossing      currentLC = temp[lapNumber][positionIndex];
                LinkedComplexGap cg        = new LinkedComplexGap()
                {
                    CarIdx         = currentLC.CarIdx,
                    CrossedAt      = currentLC.CrossedAt,
                    LapIndex       = lapNumber,
                    Position       = positionIndex + 1,
                    IsPitted       = currentLC.IsPitted,
                    IsOffTrack     = currentLC.IsOffTrack,
                    IsBlackFlagged = currentLC.IsBlackFlagged,
                    IsTimeInvalid  = currentLC.IsTimeInvalid
                };

                if (positionIndex > 0)
                {
                    FillComplexGapGaps(cg);
                }
                else
                {
                    cg.ToFirst    = new Gap();
                    cg.ToPrevious = new Gap();
                }

                return(cg);
            }
        private LinkedComplexGap xGet(int lapIndex, int carIdx)
        {
            LinkedComplexGap ret = this.lapHeads[lapIndex];

            ret = xGetCarIdx(ret, carIdx);

            return(ret);
        }
        internal static void LinkByPosition(LinkedComplexGap previous, LinkedComplexGap next)
        {
            Contract.Assert(previous != next);

            if (previous.NextPosition != null)
            {
                previous.NextPosition.PreviousPosition = null;
            }
            if (next.PreviousPosition != null)
            {
                next.PreviousPosition.NextPosition = null;
            }

            previous.NextPosition = next;
            next.PreviousPosition = previous;
        }
        internal static void LinkByLap(LinkedComplexGap previous, LinkedComplexGap next)
        {
            Contract.Assert(previous != next);

            if (previous.NextLap != null)
            {
                previous.NextLap.PreviousLap = null;
            }
            if (next.PreviousLap != null)
            {
                next.PreviousLap.NextLap = null;
            }

            previous.NextLap = next;
            next.PreviousLap = previous;
        }
        internal void AddLapLinkedComplexGaps(LinkedComplexGap first)
        {
            Contract.Assert(first.LapIndex == this.lapHeads.Count);
            LinkedComplexGap current = first;

            if (first.LapIndex != 0)
            {
                while (current != null)
                {
                    LinkedComplexGap prevLap = xGet(first.LapIndex - 1, first.CarIdx);

                    Contract.Assert(prevLap != null);

                    LinkedComplexGap.LinkByLap(prevLap, current);
                    current = current.NextPosition;
                }
            }

            this.lapHeads.Add(first);
        }
            private LinkedComplexGap CalculateLapAndReturnFirst(int lapNumber)
            {
                LinkedComplexGap first;
                LinkedComplexGap current;

                SortAllLapCrossings();

                LapCrossing firstTime = temp[lapNumber][0];

                first = CreateComplexGapForDriver(lapNumber, 0);

                LinkedComplexGap previous = first;

                for (int i = 1; i < temp[lapNumber].Count; i++)
                {
                    current = CreateComplexGapForDriver(lapNumber, i);
                    LinkedComplexGap.LinkByPosition(previous, current);
                    previous = current;
                }

                return(first);
            }
        private LinkedComplexGap xFind(LinkedComplexGap head, Func <LinkedComplexGap, bool> comparer,
                                       Func <LinkedComplexGap, LinkedComplexGap> forward, Func <LinkedComplexGap, LinkedComplexGap> backward)
        {
            LinkedComplexGap ret = null;

            ret = head;
            while (ret != null && comparer(ret) == false)
            {
                ret = forward(ret);
            }

            if (ret == null)
            {
                ret = head;
                while (ret != null && comparer(ret) == false)
                {
                    ret = backward(ret);
                }
            }

            return(ret);
        }