using FLY.OBJComponents.Client;
using FLY.Thick.Base.Client;
using FLY.Thick.Base.Common;
using FLY.Thick.Base.IService;
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using Unity;

namespace FLY.Thick.Base.UI
{
    class CtMicroGageVm:ICtMicroGageVm
    {
        #region 延时推送 MARKNO
        const int MARKNO_UPDATEERROR = 1;
        #endregion

        public event PropertyChangedEventHandler PropertyChanged;


        public double Thick { get; set; }
        public int AD { get; set; }
        public int ADMax { get; set; }
        public int Position { get; set; }
        public int PosLength { get; set; }

        public double Posmm { get; set; }
        public double Velocity { get; set; }

        public string ControllerState { get; set; }

        public UInt16 OStatus { get; set; }
        public UInt16 IStatus { get; set; }

        public bool IsError { get; set; }
        /// <summary>
        /// 异常消息
        /// </summary>
        public string ErrMsg { get; set; }

        public RelayCommand StopCmd { get; private set; }

        public RelayCommand ForwCmd { get; private set; }

        public RelayCommand BackwCmd { get; private set; }

        public RelayCommand OrgCmd { get; private set; }


        DynArea mDynArea;
        ITDGageService mTDGageService;
        IInitParamService mInitParam;
        BufferWindow<FLY.OBJComponents.Common.FlyData_WarningHistory> mWindow;
        DispatcherTimer timer_error;
        private int reason_list_index = -1;

        public CtMicroGageVm()
        {
            StopCmd = new RelayCommand(() =>
            {
                mTDGageService.StartP2(STARTP2_MODE.STOP);
            });
            OrgCmd = new RelayCommand(() =>
            {
                mTDGageService.StartP2(STARTP2_MODE.ORG);
            });
            ForwCmd = new RelayCommand(() =>
            {
                mTDGageService.StartP2(STARTP2_MODE.FORW);
            });
            BackwCmd = new RelayCommand(() =>
            {
                mTDGageService.StartP2(STARTP2_MODE.BACKW);
            });
        }

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="dynAreaService"></param>
        /// <param name="initParam"></param>
        /// <param name="gageService"></param>
        /// <param name="warningReasonWindow"></param>
        [InjectionMethod]
        public void Init(
            IDynAreaService dynAreaService, 
            IInitParamService initParam,
            ITDGageService gageService,
            WarningReasonWindow warningReasonWindow)
        {

            mTDGageService = gageService;
            mDynArea = dynAreaService.DynArea;
            mInitParam = initParam;
            mWindow = warningReasonWindow;

            Misc.BindingOperations.SetBinding(mDynArea, "Thick", () =>
            {
                Thick = mDynArea.Thick / 100.0;
            });
            Misc.BindingOperations.SetBinding(mDynArea, "AD", this, "AD");
            Misc.BindingOperations.SetBinding(mDynArea, "ADMax", this, "ADMax");
            Misc.BindingOperations.SetBinding(mDynArea, "Position", this, "Position");
            Misc.BindingOperations.SetBinding(mDynArea, "Velocity", this, "Velocity");


            Misc.BindingOperations.SetBinding(mDynArea, "ControllerState", () =>
            {
                FLY.Thick.Base.UI.Converter.ControllerStateConverter converter = new FLY.Thick.Base.UI.Converter.ControllerStateConverter();
                ControllerState = (string)converter.Convert(mDynArea.ControllerState, typeof(string), null, null);
            });

            Misc.BindingOperations.SetBinding(mInitParam, "PosLength", this, "PosLength");

            Action action = () =>
            {
                Posmm = mDynArea.Position * mInitParam.Encoder1_mmpp;
            };
            Misc.BindingOperations.SetBinding(mDynArea, "Position", action);
            Misc.BindingOperations.SetBinding(mInitParam, "Encoder1_mmpp", action);

            Misc.BindingOperations.SetBinding(mDynArea, "OStatus", this, "OStatus");
            Misc.BindingOperations.SetBinding(mDynArea, "IStatus", this, "IStatus");


            //报警原因轮流显示
            timer_error = new DispatcherTimer();
            timer_error.Interval = TimeSpan.FromSeconds(3);
            timer_error.Tick += (s, e) =>
            {
                reason_list_index--;
                if (reason_list_index < 0)
                    reason_list_index = mWindow.Record.Count();
                UpdateError();
            };
            mWindow.Record.CollectionChanged += Record_CollectionChanged;

            mDynArea.PropertyChanged += (s, e) =>
            {
                if (e.PropertyName == "ServerIsConnected")
                {
                    UpdateError();
                }
            };

            UpdateError();

            
        }

        private void Record_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            FObjBase.PollModule.Current.Poll_JustOnce(
                new FObjBase.PollModule.PollHandler(delegate ()
                {
                    reason_list_index = mWindow.Record.Count() - 1;

                    UpdateError();
                }), this, MARKNO_UPDATEERROR);
        }

        void UpdateError()
        {
            if (!mDynArea.ServerIsConnected)
            {
                ErrMsg = "服务器连接断开";
                IsError = true;
                reason_list_index = -1;
                timer_error.Stop();
            }
            else if (mWindow.Record.Count > 0)
            {
                if (reason_list_index >= mWindow.Record.Count)
                    reason_list_index = mWindow.Record.Count - 1;
                else if (reason_list_index < 0)
                    reason_list_index = 0;


                ErrMsg = mWindow.Record[reason_list_index].Description;
                IsError = true;
                timer_error.Start();
            }
            else
            {
                IsError = false;
                ErrMsg = "";
                reason_list_index = -1;
                timer_error.Stop();
            }
        }
    }
}
