using System;
using System.ComponentModel;
using System.Reactive.Subjects;
using System.Runtime.CompilerServices;
using Reactive.Bindings;

namespace Reactive.ViewModels
{
    internal class ConnectableObservableSnapshot2<T> : IConnectableReadOnlyReactiveProperty<T>
    {
        private readonly IConnectableObservable<T> _source;
        private T _value;

        public ConnectableObservableSnapshot2(IConnectableObservable<T> source, T initialValue = default(T))
        {
            _source = source;
            Value = initialValue;
            _source.Subscribe(t => Value = t);
        }

        public T Value
        {
            get { return _value; }
            private set
            {
                if (Equals(value, _value)) return;
                _value = value;
                OnPropertyChanged();
            }
        }

        public IDisposable Subscribe(IObserver<T> observer)
        {
            return _source.Subscribe(observer);
        }

        object IReadOnlyReactiveProperty.Value => Value;
        public void Dispose()
        {
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public IDisposable Connect()
        {
            return _source.Connect();
        }
    }
}