using System;
using System.Collections.Generic;

namespace System.Reactive.Linq.ObservableImpl
{
	internal sealed class DistinctUntilChanged<TSource, TKey> : Producer<TSource, DistinctUntilChanged<TSource, TKey>._>
	{
		public DistinctUntilChanged(IObservable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
		{
			this._source = source;
			this._keySelector = keySelector;
			this._comparer = comparer;
		}

		protected override DistinctUntilChanged<TSource, TKey>._ CreateSink(IObserver<TSource> observer)
		{
			return new DistinctUntilChanged<TSource, TKey>._(this, observer);
		}

		protected override void Run(DistinctUntilChanged<TSource, TKey>._ sink)
		{
			sink.Run(this._source);
		}

		private readonly IObservable<TSource> _source;

		private readonly Func<TSource, TKey> _keySelector;

		private readonly IEqualityComparer<TKey> _comparer;

		internal sealed class _ : IdentitySink<TSource>
		{
			public _(DistinctUntilChanged<TSource, TKey> parent, IObserver<TSource> observer)
				: base(observer)
			{
				this._keySelector = parent._keySelector;
				this._comparer = parent._comparer;
			}

			public override void OnNext(TSource value)
			{
				TKey tkey;
				try
				{
					tkey = this._keySelector(value);
				}
				catch (Exception ex)
				{
					base.ForwardOnError(ex);
					return;
				}
				bool flag = false;
				if (this._hasCurrentKey)
				{
					try
					{
						flag = this._comparer.Equals(this._currentKey, tkey);
					}
					catch (Exception ex2)
					{
						base.ForwardOnError(ex2);
						return;
					}
				}
				if (!this._hasCurrentKey || !flag)
				{
					this._hasCurrentKey = true;
					this._currentKey = tkey;
					base.ForwardOnNext(value);
				}
			}

			private readonly Func<TSource, TKey> _keySelector;

			private readonly IEqualityComparer<TKey> _comparer;

			private TKey _currentKey;

			private bool _hasCurrentKey;
		}
	}
}
