using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Text;
using RainmeterStudio.Core.Model;
namespace RainmeterStudio.UI.ViewModel
{
    /// 
    /// Contains the view model of a reference
    /// 
    public class ReferenceViewModel : INotifyPropertyChanged, INotifyCollectionChanged
    {
        private List _children = null;
        #region Properties
        /// 
        /// Gets the linked reference
        /// 
        public Reference Reference { get; private set; }
        /// 
        /// Gets or sets the name
        /// 
        public string Name
        {
            get
            {
                return Reference.Name;
            }
        }
        /// 
        /// Gets or sets the path
        /// 
        public string Path
        {
            get
            {
                return Reference.StoragePath;
            }
        }
        /// 
        /// Gets an enumerable of this object's children
        /// 
        public IEnumerable Children
        {
            get
            {
                return _children;
            }
        }
        private bool _isExpanded = true;
        /// 
        /// Gets or sets a property indicating if the tree view item is expanded
        /// 
        public bool IsExpanded
        {
            get
            {
                return _isExpanded;
            }
            set
            {
                _isExpanded = value;
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs("IsExpanded"));
            }
        }
        private bool _isSelected;
        /// 
        /// Gets or sets a property indicating if the tree view item is selected
        /// 
        public bool IsSelected
        {
            get
            {
                return _isSelected;
            }
            set
            {
                _isSelected = value;
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs("IsSelected"));
            }
        }
        
        #endregion
        #region Events
        /// 
        /// Event triggered when a property is changed
        /// 
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
        #region Constructor
        /// 
        /// Creates a new instance of reference view model
        /// 
        /// Reference
        public ReferenceViewModel(Reference reference)
        {
            Reference = reference;
            Reference.CollectionChanged += Reference_CollectionChanged;
            UpdateChildren();
        }
        void Reference_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            List newItems = new List();
            List oldItems = new List();
            // Update collection
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    newItems = e.NewItems.Cast().Select(x => new ReferenceViewModel(x)).ToList();
                    break;
                case NotifyCollectionChangedAction.Remove:
                    oldItems = _children.Where(x => e.OldItems.Contains(x.Reference)).ToList();
                    break;
                case NotifyCollectionChangedAction.Replace:
                    newItems = e.NewItems.Cast().Select(x => new ReferenceViewModel(x)).ToList();
                    oldItems = _children.Where(x => e.OldItems.Contains(x.Reference)).ToList();
                    break;
                default:
                    UpdateChildren();
                    break;
            }
            _children.RemoveAll(oldItems.Contains);
            _children.AddRange(newItems);
            // Pass event
            if (CollectionChanged != null)
                CollectionChanged(this, new NotifyCollectionChangedEventArgs(e.Action, newItems, oldItems));
        }
        #endregion
        #region Operations
        /// 
        /// Sets the 'IsExpanded' property for the entire subtree
        /// 
        /// Value to set
        public void TreeExpand(bool value)
        {
            IsExpanded = value;
        }
        private void UpdateChildren()
        {
            _children = Reference.Children.Select(x => new ReferenceViewModel(x)).ToList();
        }
        #endregion
        /// 
        /// Triggered when the linked reference collection changes
        /// 
        public event NotifyCollectionChangedEventHandler CollectionChanged;
    }
}