using System;
using System.Reactive.Disposables;

namespace System.Reactive.Linq.ObservableImpl
{
	internal sealed class Zip<T1, T2, T3, T4, T5, TResult> : Producer<TResult, Zip<T1, T2, T3, T4, T5, TResult>._>
	{
		public Zip(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 Zip<T1, T2, T3, T4, T5, TResult>._ CreateSink(IObserver<TResult> observer)
		{
			return new Zip<T1, T2, T3, T4, T5, TResult>._(this._resultSelector, observer);
		}

		protected override void Run(Zip<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 _ : ZipSink<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[5];
				this._observer1 = new ZipObserver<T1>(this._gate, this, 0);
				array[0] = this._observer1;
				base.Queues[0] = this._observer1.Values;
				this._observer2 = new ZipObserver<T2>(this._gate, this, 1);
				array[1] = this._observer2;
				base.Queues[1] = this._observer2.Values;
				this._observer3 = new ZipObserver<T3>(this._gate, this, 2);
				array[2] = this._observer3;
				base.Queues[2] = this._observer3.Values;
				this._observer4 = new ZipObserver<T4>(this._gate, this, 3);
				array[3] = this._observer4;
				base.Queues[3] = this._observer4.Values;
				this._observer5 = new ZipObserver<T5>(this._gate, this, 4);
				array[4] = this._observer5;
				base.Queues[4] = this._observer5.Values;
				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.Values.Dequeue(), this._observer2.Values.Dequeue(), this._observer3.Values.Dequeue(), this._observer4.Values.Dequeue(), this._observer5.Values.Dequeue());
			}

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

			private ZipObserver<T1> _observer1;

			private ZipObserver<T2> _observer2;

			private ZipObserver<T3> _observer3;

			private ZipObserver<T4> _observer4;

			private ZipObserver<T5> _observer5;
		}
	}
}
