using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.ComponentModel;
using FlyADBase;
using FLY.Thick.Base.IService;
using AutoMapper;
using System.IO;
using Newtonsoft.Json;

namespace FLY.Thick.Base.Server
{

    public class GM_GageInfo : GM_ScanMotion2, IGageInfoService
    {
        #region IGageInfoService 接口

        /// <summary>
        /// 数据好了！！！！
        /// 当 flyad7 的poslen, posOfGrid 发生变化时，DataOK = false, 需要重新记录。
        /// </summary>
        public bool DataOK { get; private set; }

        /// <summary>
        /// 机架总长，脉冲
        /// </summary>
        public int PosLen { get; private set; } = 9123;

        /// <summary>
        /// 1个grid = N个pos
        /// </summary>
        public int PosOfGrid { get; private set; } = 11;

        public int[] ForwData { get; private set; } 

        public int[] BackwData { get; private set; } 

        /// <summary>
        /// 0~100
        /// </summary>
        public int Progress { get; private set; }
        
        /// <summary>
        /// 数据录制，记下来回扫描的AD值数组
        /// </summary>
        public override void Start()
        {
            base.Start();
            if (!IsRunning)
                return;

            Progress = 0;
            tempDataCnt = 0;
            ScanCnt = 1;
            DataOK = false;
            PosOfGrid = mFlyAD.PosOfGrid;
            PosLen = mFlyAD.PosLen;
            ForwData = null;
            BackwData = null;

            base.Start2();
        }
        public override void Stop()
        {
            base.Stop();
            if (DataOK)
            {
                Progress = 100;
            }
            else 
            {
                PosOfGrid = mFlyAD.PosOfGrid;
                PosLen = mFlyAD.PosLen;
                ForwData = null;
                BackwData = null;
            }
            Save();

        }
        #endregion
        private int tempDataCnt = 0;
        string file_path;
        public GM_GageInfo():this("gageinfo.json")
        {

        }
        public GM_GageInfo(string param_path)
        {
            GMState = Common.CTRL_STATE.GAGEINFO;
            this.file_path = param_path;

            Load();

            DataPosEvent += new EndEventHandler(pollCorrect_DataPosEvent);
            EndEvent += new EndEventHandler(pollCorrect_EndEvent);
        }
        public override void Init(FlyAD7 flyad)
        {
            base.Init(flyad);
            if ((PosOfGrid != mFlyAD.PosOfGrid) || (PosLen != mFlyAD.PosLen))
                DataOK = false;
            else
                DataOK = true;
            flyad.PropertyChanged += new PropertyChangedEventHandler(flyad_PropertyChanged);
        }
        void flyad_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if ((e.PropertyName == nameof(mFlyAD.PosOfGrid)) ||
                (e.PropertyName == nameof(mFlyAD.PosLen)))
            {
                DataOK = false;
            }
        }


        void pollCorrect_EndEvent(object obj, FlyADBase.MiniGridEventArgs e)
        {
            DataEnd(e.direction, e.posOfGrid, e.grid_start, e.buf);
        }
        void pollCorrect_DataPosEvent(object obj, FlyADBase.MiniGridEventArgs e)
        {
            int grid_len = PosLen / PosOfGrid;
            if (e.direction == Misc.DIRECTION.FORWARD)
            {
                int p = e.grid_start * 100 / grid_len;

                Progress = (100 * tempDataCnt + p) / (2);
            }
            else
            {
                int p = (grid_len - e.grid_start) * 100 / grid_len;

                Progress = (100 * tempDataCnt + p) / (2);
            }
        }
        void DataEnd(Misc.DIRECTION direction, int posOfGrid, int start_grid, int[] dat)
        {
            int grid_len = PosLen / PosOfGrid;
            int[] datas = new int[grid_len];
            for (int i = 0; i < grid_len; i++) {
                datas[i] = Misc.MyBase.NULL_VALUE;
            }
            if (direction == Misc.DIRECTION.FORWARD)
            {
                for (int i = 0; i < dat.Length; i++)
                {
                    int grid = i + start_grid;
                    if (grid >= grid_len)
                        break;
                    datas[grid] = dat[i];
                }
                ForwData = datas;
            }
            else 
            {
                for (int i = 0; i < dat.Length; i++)
                {
                    int grid = i + start_grid;
                    if (grid >= grid_len)
                        break;
                    datas[grid] = dat[i];
                    
                }
                BackwData = datas;
                DataOK = true;
            }
            tempDataCnt++;
            Progress = 100 * tempDataCnt / (2);
        }

        bool Load()
        {
            try
            {
                if (File.Exists(file_path))
                {
                    string json = File.ReadAllText(file_path);
                    var p = JsonConvert.DeserializeObject<GageInfoJsonDb>(json);
                    GageInfoJsonDb.Mapper.Map(p, this);
                }
            }
            catch
            {
                //异常，没有json 解码失败

            }
            return false;
        }

        bool Save()
        {
            try
            {
                var p = GageInfoJsonDb.Mapper.Map<GageInfoJsonDb>(this);
                File.WriteAllText(file_path, JsonConvert.SerializeObject(p, Formatting.Indented));
                return true;
            }
            catch
            {
                //异常，没有json 编码失败

            }
            return false;
        }
    }
    public class GageInfoJsonDb
    {
        public static Mapper Mapper { get; } = new AutoMapper.Mapper(new MapperConfiguration(c =>
        {
            c.CreateMap<GM_GageInfo, GageInfoJsonDb>().ReverseMap();
        }));

        /// <summary>
        /// 机架总长，脉冲
        /// </summary>
        public int PosLen { get; set; } = 9123;

        /// <summary>
        /// 1个grid = N个pos
        /// </summary>
        public int PosOfGrid { get; set; } = 11;

        public List<int> ForwData { get; } = new List<int>();

        public List<int> BackwData { get; } = new List<int>();
    }
}
