using System;
using System.Reactive.Disposables;

namespace System.Reactive.Linq.ObservableImpl
{
	internal sealed class CombineLatest<T1, T2, T3, T4, T5, TResult> : Producer<TResult, CombineLatest<T1, T2, T3, T4, T5, TResult>._>
	{
		public CombineLatest(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, Func<T1, T2, T3, T4, T5, TResult> resultSelector)
		{
			this._source1 = source1;
			this._source2 = source2;
			this._source3 = source3;
			this._source4 = source4;
			this._source5 = source5;
			this._resultSelector = resultSelector;
		}

		protected override CombineLatest<T1, T2, T3, T4, T5, TResult>._ CreateSink(IObserver<TResult> observer)
		{
			return new CombineLatest<T1, T2, T3, T4, T5, TResult>._(this._resultSelector, observer);
		}

		protected override void Run(CombineLatest<T1, T2, T3, T4, T5, TResult>._ sink)
		{
			sink.Run(this._source1, this._source2, this._source3, this._source4, this._source5);
		}

		private readonly IObservable<T1> _source1;

		private readonly IObservable<T2> _source2;

		private readonly IObservable<T3> _source3;

		private readonly IObservable<T4> _source4;

		private readonly IObservable<T5> _source5;

		private readonly Func<T1, T2, T3, T4, T5, TResult> _resultSelector;

		internal sealed class _ : CombineLatestSink<TResult>
		{
			public _(Func<T1, T2, T3, T4, T5, TResult> resultSelector, IObserver<TResult> observer)
				: base(5, observer)
			{
				this._resultSelector = resultSelector;
			}

			public void Run(IObservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5)
			{
				IDisposable[] array = new IDisposable[]
				{
					this._observer1 = new CombineLatestObserver<T1>(this._gate, this, 0),
					this._observer2 = new CombineLatestObserver<T2>(this._gate, this, 1),
					this._observer3 = new CombineLatestObserver<T3>(this._gate, this, 2),
					this._observer4 = new CombineLatestObserver<T4>(this._gate, this, 3),
					this._observer5 = new CombineLatestObserver<T5>(this._gate, this, 4)
				};
				this._observer1.SetResource(source1.SubscribeSafe(this._observer1));
				this._observer2.SetResource(source2.SubscribeSafe(this._observer2));
				this._observer3.SetResource(source3.SubscribeSafe(this._observer3));
				this._observer4.SetResource(source4.SubscribeSafe(this._observer4));
				this._observer5.SetResource(source5.SubscribeSafe(this._observer5));
				base.SetUpstream(StableCompositeDisposable.CreateTrusted(array));
			}

			protected override TResult GetResult()
			{
				return this._resultSelector(this._observer1.Value, this._observer2.Value, this._observer3.Value, this._observer4.Value, this._observer5.Value);
			}

			private readonly Func<T1, T2, T3, T4, T5, TResult> _resultSelector;

			private CombineLatestObserver<T1> _observer1;

			private CombineLatestObserver<T2> _observer2;

			private CombineLatestObserver<T3> _observer3;

			private CombineLatestObserver<T4> _observer4;

			private CombineLatestObserver<T5> _observer5;
		}
	}
}
