using MECF.Framework.Common.Beckhoff.AxisProvider;
using MECF.Framework.Common.Beckhoff.Station;
using MECF.Framework.Common.DataCenter;
using MECF.Framework.Common.OperationCenter;
using MECF.Framework.Common.Utilities;
using PunkHPX8_Core;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace PunkHPX8_Themes.UserControls
{
    /// 
    /// PufStationPositionControl.xaml 的交互逻辑
    /// 
    public partial class PufStationPositionControl : UserControl, INotifyPropertyChanged
    {
        #region 内部变量
        /// 
        /// 步进
        /// 
        private double _incrementValue;
        /// 
        /// 查询后台数据集合
        /// 
        private List _rtDataKeys = new List();
        /// 
        /// 查询后台的数据
        /// 
        private Dictionary _rtDataValues;
        /// 
        /// axis
        /// 
        BeckhoffStationAxis _axis;
        /// 
        /// Stations
        /// 
        private List _moduleStations;
        /// 
        /// 选择项
        /// 
        private string _moduleSelectedItem;
        /// 
        /// 已经保存的位置
        /// 
        private double _savePosition;
        /// 
        /// scaleFactor
        /// 
        private double _scaleFactor;
        #endregion
        #region 属性
        public static readonly DependencyProperty ModuleNameProperty = DependencyProperty.Register(
           "ModuleName", typeof(string), typeof(PufStationPositionControl),
           new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.AffectsRender));
        /// 
        /// 模块名称
        /// 
        public string ModuleName
        {
            get
            {
                return (string)this.GetValue(ModuleNameProperty);
            }
            set
            {
                this.SetValue(ModuleNameProperty, value);
            }
        }
        public List ModuleItemSource
        {
            get { return _moduleStations; }
            set
            {
                _moduleStations = value;
                InvokePropertyChanged(nameof(ModuleItemSource));
            }
        }
        public static readonly DependencyProperty IsAtStationProperty = DependencyProperty.Register(
          "IsAtStation", typeof(bool), typeof(PufStationPositionControl));
        public bool IsAtStation
        {
            get 
            {
                return (bool)this.GetValue(IsAtStationProperty); 
            }
            set
            {
                SetValue(IsAtStationProperty, value);
                InvokePropertyChanged(nameof(IsAtStation));
            }
        }
        /// 
        /// 选项索引
        /// 
        public string ModuleSelectedItem
        {
            get
            {
                return _moduleSelectedItem;
            }
            set
            {
                SavedPosition = GetStationPosition(_axis, value);
                _moduleSelectedItem = value;
                InvokePropertyChanged(nameof(ModuleSelectedItem));
            }
        }
        public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
           "OperationCommand", typeof(ICommand), typeof(PufStationPositionControl),
           new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));
        public ICommand OperationCommand
        {
            get
            {
                return (ICommand)this.GetValue(CommandProperty);
            }
            set
            {
                this.SetValue(CommandProperty, value);
            }
        }
        public static readonly DependencyProperty ModuleTitleProperty = DependencyProperty.Register(
            "ModuleTitle", typeof(string), typeof(PufStationPositionControl),
            new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.AffectsRender));
        /// 
        /// 标题
        /// 
        public string ModuleTitle
        {
            get
            {
                return (string)this.GetValue(ModuleTitleProperty);
            }
            set
            {
                this.SetValue(ModuleTitleProperty, value);
            }
        }
        public static readonly DependencyProperty SavedPositionProperty = DependencyProperty.Register(
           "SavedPosition", typeof(double), typeof(PufStationPositionControl), new FrameworkPropertyMetadata(0.00, new PropertyChangedCallback(OnCurrentPositionChanged)));
        /// 
        /// 保存位置
        /// 
        public double SavedPosition
        {
            get
            {
                return _savePosition;
            }
            set
            {
                _savePosition = value;
                SetValue(SavedPositionProperty, value);
                IsAtStation = JudgeAtStation(value,CurrentPosition,ToleranceDefault);
                InvokePropertyChanged(nameof(SavedPosition));
            }
        }
        public static readonly DependencyProperty ToleranceDefaultProperty = DependencyProperty.Register(
           "ToleranceDefault", typeof(double), typeof(PufStationPositionControl), new FrameworkPropertyMetadata(0.00, new PropertyChangedCallback(OnCurrentPositionChanged)));
        /// 
        /// 保存位置
        /// 
        public double ToleranceDefault
        {
            get
            {
                if(_axis!=null)
                {
                    return _axis.ToleranceDefault;
                }
                else
                {
                    return 0;
                }
            }
            set
            {
                SetValue(ToleranceDefaultProperty, _axis != null ? _axis.ToleranceDefault : 0);
            }
        }
        public static readonly DependencyProperty CurrentPositionProperty = DependencyProperty.Register(
           "CurrentPosition", typeof(double), typeof(PufStationPositionControl), new FrameworkPropertyMetadata(0.00, new PropertyChangedCallback(OnCurrentPositionChanged)));
        /// 
        /// 当前位置
        /// 
        public double CurrentPosition
        {
            get
            {
                return (double)this.GetValue(CurrentPositionProperty);
            }
            set
            {
                SetValue(CurrentPositionProperty, value);
            }
        }
        private static void OnCurrentPositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {
                double tmpSavedPosition = (double)d.GetValue(SavedPositionProperty);
                double toleranceDefault = (double)d.GetValue(ToleranceDefaultProperty);
                bool result = JudgeAtStation(tmpSavedPosition, (double)e.NewValue, toleranceDefault);
                d.SetValue(IsAtStationProperty, result);
            }
        }
        public static readonly DependencyProperty IsMotorOnProperty = DependencyProperty.Register(
          "IsMotorOn", typeof(bool), typeof(PufStationPositionControl),
          new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsRender));
        /// 
        /// AtStation
        /// 
        public bool IsMotorOn
        {
            get
            {
                return (bool)this.GetValue(IsMotorOnProperty);
            }
            set
            {
                this.SetValue(IsMotorOnProperty, value);
            }
        }
        public static readonly DependencyProperty DegValueProperty = DependencyProperty.Register(
         "DegValue", typeof(double), typeof(PufStationPositionControl), new FrameworkPropertyMetadata(0.00, FrameworkPropertyMetadataOptions.AffectsRender));
        /// 
        /// 当前位置
        /// 
        public double DegValue
        {
            get
            {
                return (double)this.GetValue(DegValueProperty);
            }
            set
            {
                this.SetValue(DegValueProperty, value);
            }
        }
        public static readonly DependencyProperty CurrentStationProperty = DependencyProperty.Register("CurrentStation", typeof(string), typeof(PufStationPositionControl));
        /// 
        /// 当前位置
        /// 
        public string CurrentStation
        {
            get
            {
                return (string)this.GetValue(CurrentStationProperty);
            }
            set
            {
                this.SetValue(CurrentStationProperty, value);
            }
        }
        /// 
        /// 当前位置
        /// 
        public double IncrementValue
        {
            get { return _incrementValue; }
            set
            {
                _incrementValue = value;
                InvokePropertyChanged(nameof(IncrementValue));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
        /// 
        /// 构造函数
        /// 
        public PufStationPositionControl()
        {
            InitializeComponent();
        }
        private void GotoSavedPos_Click(object sender, RoutedEventArgs e)
        {
            InvokeClient.Instance.Service.DoOperation($"{ModuleName}.GotoSavedPosition", "TargetPosition",ModuleSelectedItem);
        }
        private void MotorPos_Click(object sender, RoutedEventArgs e)
        {
            InvokeClient.Instance.Service.DoOperation($"{ModuleName}.Save", $"{ModuleSelectedItem}", Math.Round(CurrentPosition, 2));
            SavedPosition = CurrentPosition;
            foreach (Station item in _axis.Stations)
            {
                if (item.Name == ModuleSelectedItem)
                {
                    item.Position = CurrentPosition.ToString();
                    break;
                }
            }
        }
        private void LeftCommand_Click(object sender, RoutedEventArgs e)
        {
            InvokeClient.Instance.Service.DoOperation($"{ModuleName}.JogDown", "TargetPosition",DegValue,CurrentPosition);
        }
        private void RightCommand_Click(object sender, RoutedEventArgs e)
        {
            InvokeClient.Instance.Service.DoOperation($"{ModuleName}.JogUp", "TargetPosition", DegValue,CurrentPosition);
        }
        /// 
        /// 获取工位集合
        /// 
        /// 
        /// 
        private List GetStationList(BeckhoffStationAxis stationAxis)
        {
            List lst = new List();
            if (stationAxis == null)
            {
                return lst;
            }
            foreach (var item in stationAxis.Stations)
            {
                lst.Add(item.Name);
            }
            return lst;
        }
        /// 
        /// 获取工位位置
        /// 
        /// 
        /// 
        /// 
        private double GetStationPosition(BeckhoffStationAxis stationAxis, string station)
        {
            if (stationAxis == null)
            {
                return 0;
            }
            foreach (var item in stationAxis.Stations)
            {
                if (item.Name == station)
                {
                    double.TryParse(item.Position, out var position);
                    return position;
                }
            }
            return 0;
        }
        /// 
        /// 转换数值
        /// 
        /// 
        /// 
        private int ConvertValue(double value)
        {
            if(_scaleFactor!=0)
            {
                return (int)Math.Round(value * _scaleFactor,0);
            }
            else
            {
                return (int)Math.Round(value,0);
            }
        }
        private void InvokePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        /// 
        /// 判定AtStation
        /// 
        private static bool JudgeAtStation(double saved,double current,double tolerance)
        {
            return Math.Abs(saved - current) <= tolerance;
        }
        private void IsControlVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null && ((bool)e.NewValue) == true)
            {
                if (!string.IsNullOrEmpty(ModuleName))
                {
                    _rtDataKeys.Clear();
                    IncrementValue = (double)QueryDataClient.Instance.Service.GetConfig("System.Increment");
                    _rtDataKeys.Add($"Station.{ModuleName}");
                    _rtDataKeys.Add($"{ModuleName}.AxisProvider");
                    _rtDataValues = QueryDataClient.Instance.Service.PollData(_rtDataKeys);
                    if (_rtDataValues != null)
                    {
                        _axis = CommonFunction.GetValue(_rtDataValues, $"Station.{ModuleName}");
                        BeckhoffProviderAxis beckhoffProviderAxis = CommonFunction.GetValue(_rtDataValues, $"{ModuleName}.AxisProvider");
                        if (_axis != null)
                        {
                            ToleranceDefault = _axis.ToleranceDefault;
                            ModuleItemSource = GetStationList(_axis);
                            if (ModuleItemSource != null && ModuleItemSource.Count != 0)
                            {
                                ModuleSelectedItem = ModuleItemSource[0];
                            }
                        }
                        if (beckhoffProviderAxis != null)
                        {
                            _scaleFactor = beckhoffProviderAxis.ScaleFactor;
                        }
                    }
                }
            }
        }
    }
}