aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Scripting/Tango.Scripting.IDE/ISolution.cs
blob: 7ad659c69c2b888f63d5119bc4b0b24067dd2c3c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Tango.Core.Helpers;
using Tango.MachineStudio.Common.StudioApplication;
using Tango.MachineStudio.Common.Navigation;
using System.Reflection;
using System.Collections;
using Tango.Core;
using Tango.Logging;
using Tango.MachineStudio.Common.Modules;
using Tango.MachineStudio.Common;
using Tango.Settings;
using System.Windows;
using Tango.Integration.Services;
using Tango.MachineStudio.Common.EventLogging;
using Tango.BL.Enumerations;
using Tango.Core.DI;

namespace Tango.MachineStudio.UI.StudioApplication
{
    /// <summary>
    /// Represents the default Machine Studio <see cref="IStudioApplicationManager">Application Manager</see>.
    /// </summary>
    /// <seealso cref="Tango.Core.ExtendedObject" />
    /// <seealso cref="Tango.MachineStudio.Common.StudioApplication.IStudioApplicationManager" />
    public class DefaultStudioApplicationManager : ExtendedObject, IStudioApplicationManager
    {
        private INavigationManager _navigationManager;
        private IStudioModuleLoader _moduleLoader;
        private List<Window> _openedWindows;

        /// <summary>
        /// Initializes a new instance of the <see cref="DefaultStudioApplicationManager" /> class.
        /// </summary>
        /// <param name="navigationManager">The navigation manager.</param>
        public DefaultStudioApplicationManager(INavigationManager navigationManager, IStudioModuleLoader moduleLoader)
        {
            _moduleLoader = moduleLoader;
            _navigationManager = navigationManager;
            _openedWindows = new List<Window>();

            Task.Factory.StartNew(() => 
            {
                while (MainWindow.Instance == null)
                {
                    Thread.Sleep(100);
                }

                InvokeUI(() => 
                {
                    MainWindow.Instance.ContentRendered += (_, __) =>
                    {
                        TangoIOC.Default.GetAllInstancesByBase<IStudioViewModel>().ToList().ForEach(x => x.OnApplicationStarted());
                    };
                });
            });
        }

        /// <summary>
        /// Gets a value indicating whether Machine Studio is shutting down.
        /// </summary>
        public bool IsShuttingDown { get; private set; }

        /// <summary>
        /// The connected machine
        /// </summary>
        private IExternalBridgeClient _connectedMachine;

        /// <summary>
        /// Occurs when the connected machine property has changed.
        /// </summary>
        public event EventHandler<IExternalBridgeClient> ConnectedMachineChanged;

        /// <summary>
        /// Gets or sets the currently connected machine if any.
        /// </summary>
        public IExternalBridgeClient ConnectedMachine
        {
            get { return _connectedMachine; }
            set
            {
                _connectedMachine = value;
                RaisePropertyChangedAuto();
                RaisePropertyChanged(nameof(IsMachineConnected));
                RaisePropertyChanged(nameof(IsMachineConnectedViaTCP));

                if (_connectedMachine != null)
                {
                    _connectedMachine.StateChanged -= ConnectedMachine_StateChanged;
                    _connectedMachine.StateChanged += ConnectedMachine_StateChanged;
                }

                ConnectedMachineChanged?.Invoke(this, _connectedMachine);
            }
        }

        /// <summary>
        /// Gets a value indicating whether the <see cref="P:Tango.MachineStudio.Common.StudioApplication.IStudioApplicationManager.ConnectedMachine" /> is valid and connected through TCP/IP.
        /// </summary>
        public bool IsMachineConnectedViaTCP
        {
            get { return IsMachineConnected && ConnectedMachine is ExternalBridgeTcpClient; }
        }

        /// <summary>
        /// Handles the <see cref="ConnectedMachine"/> state changed event.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The e.</param>
        private void ConnectedMachine_StateChanged(object sender, Transport.TransportComponentState e)
        {
            if (e == Transport.TransportComponentState.Disconnected || e == Transport.TransportComponentState.Failed)
            {
                ConnectedMachine = null;
            }

        }

        /// <summary>
        /// Gets a value indicating whether the <see cref="P:Tango.MachineStudio.Common.StudioApplication.IStudioApplicationManager.ConnectedMachine" /> is valid.
        /// </summary>
        public bool IsMachineConnected
        {
            get { return ConnectedMachine != null; }
        }

        /// <summary>
        /// Gets the machine studio application version.
        /// </summary>
        public string Version
        {
            get
            {
                return typeof(DefaultStudioApplicationManager).Assembly.GetName().Version.ToString();
            }
        }

        /// <summary>
        /// Shutdown the application.
        /// </summary>
        public async void ShutDown()
        {
            if (IsShuttingDown) return;

            IsShuttingDown = true;

            await Task.Factory.StartNew(async () =>
            {
                //Do Shutdown Procedures...
                foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<IStudioViewModel>())
                {
                    try
                    {
                        var result = await vm.OnShutdownRequest();
                        if (!result)
                        {
                            IsShuttingDown = false;
                            return;
                        }
                    }
                    catch (Exception ex)
                    {
                        LogManager.Log(ex, "Error on shutdown request with " + vm.GetType().Name);
                    }
                }

                foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<IStudioViewModel>())
                {
                    vm.OnShuttingDown();
                }

                try
                {
                    SettingsManager.Default.Save();
                }
                catch (Exception ex)
                {
                    LogManager.Log(ex, "Error saving settings.");
                }

                _navigationManager.NavigateTo(NavigationView.ShutdownView);

                Thread.Sleep(1500);

                foreach (var window in _openedWindows)
                {
                    ThreadsHelper.InvokeUI(() =>
                    {
                        window.Close();
                    });
                }

                try
                {
                    if (ConnectedMachine != null)
                    {
                        ConnectedMachine.Disconnect().Wait();
                    }
                }
                catch (Exception ex)
                {
                    LogManager.Log(ex, "Error disconnecting from machine.");
                }

                var eventLogger = TangoIOC.Default.GetInstance<IEventLogger>();
                if (eventLogger != null)
                {
                    eventLogger.Log(EventTypes.ApplicationTerminated, "Application Terminated!");
                    eventLogger.FlushAll();
                }

                Thread.Sleep(1500);

                Environment.Exit(0);

            });
        }

        /// <summary>
        /// Loads the specified module if permitted.
        /// </summary>
        /// <param name="moduleName">Name of the module.</param>
        /// <param name="args">The arguments.</param>
        public void RequestModule(string moduleName, params object[] args)
        {
            IStudioModule module = _moduleLoader.UserModules.SingleOrDefault(x => x.Name == moduleName);

            if (module != null)
            {
                TangoIOC.Default.GetInstance<ViewModels.MainViewVM>().StartModule(module);

                //Notify request listeners.
                foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<IStudioViewModel>())
                {
                    vm.OnModuleRequest(module, args);
                }
            }
            else
            {
                throw new InvalidOperationException("The module was not found or you do not have sufficient privileges.");
            }
        }

        /// <summary>
        /// Notify the application manager about an external opened window.
        /// When application exists. All registered windows will be closed.
        /// </summary>
        /// <param name="window">The window.</param>
        public void RegisterOpenedWindow(Window window)
        {
            _openedWindows.Add(window);

            window.Closed += (x, y) => { _openedWindows.Remove(window); };
        }
    }
}