using System.Runtime.InteropServices;

namespace coolprop_wrapper.Functions
{
  class CoolProp_get_global_param_string : IFunction
  {
    [DllImport(
      "CoolProp.x86.dll", EntryPoint = "get_global_param_string",
      CharSet = CharSet.Ansi)]
    internal static extern long get_global_param_string_x86(
      string param,
      System.Text.StringBuilder Output,
      int n);
    [DllImport(
      "CoolProp.x64.dll", EntryPoint = "get_global_param_string",
      CharSet = CharSet.Ansi)]
    internal static extern long get_global_param_string_x64(
      string param,
      System.Text.StringBuilder Output,
      int n);
    internal static long get_global_param_string(
      string param,
      System.Text.StringBuilder Output,
      int n)
    {
      switch (System.IntPtr.Size)
      {
        case 4:
          return get_global_param_string_x86(param, Output, n);
        case 8:
          return get_global_param_string_x64(param, Output, n);
      }
      throw new SMath.Manager.EvaluationException(SMath.Manager.Errors.PluginCannotBeEnabled);
    }

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

    public CoolProp_get_global_param_string(int childCount)
    {
      inf = new SMath.Manager.Term("CoolProp_get_global_param_string", 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 1:
        default:
          funcInfo = "(ParamName) Get a globally-defined string\r\n" +
                     "ParamName A string, one of \"version\", \"errstring\", \"warnstring\", \"gitrevision\", \"FluidsList\", \"fluids_list\", \"parameter_list\",\"predefined_mixtures\"";
          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 1:
          var output = new System.Text.StringBuilder(10000);
          string param = args[0].obj.ToString().Trim('"');
          var Result = get_global_param_string(param, output, output.Capacity);
          coolpropPlugin.LogInfo(string.Format("[INFO ] [CoolProp_get_global_param_string.NumericEvaluation()] param = {0} output = {1} Result = {2}", param, output.ToString(), Result));
          if (Result != 1)
            throw new SMath.Manager.EvaluationException(SMath.Manager.Errors.ArgumentDoesNotMatchToExpectedKind/*, null, "Wrong param string!"*/);
//          result = SMath.Math.Numeric.Expression.Calculate(SMath.Manager.Converter.ToTerms("\"" + output.ToString() + "\""), null);
          result = new SMath.Math.Numeric.TDouble("\"" + output.ToString() + "\"");
          break;
      }

      return true;
    }
  }
}
