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

namespace FLY.Simulation.Casting
{
    public class AutoDie
    {
        /// <summary>
        /// 加热通过
        /// </summary>
        public int ChannelCnt;
        /// <summary>
        /// 加热量, 数据量为 ChannelCnt
        /// </summary>
        public int[] Heats;
        /// <summary>
        /// 第1个加热棒,对应的 数据序号, 数据量为 1000, BeforeData.Count
        /// </summary>
        public int Channel1stIndex;
        /// <summary>
        /// 加热 对 厚度的影响
        /// </summary>
        public double Factor;

        //需要别人赋值
        /// <summary>
        /// 原始数据!! 数据量为1000
        /// </summary>
        public ObservableCollection<int> BeforeDatas;
        /// <summary>
        /// 加热后的数据!!!! 数据量为BeforeDatas.Count
        /// </summary>
        public ObservableCollection<int> AfterDatas;


        double[] p;// 一个凸起来的数组  0 1 4 9 16 9 4 1 0
        void p_init()
        {
            int size = ChannelCnt / 10;
            p = new double[size];
            for (int i = 0; i < size; i++)
            {
                int index1 = i;
                int index2 = size - 1 - i;
                double d = i * i;
                p[index1] = d;
                p[index2] = d;
                if (Math.Abs(index2 - index1) <= 1)
                    break;
            }
            double sum_p = p.Max();
            for (int i = 0; i < size; i++)
            {
                p[i] = p[i] / sum_p;
            }
        }
        public AutoDie(int channelcnt)
        {
            SetChannelCnt(channelcnt);
            p_init();
            Factor = 5;
        }
        public void Init(ObservableCollection<int> before_datas, ObservableCollection<int> after_datas, int channel1stIndex)
        {
            BeforeDatas = before_datas;
            AfterDatas = after_datas;
            Channel1stIndex = channel1stIndex;

        }
        public void SetChannelCnt(int channelcnt)
        {
            ChannelCnt = channelcnt;
            Heats = new int[ChannelCnt];
            Array.Clear(Heats, 0, ChannelCnt);
        }
        public event Action<ObservableCollection<int>> AfterDatasUpdateEvent;
        public void HeatApply()
        {
            int boltcnt = BeforeDatas.Count();
            double b_c = (double)(boltcnt) / ChannelCnt;
            int b = Channel1stIndex;
            double beforeavg = BeforeDatas.Average();
            int[] datas = new int[boltcnt];
            for (int i = 0; i < ChannelCnt; i++)
            {
                int heat = Heats[i];
                int e = (int)((i + 1) * b_c) + Channel1stIndex;

                if (e >= boltcnt)
                    e -= boltcnt;
                else if (e < 0)
                    e += boltcnt;

                int j = b;
                while (j != e)
                {
                    datas[j] = (int)(BeforeDatas[j] - beforeavg * heat / Factor / 100);

                    j++;
                    if (j >= boltcnt)
                        j -= boltcnt;
                }
                b = e;
            }
            double afteravg = datas.Average();

            for (int j = 0; j < boltcnt; j++)
            {
                AfterDatas[j] = (int)(beforeavg * datas[j] / afteravg);
            }
            if (AfterDatasUpdateEvent != null)
            {
                AfterDatasUpdateEvent(AfterDatas);
            }
        }

        public void Test(int idx, int offset)
        {
            idx -= p.Count() / 2;
            if (idx < 0)
                idx += ChannelCnt;
            else if (idx >= ChannelCnt)
                idx -= ChannelCnt;

            for (int i = 0; i < p.Count(); i++)
            {
                int index = idx + i;

                if (index < 0)
                    index += ChannelCnt;
                else if (index >= ChannelCnt)
                    index -= ChannelCnt;


                int heat = Heats[index] + (int)(offset * p[i]);
                if (heat > 100)
                    heat = 100;
                else if (heat < 0)
                    heat = 0;
                Heats[index] = heat;
            }
            HeatApply();
        }
    }
}