/// <summary> /// Calculates the adapted talk duration for specified talk id /// </summary> /// <param name="itemId">Talk Id</param> /// <returns>Adapted time (or null if time is not adapted)</returns> public TimeSpan?CalculateAdaptedDuration(int itemId) { var talk = _scheduleService.GetTalkScheduleItem(itemId); if (talk == null) { return(null); } Log.Logger.Debug($"Calculating adapted talk duration for item {talk.Name}"); EnsureMeetingStartTimeIsSet(talk); if (_meetingStartTimeUtc == null) { return(null); } var adaptiveMode = _optionsService.GetAdaptiveMode(); Log.Logger.Debug($"Adaptive mode = {adaptiveMode}"); if (adaptiveMode == AdaptiveMode.None || !talk.AllowAdaptive) { return(null); } var mtgEnd = GetPlannedMeetingEnd(); var totalTimeRemaining = mtgEnd - _dateTimeService.UtcNow(); var remainingProgramTimeRequired = GetRemainingProgramTimeRequired(talk); var deviation = totalTimeRemaining - remainingProgramTimeRequired; if (!IsDeviationSignificant(deviation)) { return(null); } if (adaptiveMode != AdaptiveMode.TwoWay && totalTimeRemaining >= remainingProgramTimeRequired) { // there is time in hand and we don't want to adaptively increase talk durations. return(null); } var remainingAdaptiveTime = CalculateRemainingAdaptiveTimerValues(talk); Log.Logger.Debug($"Remaining time = {remainingAdaptiveTime}"); var fractionToApplyToThisTalk = talk.GetPlannedDurationSeconds() / remainingAdaptiveTime.TotalSeconds; Log.Logger.Debug($"Fraction to apply = {fractionToApplyToThisTalk:F2}"); var secondsToApply = deviation.TotalSeconds * fractionToApplyToThisTalk; Log.Logger.Debug($"Seconds to add = {secondsToApply:F1}"); return(talk.ActualDuration.Add(TimeSpan.FromSeconds(secondsToApply))); }