using System.Windows;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Model.Logging;
using MediaBrowser.ServerApplication.Controls;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Windows.Controls.Primitives;
namespace MediaBrowser.ServerApplication.EntryPoints
{
    /// 
    /// Class NewItemNotifier
    /// 
    public class NewItemNotifier : IServerEntryPoint
    {
        /// 
        /// Holds the list of new items to display when the NewItemTimer expires
        /// 
        private readonly List _newlyAddedItems = new List();
        /// 
        /// The amount of time to wait before showing a new item notification
        /// This allows us to group items together into one notification
        /// 
        private const int NewItemDelay = 60000;
        /// 
        /// The current new item timer
        /// 
        /// The new item timer.
        private Timer NewItemTimer { get; set; }
        /// 
        /// The _library manager
        /// 
        private readonly ILibraryManager _libraryManager;
        /// 
        /// The _logger
        /// 
        private readonly ILogger _logger;
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// The library manager.
        /// The log manager.
        public NewItemNotifier(ILibraryManager libraryManager, ILogManager logManager)
        {
            _logger = logManager.GetLogger("NewItemNotifier");
            _libraryManager = libraryManager;
        }
        /// 
        /// Runs this instance.
        /// 
        public void Run()
        {
            _libraryManager.LibraryChanged += libraryManager_LibraryChanged;
        }
        /// 
        /// Handles the LibraryChanged event of the libraryManager control.
        /// 
        /// The source of the event.
        /// The  instance containing the event data.
        void libraryManager_LibraryChanged(object sender, ChildrenChangedEventArgs e)
        {
            var newItems = e.ItemsAdded.Where(i => !i.IsFolder).ToList();
            // Use a timer to prevent lots of these notifications from showing in a short period of time
            if (newItems.Count > 0)
            {
                lock (_newlyAddedItems)
                {
                    _newlyAddedItems.AddRange(newItems);
                    if (NewItemTimer == null)
                    {
                        NewItemTimer = new Timer(NewItemTimerCallback, null, NewItemDelay, Timeout.Infinite);
                    }
                    else
                    {
                        NewItemTimer.Change(NewItemDelay, Timeout.Infinite);
                    }
                }
            }
        }
        /// 
        /// Called when the new item timer expires
        /// 
        /// The state.
        private void NewItemTimerCallback(object state)
        {
            List newItems;
            // Lock the list and release all resources
            lock (_newlyAddedItems)
            {
                newItems = _newlyAddedItems.ToList();
                _newlyAddedItems.Clear();
                NewItemTimer.Dispose();
                NewItemTimer = null;
            }
            // Show the notification
            if (newItems.Count == 1)
            {
                Application.Current.Dispatcher.InvokeAsync(() =>
                {
                    var window = (MainWindow)Application.Current.MainWindow;
                    window.Dispatcher.InvokeAsync(() => window.MbTaskbarIcon.ShowCustomBalloon(new ItemUpdateNotification(_logger)
                    {
                        DataContext = newItems[0]
                    }, PopupAnimation.Slide, 6000));
                });
            }
            else if (newItems.Count > 1)
            {
                Application.Current.Dispatcher.InvokeAsync(() =>
                {
                    var window = (MainWindow)Application.Current.MainWindow;
                    window.Dispatcher.InvokeAsync(() => window.MbTaskbarIcon.ShowCustomBalloon(new MultiItemUpdateNotification(_logger)
                    {
                        DataContext = newItems
                    }, PopupAnimation.Slide, 6000));
                });
            }
        }
        /// 
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// 
        public void Dispose()
        {
            _libraryManager.LibraryChanged -= libraryManager_LibraryChanged;
        }
    }
}