using System;
using System.Collections;
using System.Runtime.CompilerServices;
using UnityEngine;
using System.Threading;
using System.Threading.Tasks;
using UnityAsync.Awaiters;
using Object = UnityEngine.Object;
namespace UnityAsync
{
	public static class Extensions
	{
		/// 
		/// Link the 's lifespan to a  and
		/// configure the type of update cycle it should be evaluated on.
		/// 
		/// A continuation with updated params.
		public static AwaitInstructionAwaiter ConfigureAwait(this T i, Object parent, FrameScheduler scheduler) where T : IAwaitInstruction
			=> new AwaitInstructionAwaiter(i, parent, scheduler);
		/// 
		/// Link the 's lifespan to a .
		/// 
		/// A continuation with updated params.
		public static AwaitInstructionAwaiter ConfigureAwait(this T i, Object parent) where T : IAwaitInstruction
			=> new AwaitInstructionAwaiter(i, parent, FrameScheduler.Update);
		/// 
		/// Configure the type of update cycle it should be evaluated on.
		/// 
		/// A continuation with updated params.
		public static AwaitInstructionAwaiter ConfigureAwait(this T i, FrameScheduler scheduler) where T : IAwaitInstruction
			=> new AwaitInstructionAwaiter(i, scheduler);
		
		/// 
		/// Link the 's lifespan to a
		///  and configure the type of update cycle it should be
		/// evaluated on.
		/// 
		/// A continuation with updated params.
		public static AwaitInstructionAwaiter ConfigureAwait(this T i, CancellationToken cancellationToken, FrameScheduler scheduler) where T : IAwaitInstruction
			=> new AwaitInstructionAwaiter(i, cancellationToken, scheduler);
		/// 
		/// Link the 's lifespan to a .
		/// 
		/// A continuation with updated params.
		public static AwaitInstructionAwaiter ConfigureAwait(this T i, CancellationToken cancellationToken) where T : struct, IAwaitInstruction
			=> new AwaitInstructionAwaiter(i, cancellationToken, FrameScheduler.Update);
		/// 
		/// Encapsulate the  in a 
		/// so that it can be yielded in an IEnumerator coroutine.
		/// 
		public static TaskYieldInstruction AsYieldInstruction(this Task t) => new TaskYieldInstruction(t);
		
		/// 
		/// Encapsulate the  in a 
		/// so that it can be yielded in an IEnumerator coroutine. The result can be obtained through
		///  after yielding.
		/// 
		public static TaskYieldInstruction AsYieldInstruction(this Task t) => new TaskYieldInstruction(t);
		public static SynchronizationContextAwaiter GetAwaiter(this SynchronizationContext s) => new SynchronizationContextAwaiter(s);
		public static IEnumeratorAwaiter GetAwaiter(this IEnumerator e) => new IEnumeratorAwaiter(e);
		public static YieldInstructionAwaiter GetAwaiter(this YieldInstruction y) => new YieldInstructionAwaiter(y);
		public static ResourceRequestAwaiter GetAwaiter(this ResourceRequest r) => new ResourceRequestAwaiter(r);
		public static AsyncOperationAwaiter GetAwaiter(this AsyncOperation r) => new AsyncOperationAwaiter(r);
		
		public static AwaitInstructionAwaiter GetAwaiter(this T i) where T : struct, IAwaitInstruction => new AwaitInstructionAwaiter(i);
		
		public static AwaitInstructionAwaiter GetAwaiter(in this AwaitInstructionAwaiter a) where T : IAwaitInstruction => a;
	}
}