using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FLY.Thick.Base.Common
{
    public class CurveCore
    {
        #region ICurveService 成员

        public CurveType Flag;

        public List<CurveCell> Curves;

        public event PropertyChangedEventHandler PropertyChanged;

        #region E

        double AD2Value_E(int ad, AD2ValueFlag flag)
        {
            int i;
            double value;

            if (Curves.Count() < 1) return -1;
            if (ad < 0) return -1;
            if (ad == 0) ad = 1;
            if (flag == AD2ValueFlag.NoRevised)
            {
                for (i = 0; i < Curves.Count(); i++)
                {
                    if (ad < Curves[i].AD)
                        continue;
                    else
                        break;
                }
            }
            else
            {
                for (i = 0; i < Curves.Count(); i++)
                {
                    if (ad < Curves[i].RevisedAD)
                        continue;
                    else
                        break;
                }
            }

            if (i >= Curves.Count())
                i = Curves.Count() - 1;
            if (i == 0)
                i = 1;

            var c0 = Curves[i - 1];
            var c1 = Curves[i];
            double ad0, ad1, ad2;
            if (flag == AD2ValueFlag.NoRevised)
            {
                ad0 = Math.Log(c0.AD, Math.E);
                ad1 = Math.Log(c1.AD, Math.E);
                ad2 = Math.Log(ad, Math.E);
            }
            else
            {
                ad0 = Math.Log(c0.RevisedAD, Math.E);
                ad1 = Math.Log(c1.RevisedAD, Math.E);
                ad2 = Math.Log(ad, Math.E);
            }
            double u = (c1.Value - c0.Value) / (ad1 - ad0);
            value = (ad2 - ad0) * u + c0.Value;

            return value;
        }
        #endregion
        #region 线性
        double AD2Value_Line(int ad, AD2ValueFlag flag)
        {
            int i;
            double value;

            if (Curves.Count() < 2) return -1;
            if (ad < 0) return -1;
            if (ad == 0) ad = 1;
            bool isDescending = true;//降序排列
            if (Curves[0].AD < Curves[1].AD)
                isDescending = false;
            //找 ad0<ad<adi

            if (flag == AD2ValueFlag.NoRevised)
            {
                if (isDescending)//降序排列
                {
                    for (i = 0; i < Curves.Count(); i++)
                    {
                        if (ad < Curves[i].AD)
                            continue;
                        else
                            break;
                    }
                }
                else
                {
                    for (i = 0; i < Curves.Count(); i++)
                    {
                        if (ad > Curves[i].AD)
                            continue;
                        else
                            break;
                    }
                }
            }
            else
            {
                if (isDescending)//降序排列
                {
                    for (i = 0; i < Curves.Count(); i++)
                    {
                        if (ad < Curves[i].RevisedAD)
                            continue;
                        else
                            break;
                    }
                }
                else
                {
                    for (i = 0; i < Curves.Count(); i++)
                    {
                        if (ad > Curves[i].RevisedAD)
                            continue;
                        else
                            break;
                    }
                }
            }

            if (i >= Curves.Count()) i = Curves.Count() - 1;
            if (i == 0) i = 1;

            var c0 = Curves[i - 1];
            var c1 = Curves[i];
            double ad0, ad1, ad2 = ad;
            if (flag == AD2ValueFlag.NoRevised)
            {
                ad0 = c0.AD;
                ad1 = c1.AD;
            }
            else
            {
                ad0 = c0.RevisedAD;
                ad1 = c1.RevisedAD;
            }
            double u = (c1.Value - c0.Value) / (ad1 - ad0);
            value = (ad2 - ad0) * u + c0.Value;
            return value;
        }
        #endregion

        public double AD2Value(int ad, AD2ValueFlag flag)
        {
            double value;
            switch (Flag)
            {
                case CurveType.Line:
                    value = AD2Value_Line(ad, flag);
                    break;
                default:
                    value = AD2Value_E(ad, flag);
                    break;
            }
            return value;
        }
        #endregion
    }
}