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 System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
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
{
    /// 
    /// VPWStationPositionControl.xaml 的交互逻辑
    /// 
    public partial class VPWStationPositionControl : 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(VPWStationPositionControl),
           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(VPWStationPositionControl));
        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(VPWStationPositionControl),
           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(VPWStationPositionControl),
            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(VPWStationPositionControl), 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(VPWStationPositionControl), 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(VPWStationPositionControl), 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 DegValueProperty = DependencyProperty.Register(
         "DegValue", typeof(double), typeof(VPWStationPositionControl), new FrameworkPropertyMetadata(0.00, FrameworkPropertyMetadataOptions.AffectsRender));
        /// 
        /// jog value
        /// 
        public double DegValue
        {
            get
            {
                return (double)this.GetValue(DegValueProperty);
            }
            set
            {
                this.SetValue(DegValueProperty, value);
            }
        }
        public static readonly DependencyProperty TorqueProperty = DependencyProperty.Register(
       "Torque", typeof(double), typeof(VPWStationPositionControl), new FrameworkPropertyMetadata(0.00, FrameworkPropertyMetadataOptions.AffectsRender));
        /// 
        /// Torque
        /// 
        public double Torque
        {
            get
            {
                return (double)this.GetValue(TorqueProperty);
            }
            set
            {
                this.SetValue(TorqueProperty, value);
            }
        }
        public static readonly DependencyProperty CurrentStationProperty = DependencyProperty.Register("CurrentStation", typeof(string), typeof(VPWStationPositionControl));
        /// 
        /// 当前位置
        /// 
        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 VPWStationPositionControl()
        {
            InitializeComponent();
        }
        private void SavedPos_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 void Self_Loaded(object sender, RoutedEventArgs e)
        {
            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);
                _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;
                }
            }
        }
        /// 
        /// 获取工位集合
        /// 
        /// 
        /// 
        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;
        }
    }
}