internal static bool HasSameLoco(this IEnumerable <VehicleSchedule> me, StationCall one, StationCall another)
        {
            var foundOne   = me.FindVehicleSchedule(one);
            var foundOther = me.FindVehicleSchedule(another);

            return(!(foundOne is null) && !(foundOther is null) && foundOne == foundOther);
        }
        public static IEnumerable <Message> GetValidationErrors(this StationCall me)
        {
            var result = new List <Message>();

            if (me.Arrival > me.Departure)
            {
                result.Add(Message.Warning(string.Format(CultureInfo.CurrentCulture, Resources.Strings.ArrivalIsAfterDeparture, me.Track.Station.Name, me.Arrival, me.Departure)));
            }
            return(result);
        }
 internal void Add(StationCall call)
 {
     if (call == null)
     {
         throw new ArgumentNullException(nameof(call));
     }
     if (Calls.Contains(call))
     {
         return;
     }
     Calls.Add(call);
 }
 public void Add(StationCall call)
 {
     if (call == null)
     {
         throw new ArgumentNullException(nameof(call));
     }
     if (Calls.Contains(call))
     {
         return;
     }
     call.Train          = this;
     call.SequenceNumber = lastSequenceNumber++;
     Calls.Add(call);
 }
        }                            //For deserialzation.

        public StretchPassing(StationCall from, StationCall to, bool isOdd)
        {
            if (from == null)
            {
                throw new ArgumentNullException(nameof(from));
            }
            if (to == null)
            {
                throw new ArgumentNullException(nameof(to));
            }
            if (!from.Train.Equals(to.Train))
            {
                throw new TimetableException($"From and to station call must be on the same train: from={from}, to={to}");
            }
            Train = from.Train;
            From  = from;
            To    = to;
            IsOdd = isOdd;
        }
        internal static (bool, IEnumerable <StationCall>) GetConflicts(this StationTrack me, StationCall call, IEnumerable <StationCall> withCalls, IEnumerable <VehicleSchedule> locos)
        {
            if (me.Calls.Count == 0)
            {
                return(false, null);
            }
            var conflictingCalls = withCalls
                                   .Where(c => !locos.HasSameLoco(call, c) && (
                                              (call.Departure > c.Arrival && call.Departure <= c.Departure) ||
                                              (call.Arrival >= c.Arrival && call.Arrival < c.Departure)));

            if (conflictingCalls.Any())
            {
                return(true, conflictingCalls);
            }
            return(false, null);
        }
        private static IEnumerable <(StationCall one, StationCall other)> GetConflicts(this StationCall me, IEnumerable <StationCall> remaining, IEnumerable <VehicleSchedule> locos)
        {
            var result            = new List <(StationCall, StationCall)>();
            var conflictingWithMe = remaining.Where(r => r.Track.Equals(me.Track) && !r.Train.Equals(me.Train) && r.Arrival > me.Departure && r.Departure < me.Arrival && !locos.HasSameLoco(r, me)).ToList();

            result.AddRange(conflictingWithMe.Select(c => (me, c)));
            if (remaining.Count() > 1)
            {
                result.AddRange(GetConflicts(remaining.First(), remaining.Skip(1), locos));
            }
            return(result);
        }
 internal static bool ContainsCall(this TrainPart me, StationCall call)
 {
     return(me.Train == call.Train && call.SequenceNumber >= me.From.SequenceNumber && call.SequenceNumber <= me.To.SequenceNumber);
 }
 internal static VehicleSchedule FindVehicleSchedule(this IEnumerable <VehicleSchedule> me, StationCall call)
 {
     if (me == null)
     {
         return(null);
     }
     foreach (var schedule in me.Where(s => s.IsLoco))
     {
         foreach (var part in schedule.Parts)
         {
             if (part.ContainsCall(call))
             {
                 return(schedule);
             }
         }
     }
     return(null);
 }