using System;
using System.Linq.Expressions;
using System.Reactive.Linq;
using System.Reflection;

namespace System.Reactive.Joins
{
	public class QueryablePattern<TSource1, TSource2, TSource3, TSource4> : QueryablePattern
	{
		internal QueryablePattern(Expression expression)
			: base(expression)
		{
		}

		public QueryablePattern<TSource1, TSource2, TSource3, TSource4, TSource5> And<TSource5>(IObservable<TSource5> other)
		{
			if (other == null)
			{
				throw new ArgumentNullException("other");
			}
			MethodInfo methodInfo = typeof(QueryablePattern<TSource1, TSource2, TSource3, TSource4>).GetMethod("And").MakeGenericMethod(new Type[] { typeof(TSource5) });
			return new QueryablePattern<TSource1, TSource2, TSource3, TSource4, TSource5>(Expression.Call(base.Expression, methodInfo, new Expression[] { Qbservable.GetSourceExpression<TSource5>(other) }));
		}

		public QueryablePlan<TResult> Then<TResult>(Expression<Func<TSource1, TSource2, TSource3, TSource4, TResult>> selector)
		{
			if (selector == null)
			{
				throw new ArgumentNullException("selector");
			}
			MethodInfo methodInfo = typeof(QueryablePattern<TSource1, TSource2, TSource3, TSource4>).GetMethod("Then").MakeGenericMethod(new Type[] { typeof(TResult) });
			return new QueryablePlan<TResult>(Expression.Call(base.Expression, methodInfo, new Expression[] { selector }));
		}
	}
}
