using System;
using System.Reactive.Disposables;

namespace System.Reactive.Concurrency
{
	internal sealed class UserWorkItem<TState> : IDisposable
	{
		public UserWorkItem(IScheduler scheduler, TState state, Func<IScheduler, TState, IDisposable> action)
		{
			this._state = state;
			this._action = action;
			this._scheduler = scheduler;
		}

		public void Run()
		{
			if (!Disposable.GetIsDisposed(ref this._cancelRunDisposable))
			{
				Disposable.SetSingle(ref this._cancelRunDisposable, this._action(this._scheduler, this._state));
			}
		}

		public IDisposable CancelQueueDisposable
		{
			get
			{
				return Disposable.GetValue(ref this._cancelQueueDisposable);
			}
			set
			{
				Disposable.SetSingle(ref this._cancelQueueDisposable, value);
			}
		}

		public void Dispose()
		{
			Disposable.TryDispose(ref this._cancelQueueDisposable);
			Disposable.TryDispose(ref this._cancelRunDisposable);
		}

		private IDisposable _cancelRunDisposable;

		private IDisposable _cancelQueueDisposable;

		private readonly TState _state;

		private readonly IScheduler _scheduler;

		private readonly Func<IScheduler, TState, IDisposable> _action;
	}
}
