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

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

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

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