<#@ output extension="cs"
#><#@ template language="C#" hostspecific="True"
#><#@ assembly name="System.Core"
#><#@ import namespace="System"
#><#@ import namespace="System.Linq"
#><#@ include file="..\..\..\DelegateGenerator.ttinclude"
#>// Copyright (C) 2003-2010 Xtensive LLC.
// All rights reserved.
// For conditions of distribution and use, see license.
// Created by: Denis Krjuchkov
// Created:    2010.03.10

using System;
using System.Reflection;
using Xtensive.Core;
using Xtensive.Reflection;

namespace Xtensive.Orm.Linq.MemberCompilation
{
  partial class MemberCompilerProvider<T>
  {
    private static Func<MemberInfo, T, T[], T> CreateInvokerForInstanceCompiler(MethodInfo compiler)
    {
      var t = compiler.ReflectedType;
      string s = compiler.Name;

      switch (compiler.GetParameters().Length) {
<#
PushIndent("      ");
for (int i = 1; i <= DelegateGenerator.MaxNumberOfArguments; i++) {
  WriteLine(string.Format("case {0}:", i));
  PushIndent("  ");
  var func = DelegateGenerator.GenerateOneArgumentFunc(null, "T", "T", i);
  var invoke = DelegateGenerator.GenerateArrayArgumentUsage("_this", "args", i - 1);
  WriteLine(string.Format("var d{0} = DelegateHelper.CreateDelegate<{1}>(null, t, s);", i, func));
  WriteLine(string.Format("return (member, _this, args) => d{0}{1};", i, invoke));
  PopIndent();
}
PopIndent();
#>
      }

      throw new InvalidOperationException();
    }
    
    private static Func<MemberInfo, T, T[], T> CreateInvokerForInstanceGenericCompiler(MethodInfo compiler)
    {
      var t = compiler.ReflectedType;
      string s = compiler.Name;

      switch (compiler.GetParameters().Length) {
<#
PushIndent("      ");
for (int i = 2; i <= DelegateGenerator.MaxNumberOfArguments; i++) {
  WriteLine(string.Format("case {0}:", i));
  PushIndent("  ");
  var func = DelegateGenerator.GenerateOneArgumentFunc("MemberInfo", "T", "T", i - 1);
  var invoke = DelegateGenerator.GenerateArrayArgumentUsage("member, _this", "args", i - 2);
  WriteLine(string.Format("var d{0} = DelegateHelper.CreateDelegate<{1}>(null, t, s);", i, func));
  WriteLine(string.Format("return (member, _this, args) => d{0}{1};", i, invoke));
  PopIndent();
}
PopIndent();
#>
      }

      throw new InvalidOperationException();
    }
    
    private static Func<MemberInfo, T, T[], T> CreateInvokerForStaticCompiler(MethodInfo compiler)
    {
      var t = compiler.ReflectedType;
      string s = compiler.Name;

      switch (compiler.GetParameters().Length) {
<#
PushIndent("      ");
for (int i = 0; i <= DelegateGenerator.MaxNumberOfArguments; i++) {
  WriteLine(string.Format("case {0}:", i));
  PushIndent("  ");
  var func = DelegateGenerator.GenerateOneArgumentFunc(null, "T", "T", i);
  var invoke = DelegateGenerator.GenerateArrayArgumentUsage(null, "args", i);
  WriteLine(string.Format("var d{0} = DelegateHelper.CreateDelegate<{1}>(null, t, s);", i, func));
  WriteLine(string.Format("return (member, _this, args) => d{0}{1};", i, invoke));
  PopIndent();
}
PopIndent();
#>
      }

      throw new InvalidOperationException();
    }
    
    private static Func<MemberInfo, T, T[], T> CreateInvokerForStaticGenericCompiler(MethodInfo compiler)
    {
      var t = compiler.ReflectedType;
      string s = compiler.Name;

      switch (compiler.GetParameters().Length) {
<#
PushIndent("      ");
for (int i = 1; i <= DelegateGenerator.MaxNumberOfArguments; i++) {
  WriteLine(string.Format("case {0}:", i));
  PushIndent("  ");
  var func = DelegateGenerator.GenerateOneArgumentFunc("MemberInfo", "T", "T", i - 1);
  var invoke = DelegateGenerator.GenerateArrayArgumentUsage("member", "args", i - 1);
  WriteLine(string.Format("var d{0} = DelegateHelper.CreateDelegate<{1}>(null, t, s);", i, func));
  WriteLine(string.Format("return (member, _this, args) => d{0}{1};", i, invoke));
  PopIndent();
}
PopIndent();
#>
      }

      throw new InvalidOperationException();
    }
  }
}