using MahApps.Metro.Controls;
using MediaBrowser.Common;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
using MediaBrowser.ServerApplication.Logging;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Threading;
namespace MediaBrowser.ServerApplication
{
    /// 
    /// Interaction logic for MainWindow.xaml
    /// 
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        /// 
        /// The _logger
        /// 
        private readonly ILogger _logger;
        /// 
        /// The _app host
        /// 
        private readonly IServerApplicationHost _appHost;
        /// 
        /// The _log manager
        /// 
        private readonly ILogManager _logManager;
        /// 
        /// The _configuration manager
        /// 
        private readonly IServerConfigurationManager _configurationManager;
        private readonly IUserManager _userManager;
        private readonly ILibraryManager _libraryManager;
        private readonly IJsonSerializer _jsonSerializer;
        private readonly IDisplayPreferencesRepository _displayPreferencesManager;
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// The log manager.
        /// The app host.
        /// The configuration manager.
        /// The user manager.
        /// The library manager.
        /// The json serializer.
        /// The display preferences manager.
        /// logger
        public MainWindow(ILogManager logManager, IServerApplicationHost appHost, IServerConfigurationManager configurationManager, IUserManager userManager, ILibraryManager libraryManager, IJsonSerializer jsonSerializer, IDisplayPreferencesRepository displayPreferencesManager)
        {
            if (logManager == null)
            {
                throw new ArgumentNullException("logManager");
            }
            if (appHost == null)
            {
                throw new ArgumentNullException("appHost");
            }
            if (configurationManager == null)
            {
                throw new ArgumentNullException("configurationManager");
            }
            _logger = logManager.GetLogger("MainWindow");
            _appHost = appHost;
            _logManager = logManager;
            _configurationManager = configurationManager;
            _userManager = userManager;
            _libraryManager = libraryManager;
            _jsonSerializer = jsonSerializer;
            _displayPreferencesManager = displayPreferencesManager;
            InitializeComponent();
            Loaded += MainWindowLoaded;
        }
        /// 
        /// Mains the window loaded.
        /// 
        /// The sender.
        /// The  instance containing the event data.
        void MainWindowLoaded(object sender, RoutedEventArgs e)
        {
            DataContext = this;
            UpdateButtons();
            LoadLogWindow(null, EventArgs.Empty);
            _logManager.LoggerLoaded += LoadLogWindow;
            _configurationManager.ConfigurationUpdated += Instance_ConfigurationUpdated;
            if (_appHost.IsFirstRun)
            {
                Dispatcher.InvokeAsync(() => MbTaskbarIcon.ShowBalloonTip("Media Browser", "Welcome to Media Browser Server!", Hardcodet.Wpf.TaskbarNotification.BalloonIcon.None));
            }
        }
        /// 
        /// Handles the ConfigurationUpdated event of the Instance control.
        /// 
        /// The source of the event.
        /// The  instance containing the event data.
        void Instance_ConfigurationUpdated(object sender, EventArgs e)
        {
            UpdateButtons();
            Dispatcher.InvokeAsync(() =>
            {
                var logWindow = App.Instance.Windows.OfType().FirstOrDefault();
                if ((logWindow == null && _configurationManager.Configuration.ShowLogWindow) || (logWindow != null && !_configurationManager.Configuration.ShowLogWindow))
                {
                    _logManager.ReloadLogger(_configurationManager.Configuration.EnableDebugLevelLogging ? LogSeverity.Debug : LogSeverity.Info);
                }
            });
        }
        private void UpdateButtons()
        {
            Dispatcher.InvokeAsync(() =>
            {
                var developerToolsVisibility = _configurationManager.Configuration.EnableDeveloperTools
                                                   ? Visibility.Visible
                                                   : Visibility.Collapsed;
                separatorDeveloperTools.Visibility = developerToolsVisibility;
                cmdReloadServer.Visibility = developerToolsVisibility;
                cmOpenExplorer.Visibility = developerToolsVisibility;
                cmShowLogWindow.Visibility = developerToolsVisibility;
            });
        }
        /// 
        /// Loads the log window.
        /// 
        /// The sender.
        /// The  instance containing the event data.
        void LoadLogWindow(object sender, EventArgs args)
        {
            CloseLogWindow();
            Dispatcher.InvokeAsync(() =>
            {
                // Add our log window if specified
                if (_configurationManager.Configuration.ShowLogWindow)
                {
                    Trace.Listeners.Add(new WindowTraceListener(new LogWindow(_logManager)));
                }
                else
                {
                    Trace.Listeners.Remove("MBLogWindow");
                }
                // Set menu option indicator
                cmShowLogWindow.IsChecked = _configurationManager.Configuration.ShowLogWindow;
            }, DispatcherPriority.Normal);
        }
        /// 
        /// Closes the log window.
        /// 
        void CloseLogWindow()
        {
            Dispatcher.InvokeAsync(() =>
            {
                foreach (var win in Application.Current.Windows.OfType())
                {
                    win.Close();
                }
            });
        }
        /// 
        /// Handles the Click event of the cmdApiDocs control.
        /// 
        /// The source of the event.
        /// The  instance containing the event data.
        void cmdApiDocs_Click(object sender, EventArgs e)
        {
            App.OpenUrl("http://localhost:" + _configurationManager.Configuration.HttpServerPortNumber + "/" +
                      _appHost.WebApplicationName + "/metadata");
        }
        void cmdSwaggerApiDocs_Click(object sender, EventArgs e)
        {
            App.OpenUrl("http://localhost:" + _configurationManager.Configuration.HttpServerPortNumber + "/" +
                      _appHost.WebApplicationName + "/swagger-ui/index.html");
        }
        void cmdGithubWiki_Click(object sender, EventArgs e)
        {
            App.OpenUrl("https://github.com/MediaBrowser/MediaBrowser/wiki");
        }
        
        /// 
        /// Occurs when [property changed].
        /// 
        public event PropertyChangedEventHandler PropertyChanged;
        /// 
        /// Called when [property changed].
        /// 
        /// The info.
        public void OnPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                try
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(info));
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error in event handler", ex);
                }
            }
        }
        #region Context Menu events
        /// 
        /// Handles the click event of the cmOpenExplorer control.
        /// 
        /// The source of the event.
        /// The  instance containing the event data.
        private void cmOpenExplorer_click(object sender, RoutedEventArgs e)
        {
            new LibraryExplorer(_jsonSerializer, _logger, _appHost, _userManager, _libraryManager, _displayPreferencesManager).Show();
        }
        /// 
        /// Handles the click event of the cmOpenDashboard control.
        /// 
        /// The source of the event.
        /// The  instance containing the event data.
        private void cmOpenDashboard_click(object sender, RoutedEventArgs e)
        {
            var user = _userManager.Users.FirstOrDefault(u => u.Configuration.IsAdministrator);
            OpenDashboard(user);
        }
        /// 
        /// Opens the dashboard.
        /// 
        private void OpenDashboard(User loggedInUser)
        {
            App.OpenDashboardPage("dashboard.html", loggedInUser, _configurationManager, _appHost);
        }
        
        /// 
        /// Handles the click event of the cmVisitCT control.
        /// 
        /// The source of the event.
        /// The  instance containing the event data.
        private void cmVisitCT_click(object sender, RoutedEventArgs e)
        {
            App.OpenUrl("http://community.mediabrowser.tv/");
        }
        /// 
        /// Handles the click event of the cmdBrowseLibrary control.
        /// 
        /// The source of the event.
        /// The  instance containing the event data.
        private void cmdBrowseLibrary_click(object sender, RoutedEventArgs e)
        {
            var user = _userManager.Users.FirstOrDefault(u => u.Configuration.IsAdministrator);
            App.OpenDashboardPage("index.html", user, _configurationManager, _appHost);
        }
        /// 
        /// Handles the click event of the cmExit control.
        /// 
        /// The source of the event.
        /// The  instance containing the event data.
        private void cmExit_click(object sender, RoutedEventArgs e)
        {
            Application.Current.Shutdown();
        }
        /// 
        /// Handles the click event of the cmdReloadServer control.
        /// 
        /// The source of the event.
        /// The  instance containing the event data.
        private void cmdReloadServer_click(object sender, RoutedEventArgs e)
        {
            App.Instance.Restart();
        }
        /// 
        /// Handles the click event of the CmShowLogWindow control.
        /// 
        /// The source of the event.
        /// The  instance containing the event data.
        private void CmShowLogWindow_click(object sender, RoutedEventArgs e)
        {
            _configurationManager.Configuration.ShowLogWindow = !_configurationManager.Configuration.ShowLogWindow;
            _configurationManager.SaveConfiguration();
            LoadLogWindow(sender, e);
        }
        #endregion
    }
}