using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using CommunityToolkit.Mvvm.ComponentModel;
using CtrEditor.FuncionesBase;
using DocumentFormat.OpenXml.Spreadsheet;
using Newtonsoft.Json;
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
using Color = System.Windows.Media.Color;
using Colors = System.Windows.Media.Colors;
using JsonIgnoreAttribute = Newtonsoft.Json.JsonIgnoreAttribute;

namespace CtrEditor.ObjetosSim
{
    /// <summary>
    /// Interaction logic for ucFramePlate.xaml
    /// </summary>
    /// 

    public partial class osFramePlate : osBase, IosBase
    {
        [JsonIgnore]
        public float offsetY;
        [JsonIgnore]
        public float offsetX;

        public static string NombreClase()
        {
            return "Frame Plate";
        }
        private string nombre = NombreClase();
        public override string Nombre
        {
            get => nombre;
            set => SetProperty(ref nombre, value);
        }

        [ObservableProperty]
        [property: Description("Layer index to add to Objects on the Frame")]
        [property: Category("Layer:")]
        int zindex_FramePlate;

        partial void OnZindex_FramePlateChanged(int value)
        {
            UpdateZIndex(value);
        }

        [ObservableProperty]
        Color color;
        [ObservableProperty]
        Color color_Titulo;

        [ObservableProperty]
        string titulo;
        [ObservableProperty]
        public float alto_Titulo;

        // Encoder
        [ObservableProperty]
        [property: Description("This is a link to a Encoder for X.")]
        [property: Category("Encoders:")]       
        [property: ItemsSource(typeof(osBaseItemsSource<osEncoderMotorLineal>))]
        private string encoder_X;

        [ObservableProperty]
        [property: Description("K Pulses per meter for Moving")]
        [property: Category("Encoders:")]
        public float k_encoder_X;

        [ObservableProperty]
        [property: Description("X in meter offset Left. Position when the encoder is 0")]
        [property: Category("Encoders:")]
        public float offset_encoder_X;

        partial void OnK_encoder_XChanged(float value)
        {
            UpdatePosition();
        }

        partial void OnOffset_encoder_XChanged(float value)
        {
            UpdatePosition();
        }

        [JsonIgnore]
        private osEncoderMotorLineal EncoderX;

        [JsonIgnore]
        private bool isUpdatingFromEncoderX = false;

        partial void OnEncoder_XChanged(string value)
        {
            if (EncoderX != null)
                EncoderX.PropertyChanged -= OnEncoderXPropertyChanged;
            if (_mainViewModel != null && value != null && value.Length > 0)
            {
                EncoderX = (osEncoderMotorLineal)_mainViewModel.ObjetosSimulables.FirstOrDefault(s => (s is osEncoderMotorLineal && s.Nombre == value), null);
                if (EncoderX != null)
                    EncoderX.PropertyChanged += OnEncoderXPropertyChanged;
            }
        }

        private void OnEncoderXPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (!isUpdatingFromEncoderX)
            {
                isUpdatingFromEncoderX = true;
                // Actualizamos el nombre si este fue modificado
                if (e.PropertyName == nameof(osEncoderMotorLineal.Nombre))
                    Group_Panel = ((osEncoderMotorLineal)sender).Nombre;

                if (e.PropertyName == nameof(osEncoderMotorLineal.Valor_Actual))
                {
                    UpdatePosition();
                }

                isUpdatingFromEncoderX = false;
            }
        }

        public void UpdatePosition()
        {
            if (EncoderX == null)
                return;
            if (K_encoder_X == 0)
                return;
            Left = (EncoderX.Valor_Actual / k_encoder_X) + offset_encoder_X;
        }

        public override void TopChanging(float oldValue, float newValue)
        {
            offsetY = newValue - oldValue;
        }
        public override void LeftChanging(float oldValue, float newValue)
        {
            offsetX = newValue - oldValue;
        }

        public osFramePlate()
        {
            Ancho = 0.5f;
            Alto = 0.5f;
            Alto_Titulo = 0.2f;
            Color = Colors.WhiteSmoke;
            Titulo = "Frame";
            Zindex_FramePlate = 0;
        }

        public override void ucLoaded()
        {
            base.ucLoaded();
            // El UserControl se ha cargado
            OnEncoder_XChanged(Encoder_X);
            UpdateZIndex(Zindex_FramePlate);
        }

        public override void ucUnLoaded()
        {
            base.ucUnLoaded();
            // El UserControl se esta eliminando
            // eliminar el objeto de simulacion
        }

    }

    public partial class ucFramePlate : UserControl, IDataContainer
    {
        public osBase? Datos { get; set; }
        public int zIndex_fromFrames { get; set; }

        public ucFramePlate()
        {
            InitializeComponent();
            this.Loaded += OnLoaded;
            this.Unloaded += OnUnloaded;
        }
        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            Datos?.ucLoaded();
        }
        private void OnUnloaded(object sender, RoutedEventArgs e)
        {
            Datos?.ucUnLoaded();
        }
        public void Highlight(bool State) { }
        public ZIndexEnum ZIndex_Base()
        {
            return ZIndexEnum.Decorativos;
        }

    }
}



