// Decompiled with JetBrains decompiler
// Type: TSLab.Script.Handlers.JMA
// Assembly: JMA, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 311E19B1-D2AA-4596-935C-99ECE8ED0DE7
// Assembly location: C:\�����\JMA.dll

using System;
using System.Collections.Generic;

namespace TSLab.Script.Handlers
{
  public class JMA : IDouble2DoubleHandler, IOneSourceHandler, IDoubleReturns, IStreamHandler, IHandler, IDoubleInputs
  {
    [HandlerParameter(true, "14", Max = "20", Min = "2", Step = "2")]
    public int Len { get; set; }

    [HandlerParameter(true, "0", Max = "1", Min = "0", Step = "1")]
    public int phase { get; set; }

    public IList<double> Execute(IList<double> source)
    {
      double[] numArray1 = new double[source.Count];
      double num1 = 0.0;
      double num2 = 0.0;
      double num3 = 0.0;
      double num4 = 0.0;
      int index1 = 0;
      int index2 = 0;
      int index3 = 0;
      int index4 = 0;
      double num5 = 0.0;
      double num6 = 0.0;
      double num7 = 0.0;
      double num8 = 0.0;
      double num9 = 0.0;
      double num10 = 0.0;
      double num11 = 0.0;
      double num12 = 0.0;
      double num13 = 0.0;
      int index5 = 0;
      double num14 = 0.0;
      double[] numArray2 = new double[500];
      double[] numArray3 = new double[500];
      double[] numArray4 = new double[500];
      double[] numArray5 = new double[500];
      for (int len = this.Len; len < source.Count; ++len)
      {
        double num15 = source[len];
        if (index5 < 61)
        {
          ++index5;
          numArray5[index5] = num15;
        }
        if (index5 > 30)
        {
          double d = (double) this.Len >= 1.0000000002 ? (double) (this.Len - 1) / 2.0 : 1E-10;
          double num16 = this.phase >= -100 ? (this.phase <= 100 ? (double) (this.phase / 100) + 1.5 : 2.5) : 0.5;
          double num17 = Math.Log(Math.Sqrt(d));
          double num18 = num17;
          double num19 = num17 / Math.Log(2.0) + 2.0 >= 0.0 ? num18 / Math.Log(2.0) + 2.0 : 0.0;
          double y = 0.5 > num19 - 2.0 ? 0.5 : num19 - 2.0;
          double num20 = Math.Sqrt(d) * num19;
          double x1 = num20 / (num20 + 1.0);
          double num21 = d * 0.9;
          double x2 = num21 / (num21 + 2.0);
          double num22;
          if (num13 != 0.0)
          {
            num13 = 0.0;
            int num23 = 0;
            for (int index6 = 1; index6 <= 29; ++index6)
            {
              if (numArray5[index6 + 1] != numArray5[index6])
                num23 = 1;
            }
            num22 = (double) num23 * 30.0;
            num7 = num22 != 0.0 ? numArray5[1] : num15;
            num6 = num7;
            if (num22 > 29.0)
              num22 = 29.0;
          }
          else
            num22 = 0.0;
          for (int index6 = 0; (double) index6 <= num22; ++index6)
          {
            int index7 = 31 - index6;
            double num23 = index6 != 0 ? numArray5[index7] : num15;
            double num24 = num23 - num6;
            double num25 = num23 - num7;
            double num26 = Math.Abs(num24) <= Math.Abs(num25) ? Math.Abs(num25) : Math.Abs(num24);
            double num27 = num26 + 1E-10;
            if (index3 <= 1)
              index3 = (int) sbyte.MaxValue;
            else
              --index3;
            if (index4 <= 1)
              index4 = 10;
            else
              --index4;
            if (num5 < 128.0)
              ++num5;
            num1 = num1 + num27 - numArray4[index4];
            numArray4[index4] = num27;
            double num28 = num5 <= 10.0 ? num1 / num5 : num1 / 10.0;
            int int32;
            if (num5 > (double) sbyte.MaxValue)
            {
              double num29 = numArray3[index3];
              numArray3[index3] = num28;
              double num30 = 64.0;
              int32 = Convert.ToInt32(num30);
              while (num30 > 1.0)
              {
                if (numArray2[int32] < num29)
                {
                  num30 *= 0.5;
                  int32 += Convert.ToInt32(num30);
                }
                else if (numArray2[int32] <= num29)
                {
                  num30 = 1.0;
                }
                else
                {
                  num30 *= 0.5;
                  int32 -= Convert.ToInt32(num30);
                }
              }
            }
            else
            {
              numArray3[index3] = num28;
              if (num3 + num4 > (double) sbyte.MaxValue)
              {
                --num4;
                int32 = Convert.ToInt32(num4);
              }
              else
              {
                ++num3;
                int32 = Convert.ToInt32(num3);
              }
              index1 = num3 <= 96.0 ? Convert.ToInt32(num3) : 96;
              index2 = num4 >= 32.0 ? Convert.ToInt32(num4) : 32;
            }
            double num31 = 64.0;
            int index8 = Convert.ToInt32(num31);
            while (num31 > 1.0)
            {
              if (numArray2[index8] >= num28)
              {
                if (numArray2[index8 - 1] <= num28)
                {
                  num31 = 1.0;
                }
                else
                {
                  num31 *= 0.5;
                  index8 -= Convert.ToInt32(num31);
                }
              }
              else
              {
                num31 *= 0.5;
                index8 += Convert.ToInt32(num31);
              }
              if (index8 == (int) sbyte.MaxValue && num28 > numArray2[(int) sbyte.MaxValue])
                index8 = 128;
            }
            if (num5 > (double) sbyte.MaxValue)
            {
              if (int32 >= index8)
              {
                if (index1 + 1 > index8 && index2 - 1 < index8)
                  num2 += num28;
                else if (index2 > index8 && index2 - 1 < int32)
                  num2 += numArray2[index2 - 1];
              }
              else if (index2 >= index8)
              {
                if (index1 + 1 < index8 && index1 + 1 > int32)
                  num2 += numArray2[index1 + 1];
              }
              else if (index1 + 2 > index8)
                num2 += num28;
              else if (index1 + 1 < index8 && index1 + 1 > int32)
                num2 += numArray2[index1 + 1];
              if (int32 > index8)
              {
                if (index2 - 1 < int32 && index1 + 1 > int32)
                  num2 -= numArray2[int32];
                else if (index1 < int32 && index1 + 1 > index8)
                  num2 -= numArray2[index1];
              }
              else if (index1 + 1 > int32 && index2 - 1 < int32)
                num2 -= numArray2[int32];
              else if (index2 > int32 && index2 < index8)
                num2 -= numArray2[index2];
            }
            if (int32 <= index8)
            {
              if (int32 >= index8)
              {
                numArray2[index8] = num28;
              }
              else
              {
                for (int index9 = int32 + 1; index9 <= index8 - 1; ++index9)
                  numArray2[index9 - 1] = numArray2[index9];
                numArray2[index8 - 1] = num28;
              }
            }
            else
            {
              for (int index9 = int32 - 1; index9 >= index8; --index9)
                numArray2[index9 + 1] = numArray2[index9];
              numArray2[index8] = num28;
            }
            if (num5 <= (double) sbyte.MaxValue)
            {
              num2 = 0.0;
              for (int index9 = index2; index9 <= index1; ++index9)
                num2 += numArray2[index9];
            }
            double num32 = num2 / (double) (index1 - index2 + 1);
            if (num14 + 1.0 > 31.0)
              num14 = 31.0;
            else
              ++num14;
            if (num14 <= 30.0)
            {
              num6 = num24 <= 0.0 ? num23 - num24 * x1 : num23;
              num7 = num25 >= 0.0 ? num23 - num25 * x1 : num23;
              num10 = num15;
              if (num14 == 30.0 && num14 == 30.0)
              {
                num11 = num15;
                double num29 = Math.Ceiling(Math.Ceiling(num20) < 1.0 ? 1.0 : Math.Ceiling(num20));
                double num30 = Math.Ceiling(Math.Floor(num20) < 1.0 ? 1.0 : Math.Floor(num20));
                double num33;
                if (num29 == num30)
                {
                  num33 = 1.0;
                }
                else
                {
                  double num34 = num29 - num30;
                  num33 = (num20 - num30) / num34;
                }
                int num35 = num30 > 29.0 ? 29 : Convert.ToInt32(num30);
                int num36 = num29 > 29.0 ? 29 : Convert.ToInt32(num29);
                num9 = (num15 - numArray5[index5 - num35]) * (1.0 - num33) / num30 + (num15 - numArray5[index5 - num36]) * num33 / num29;
              }
            }
            else
            {
              num8 = (num19 < Math.Pow(num26 / num32, y) ? num19 : Math.Pow(num26 / num32, y)) >= 1.0 ? (num19 < Math.Pow(num26 / num32, y) ? num19 : Math.Pow(num26 / num32, y)) : 1.0;
              double num29 = Math.Pow(x1, Math.Sqrt(num8));
              num6 = num24 <= 0.0 ? num23 - num24 * num29 : num23;
              num7 = num25 >= 0.0 ? num23 - num25 * num29 : num23;
            }
          }
          if (num14 > 30.0)
          {
            double num23 = Math.Pow(x2, num8);
            num11 = (1.0 - num23) * num15 + num23 * num11;
            num12 = (num15 - num11) * (1.0 - x2) + x2 * num12;
            double num24 = num16 * num12 + num11;
            double num25 = -num23 * 2.0;
            double num26 = num23 * num23;
            double num27 = num25 + num26 + 1.0;
            num9 = (num24 - num10) * num27 + num26 * num9;
            num10 += num9;
          }
          numArray1[len] = num10;
        }
        if (index5 <= 30)
          numArray1[len] = 0.0;
      }
      return (IList<double>) numArray1;
    }
  }
}