using AutoMapper;
using FLY.Thick.Base.IService;
using FLY.Thick.Base.OBJ_INTERFACE;
using FObjBase;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FLY.Thick.Base.Server.OBJProxy
{
    public class FilmPositionDetect_OBJProxy : FObj
    {
        static Mapper Mapper { get; } = new AutoMapper.Mapper(new MapperConfiguration(c =>
        {
            c.CreateMap<IFilmPositionDetectService, FILMPOS_OBJ_INTERFACE.Pack_Params>();
            c.CreateMap<IFilmPositionDetectService, FILMPOS_OBJ_INTERFACE.Pack_State>();
        }));

        #region 延时推送 MARKNO
        const int MARKNO_PUSH_PARAMS = 1;
        const int MARKNO_PUSH_STATE = 2;
        #endregion

        IFilmPositionDetectService filmPositionDetectService;

        public FilmPositionDetect_OBJProxy(int objsys_idx, UInt32 id, IFilmPositionDetectService filmPositionDetectService) : base(objsys_idx)
        {
            ID = id;
            this.filmPositionDetectService = filmPositionDetectService;
            this.filmPositionDetectService.PropertyChanged += FilmPositionDetectService_PropertyChanged;
        }
        string[] propertyNames_params = new string[] {
            "FilmVThreshold","FilmVSrc","Encoder2_mmpp","MmOfR","VDistanceWithHeader","VSensorOffset"
        };
        string[] propertyNames_state = new string[] {
            "FilmVelocity",
            "FilmPosition","IsRunning","VDistanceWithHeaderInUsed","VSensorOffsetInUsed","HasReset" 
        };
        private void FilmPositionDetectService_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (propertyNames_params.Contains(e.PropertyName))
            {
                FObjBase.PollModule.Current.Poll_JustOnce(
                    new PollModule.PollHandler(delegate ()
                    {
                        byte[] buf;
                        GetValue(null, 0, FILMPOS_OBJ_INTERFACE.GET_PARAMS, out buf);
                        CurrObjSys.PushObjInfoEx(
                                this, FILMPOS_OBJ_INTERFACE.PUSH_PARAMS,
                                buf);
                    }), this, MARKNO_PUSH_PARAMS);
            }
            else if (propertyNames_state.Contains(e.PropertyName))
            {
                FObjBase.PollModule.Current.Poll_JustOnce(
                    new PollModule.PollHandler(delegate ()
                    {
                        byte[] buf;
                        GetValue(null, 0, FILMPOS_OBJ_INTERFACE.GET_STATE, out buf);
                        CurrObjSys.PushObjInfoEx(
                                this, FILMPOS_OBJ_INTERFACE.PUSH_STATE,
                                buf);
                    }), this, MARKNO_PUSH_STATE);
            }
        }
        public override void GetValue(IFConn from, uint srcid, ushort memid, out byte[] infodata)
        {
            infodata = null;
            switch (memid)
            {
                case FILMPOS_OBJ_INTERFACE.GET_PARAMS:
                    {
                        var p = Mapper.Map<FILMPOS_OBJ_INTERFACE.Pack_Params>(filmPositionDetectService);
                        string json = Newtonsoft.Json.JsonConvert.SerializeObject(p);
                        infodata = Misc.Converter.StringToBytes(json);
                    }
                    break;
                case FILMPOS_OBJ_INTERFACE.GET_STATE:
                    {
                        var p = Mapper.Map<FILMPOS_OBJ_INTERFACE.Pack_State>(filmPositionDetectService);
                        string json = Newtonsoft.Json.JsonConvert.SerializeObject(p);
                        infodata = Misc.Converter.StringToBytes(json);
                    }
                    break;
            }
        }

        public override void SetValue(IFConn from, uint srcid, ushort memid, byte[] infodata)
        {
            switch (memid) 
            {
                case FILMPOS_OBJ_INTERFACE.SET_PARAMS:
                    {
                        string json = Misc.Converter.BytesToString(infodata);
                        Newtonsoft.Json.JsonConvert.PopulateObject(json, this.filmPositionDetectService);

                    }break;
            }
        }
        public override void CallFunction(IFConn from, uint srcid, uint magic, ushort funcid, byte[] infodata)
        {
            switch (funcid) 
            {
                case FILMPOS_OBJ_INTERFACE.CALL_RESET:
                    {
                        string json = Misc.Converter.BytesToString(infodata);
                        var p = JsonConvert.DeserializeObject<double>(json);

                        filmPositionDetectService.Reset(p);
                    }break;
                case FILMPOS_OBJ_INTERFACE.CALL_RESET_2:
                    {
                        filmPositionDetectService.Reset();
                    }
                    break;
                case FILMPOS_OBJ_INTERFACE.CALL_CLEAR_RESET:
                    {
                        filmPositionDetectService.ClearResetState();
                    }
                    break;
                case FILMPOS_OBJ_INTERFACE.CALL_SET_FILMPOS_AT01:
                    {
                        string json = Misc.Converter.BytesToString(infodata);
                        var p = JsonConvert.DeserializeObject<double>(json);

                        filmPositionDetectService.SetFilmPosAt01(p);
                    }
                    break;
                case FILMPOS_OBJ_INTERFACE.CALL_STOP:
                    {
                        filmPositionDetectService.Stop();
                    }
                    break;
                case FILMPOS_OBJ_INTERFACE.CALL_START:
                    {
                        filmPositionDetectService.Start();
                    }
                    break;
            }
        }
    }
}
