using System;
using System.Collections.Generic;

namespace System.Reactive.Joins
{
	internal class Plan<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> : Plan<TResult>
	{
		internal Pattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Expression { get; }

		internal Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> Selector { get; }

		internal Plan(Pattern<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> expression, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> selector)
		{
			this.Expression = expression;
			this.Selector = selector;
		}

		internal override ActivePlan Activate(Dictionary<object, IJoinObserver> externalSubscriptions, IObserver<TResult> observer, Action<ActivePlan> deactivate)
		{
			Action<Exception> action = new Action<Exception>(observer.OnError);
			JoinObserver<T1> firstJoinObserver = Plan<TResult>.CreateObserver<T1>(externalSubscriptions, this.Expression.First, action);
			JoinObserver<T2> secondJoinObserver = Plan<TResult>.CreateObserver<T2>(externalSubscriptions, this.Expression.Second, action);
			JoinObserver<T3> thirdJoinObserver = Plan<TResult>.CreateObserver<T3>(externalSubscriptions, this.Expression.Third, action);
			JoinObserver<T4> fourthJoinObserver = Plan<TResult>.CreateObserver<T4>(externalSubscriptions, this.Expression.Fourth, action);
			JoinObserver<T5> fifthJoinObserver = Plan<TResult>.CreateObserver<T5>(externalSubscriptions, this.Expression.Fifth, action);
			JoinObserver<T6> sixthJoinObserver = Plan<TResult>.CreateObserver<T6>(externalSubscriptions, this.Expression.Sixth, action);
			JoinObserver<T7> seventhJoinObserver = Plan<TResult>.CreateObserver<T7>(externalSubscriptions, this.Expression.Seventh, action);
			JoinObserver<T8> eighthJoinObserver = Plan<TResult>.CreateObserver<T8>(externalSubscriptions, this.Expression.Eighth, action);
			JoinObserver<T9> ninthJoinObserver = Plan<TResult>.CreateObserver<T9>(externalSubscriptions, this.Expression.Ninth, action);
			JoinObserver<T10> tenthJoinObserver = Plan<TResult>.CreateObserver<T10>(externalSubscriptions, this.Expression.Tenth, action);
			JoinObserver<T11> eleventhJoinObserver = Plan<TResult>.CreateObserver<T11>(externalSubscriptions, this.Expression.Eleventh, action);
			JoinObserver<T12> twelfthJoinObserver = Plan<TResult>.CreateObserver<T12>(externalSubscriptions, this.Expression.Twelfth, action);
			JoinObserver<T13> thirteenthJoinObserver = Plan<TResult>.CreateObserver<T13>(externalSubscriptions, this.Expression.Thirteenth, action);
			JoinObserver<T14> fourteenthJoinObserver = Plan<TResult>.CreateObserver<T14>(externalSubscriptions, this.Expression.Fourteenth, action);
			ActivePlan<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> activePlan = null;
			activePlan = new ActivePlan<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(firstJoinObserver, secondJoinObserver, thirdJoinObserver, fourthJoinObserver, fifthJoinObserver, sixthJoinObserver, seventhJoinObserver, eighthJoinObserver, ninthJoinObserver, tenthJoinObserver, eleventhJoinObserver, twelfthJoinObserver, thirteenthJoinObserver, fourteenthJoinObserver, delegate(T1 first, T2 second, T3 third, T4 fourth, T5 fifth, T6 sixth, T7 seventh, T8 eighth, T9 ninth, T10 tenth, T11 eleventh, T12 twelfth, T13 thirteenth, T14 fourteenth)
			{
				TResult tresult;
				try
				{
					tresult = this.Selector(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh, twelfth, thirteenth, fourteenth);
				}
				catch (Exception ex)
				{
					observer.OnError(ex);
					return;
				}
				observer.OnNext(tresult);
			}, delegate
			{
				firstJoinObserver.RemoveActivePlan(activePlan);
				secondJoinObserver.RemoveActivePlan(activePlan);
				thirdJoinObserver.RemoveActivePlan(activePlan);
				fourthJoinObserver.RemoveActivePlan(activePlan);
				fifthJoinObserver.RemoveActivePlan(activePlan);
				sixthJoinObserver.RemoveActivePlan(activePlan);
				seventhJoinObserver.RemoveActivePlan(activePlan);
				eighthJoinObserver.RemoveActivePlan(activePlan);
				ninthJoinObserver.RemoveActivePlan(activePlan);
				tenthJoinObserver.RemoveActivePlan(activePlan);
				eleventhJoinObserver.RemoveActivePlan(activePlan);
				twelfthJoinObserver.RemoveActivePlan(activePlan);
				thirteenthJoinObserver.RemoveActivePlan(activePlan);
				fourteenthJoinObserver.RemoveActivePlan(activePlan);
				deactivate(activePlan);
			});
			firstJoinObserver.AddActivePlan(activePlan);
			secondJoinObserver.AddActivePlan(activePlan);
			thirdJoinObserver.AddActivePlan(activePlan);
			fourthJoinObserver.AddActivePlan(activePlan);
			fifthJoinObserver.AddActivePlan(activePlan);
			sixthJoinObserver.AddActivePlan(activePlan);
			seventhJoinObserver.AddActivePlan(activePlan);
			eighthJoinObserver.AddActivePlan(activePlan);
			ninthJoinObserver.AddActivePlan(activePlan);
			tenthJoinObserver.AddActivePlan(activePlan);
			eleventhJoinObserver.AddActivePlan(activePlan);
			twelfthJoinObserver.AddActivePlan(activePlan);
			thirteenthJoinObserver.AddActivePlan(activePlan);
			fourteenthJoinObserver.AddActivePlan(activePlan);
			return activePlan;
		}
	}
}
