using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace CtrEditor.ObjetosSim.UserControls
{
    public partial class OSComboBox : UserControl, INotifyPropertyChanged
    {
        public OSComboBox()
        {
            InitializeComponent();
            DataContext = this;
        }

        public static readonly DependencyProperty ObjetosSimulablesProperty =
            DependencyProperty.Register("ObjetosSimulables", typeof(IEnumerable<osBase>), typeof(OSComboBox), new PropertyMetadata(null, OnObjetosSimulablesChanged));

        public IEnumerable<osBase> ObjetosSimulables
        {
            get { return (IEnumerable<osBase>)GetValue(ObjetosSimulablesProperty); }
            set { SetValue(ObjetosSimulablesProperty, value); }
        }

        public static readonly DependencyProperty ObjectTypeProperty =
            DependencyProperty.Register("ObjectType", typeof(Type), typeof(OSComboBox), new PropertyMetadata(null, OnObjectTypeChanged));

        public Type ObjectType
        {
            get { return (Type)GetValue(ObjectTypeProperty); }
            set { SetValue(ObjectTypeProperty, value); }
        }

        public static readonly DependencyProperty SelectedObjectNameProperty =
            DependencyProperty.Register("SelectedObjectName", typeof(string), typeof(OSComboBox), new PropertyMetadata(string.Empty, OnSelectedObjectNameChanged));

        public string SelectedObjectName
        {
            get { 
                var str = (string)GetValue(SelectedObjectNameProperty);
                return str; 
            }
            set
            {
                SetValue(SelectedObjectNameProperty, value);
                OnPropertyChanged(nameof(SelectedObjectName));
            }
        }

        public static readonly DependencyProperty SelectedObjectProperty =
            DependencyProperty.Register("SelectedObject", typeof(osBase), typeof(OSComboBox), new PropertyMetadata(null, OnSelectedObjectChanged));

        public osBase SelectedObject
        {
            get { return (osBase)GetValue(SelectedObjectProperty); }
            set
            {
                SetValue(SelectedObjectProperty, value);
                OnPropertyChanged(nameof(SelectedObject));
            }
        }

        public ObservableCollection<osBase> FilteredObjetosSimulables { get; } = new ObservableCollection<osBase>();

        private static void OnObjetosSimulablesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var control = (OSComboBox)d;
            control.FilterObjetosSimulables();
        }

        private static void OnObjectTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var control = (OSComboBox)d;
            control.FilterObjetosSimulables();
        }

        private static void OnSelectedObjectNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var control = (OSComboBox)d;
            control.UpdateSelectedObject();
        }

        private static void OnSelectedObjectChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var control = (OSComboBox)d;
            control.UpdateSelectedObjectName();
        }

        private void FilterObjetosSimulables()
        {
            FilteredObjetosSimulables.Clear();
            if (ObjetosSimulables != null && ObjectType != null)
            {
                foreach (var obj in ObjetosSimulables.Where(o => o.GetType() == ObjectType))
                {
                    FilteredObjetosSimulables.Add(obj);
                }
            }
        }

        private void UpdateSelectedObject()
        {
            if (SelectedObjectName != null && ObjetosSimulables != null)
            {
                SelectedObject = ObjetosSimulables.FirstOrDefault(o => o.Nombre == SelectedObjectName);
            }
        }

        private void UpdateSelectedObjectName()
        {
            if (SelectedObject != null)
            {
                SelectedObjectName = SelectedObject.Nombre;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}