using System.Runtime.InteropServices;

namespace coolprop_wrapper.Functions
{
  class CoolProp_Props1SI : IFunction
  {
    [DllImport(
      "CoolProp.x86.dll", EntryPoint = "Props1SI",
      CharSet = CharSet.Ansi)]
    internal static extern double Props1SI_x86(
      string FluidName,
      string Output);
    [DllImport(
      "CoolProp.x64.dll", EntryPoint = "Props1SI",
      CharSet = CharSet.Ansi)]
    internal static extern double Props1SI_x64(
      string FluidName,
      string Output);
    internal static double Props1SI(
      string FluidName,
      string Output)
    {
      switch (System.IntPtr.Size)
      {
        case 4:
          return Props1SI_x86(FluidName, Output);
        case 8:
          return Props1SI_x64(FluidName, Output);
      }
      throw new SMath.Manager.EvaluationException(SMath.Manager.Errors.PluginCannotBeEnabled);
    }

    SMath.Manager.Term inf;
    public static int[] Arguments = new[] { 2 };

    public CoolProp_Props1SI(int childCount)
    {
      inf = new SMath.Manager.Term("CoolProp_Props1SI", SMath.Manager.TermType.Function, childCount);
    }

    SMath.Manager.Term IFunction.Info
    {
      get { return inf; }
    }

    SMath.Manager.TermInfo IFunction.GetTermInfo(string lang)
    {
      string funcInfo;

      var argsInfos = new System.Collections.Generic.List<SMath.Manager.ArgumentInfo>();

      switch (inf.ChildCount)
      {
        case 2:
        default:
          funcInfo = "(FluidName, Output) Return a value that does not depend on the thermodynamic state\r\n" +
                     "FluidName The fluid name\r\n" +
                     "Output The output parameter, one of \"Tcrit\",\"D\",\"H\",etc.";
          argsInfos.Add(new SMath.Manager.ArgumentInfo(SMath.Manager.ArgumentSections.String));
          argsInfos.Add(new SMath.Manager.ArgumentInfo(SMath.Manager.ArgumentSections.String));
          break;
      }

      return new SMath.Manager.TermInfo(inf.Text,
                                        inf.Type,
                                        funcInfo,
                                        SMath.Manager.FunctionSections.Unknown,
                                        true,
                                        argsInfos.ToArray());
    }

    bool IFunction.NumericEvaluation(SMath.Manager.Term value, SMath.Math.Numeric.TNumber[] args, ref SMath.Math.Numeric.TNumber result)
    {
      switch (args.GetLength(0))
      {
        case 2:
          string FluidName = args[0].obj.ToString().Trim('"'),
                 Output    = args[1].obj.ToString().Trim('"');
          var Result = Props1SI(FluidName, Output);
          coolpropPlugin.LogInfo(string.Format("[INFO ] [CoolProp_Props1SI.ExpressionEvaluation()] FluidName = {0}, Output = {1}, Result = {2}", FluidName, Output, Result));
          result = new SMath.Math.Numeric.TNumber(Result);
          result.obj.Units = Unit.Find(Output);
          break;
      }

      return true;
    }
  }
}
