using System;

namespace System.Reactive.Linq.ObservableImpl
{
	internal abstract class CombineLatestSink<TResult> : IdentitySink<TResult>, ICombineLatest
	{
		protected CombineLatestSink(int arity, IObserver<TResult> observer)
			: base(observer)
		{
			this._gate = new object();
			this._hasValue = new bool[arity];
			this._isDone = new bool[arity];
		}

		public void Next(int index)
		{
			if (!this._hasValueAll)
			{
				this._hasValue[index] = true;
				bool flag = true;
				bool[] hasValue = this._hasValue;
				for (int i = 0; i < hasValue.Length; i++)
				{
					if (!hasValue[i])
					{
						flag = false;
						IL_0032:
						this._hasValueAll = flag;
						goto IL_0039;
					}
				}
				goto IL_0032;
			}
			IL_0039:
			if (this._hasValueAll)
			{
				TResult result;
				try
				{
					result = this.GetResult();
				}
				catch (Exception ex)
				{
					base.ForwardOnError(ex);
					return;
				}
				base.ForwardOnNext(result);
				return;
			}
			bool flag2 = true;
			int j = 0;
			while (j < this._isDone.Length)
			{
				if (j == index || this._isDone[j])
				{
					j++;
				}
				else
				{
					flag2 = false;
					IL_008E:
					if (flag2)
					{
						base.ForwardOnCompleted();
						return;
					}
					return;
				}
			}
			goto IL_008E;
		}

		protected abstract TResult GetResult();

		public void Fail(Exception error)
		{
			base.ForwardOnError(error);
		}

		public void Done(int index)
		{
			this._isDone[index] = true;
			bool flag = true;
			bool[] isDone = this._isDone;
			for (int i = 0; i < isDone.Length; i++)
			{
				if (!isDone[i])
				{
					flag = false;
					IL_002A:
					if (flag)
					{
						base.ForwardOnCompleted();
					}
					return;
				}
			}
			goto IL_002A;
		}

		protected readonly object _gate;

		private bool _hasValueAll;

		private readonly bool[] _hasValue;

		private readonly bool[] _isDone;
	}
}
