aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Modules/MachineStudio.Dispensers/Models/DispenserModel.cs
blob: 94bf24e85ece68f1b6251b742faeabcdf1319058 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.BL;
using Tango.BL.Entities;

namespace Tango.MachineStudio.Dispensers.Models
{
    public class DispenserModel
    {
        private ObservablesContext _context;

        public Dispenser Dispenser { get; set; }

        public DispenserModel(Dispenser dispenser, ObservablesContext context)
        {
            Dispenser = dispenser;
            _context = context;
        }


    }
}
using Google.Protobuf;
using Google.Protobuf.Collections;
using Microsoft.Win32;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
using Tango.Core.Commands;
using Tango.Integration.Operation;
using Tango.PMR;
using Tango.Scripting;
using Tango.Settings;
using Tango.SharedUI;
using Tango.Stubs.Views;
using Tango.Transport;
using Tango.Transport.Adapters;

namespace Tango.Stubs.ViewModels
{
    /// <summary>
    /// Represents the script execution utility main view model.
    /// </summary>
    /// <seealso cref="Tango.SharedUI.ViewModel" />
    public class StubsViewVM : ViewModel
    {
        private StubManager _stubManager;
        private TextBox _logTextBox;
        private StubsSettings _settings;

        #region Properties

        public ITransportAdapter OverrideAdapter { get; set; }

        public List<CreateGroupVM> CreateGroups { get; set; }

        public List<ExampleVM> Examples { get; set; }

        private IMachineOperator _machineOperator;
        /// <summary>
        /// Gets or sets the machine operator.
        /// </summary>
        public IMachineOperator MachineOperator
        {
            get { return _machineOperator; }
            set { _machineOperator = value; RaisePropertyChangedAuto(); }
        }

        /// <summary>
        /// Gets or sets the code tabs.
        /// </summary>
        public ObservableCollection<CodeTabVM> CodeTabs { get; set; }

        /// <summary>
        /// Gets or sets the additional highlight C# types.
        /// </summary>
        public ObservableCollection<KeyValuePair<String, Type>> HighlightTypes { get; set; }

        /// <summary>
        /// Gets or sets the intellisense types.
        /// </summary>
        public ObservableCollection<KeyValuePair<String, Type>> IntellisenseTypes { get; set; }

        /// <summary>
        /// Gets or sets the collection of stub snippets.
        /// </summary>
        public ObservableCollection<StubSnippetVM> StubSnippets { get; set; }

        private StubSnippetVM _selectedStubSnippet;
        /// <summary>
        /// Gets or sets the selected stub snippet.
        /// </summary>
        public StubSnippetVM SelectedStubSnippet
        {
            get { return _selectedStubSnippet; }
            set { _selectedStubSnippet = value; RaisePropertyChanged(nameof(SelectedStubSnippet)); }
        }

        private CodeTabVM _selectedCodeTab;
        /// <summary>
        /// Gets or sets the selected code tab.
        /// </summary>
        public CodeTabVM SelectedCodeTab
        {
            get { return _selectedCodeTab; }
            set { _selectedCodeTab = value; RaisePropertyChanged(nameof(SelectedCodeTab)); InvalidateRelayCommands(); }
        }

        private bool _isConnected;
        /// <summary>
        /// Gets or sets a value indicating whether the USB adapter is connected.
        /// </summary>
        public bool IsConnected
        {
            get { return _isConnected; }
            set { _isConnected = value; RaisePropertyChanged(nameof(IsConnected)); InvalidateRelayCommands(); }
        }

        private List<String> _ports;
        /// <summary>
        /// Gets or sets the available USB ports.
        /// </summary>
        public List<String> Ports
        {
            get { return _ports; }
            set { _ports = value; RaisePropertyChanged(nameof(Ports)); }
        }

        private String _selectedPort;
        /// <summary>
        /// Gets or sets the selected USB port.
        /// </summary>
        public String SelectedPort
        {
            get { return _selectedPort; }
            set { _selectedPort = value; RaisePropertyChanged(nameof(SelectedPort)); InvalidateRelayCommands(); }
        }

        private String _status;
        /// <summary>
        /// Gets or sets the current status bar text.
        /// </summary>
        public String Status
        {
            get { return _status; }
            set { _status = value; RaisePropertyChanged(nameof(Status)); }
        }

        private bool _isRunning;
        /// <summary>
        /// Gets or sets a value indicating whether a stub is currently running.
        /// </summary>
        public bool IsRunning
        {
            get { return _isRunning; }
            set { _isRunning = value; RaisePropertyChanged(nameof(IsRunning)); InvalidateRelayCommands(); }
        }

        private bool _appendLogAuto;
        /// <summary>
        /// Gets or sets a value indicating whether the logs automatically.
        /// </summary>
        public bool AppendLogAuto
        {
            get { return _appendLogAuto; }
            set { _appendLogAuto = value; RaisePropertyChangedAuto(); }
        }

        private UsbSerialBaudRates _baudRate;
        /// <summary>
        /// Gets or sets the baud rate.
        /// </summary>
        public UsbSerialBaudRates BaudRate
        {
            get { return _baudRate; }
            set { _baudRate = value; RaisePropertyChangedAuto(); }
        }

        private ConnectionMode _connectionMode;
        /// <summary>
        /// Gets or sets the connection mode.
        /// </summary>
        public ConnectionMode ConnectionMode
        {
            get { return _connectionMode; }
            set { _connectionMode = value; RaisePropertyChangedAuto(); }
        }

        private bool _displayConnectionPane;
        /// <summary>
        /// Gets or sets a value indicating whether [hide connection pane].
        /// </summary>
        public bool DisplayConnectionPane
        {
            get { return _displayConnectionPane; }
            set { _displayConnectionPane = value; RaisePropertyChangedAuto(); }
        }

        #endregion

        #region Commands

        /// <summary>
        /// Gets or sets the new command.
        /// </summary>
        public RelayCommand NewCommand { get; set; }

        /// <summary>
        /// Gets or sets the close tab command.
        /// </summary>
        public RelayCommand<CodeTabVM> CloseTabCommand { get; set; }

        /// <summary>
        /// Gets or sets the build command.
        /// </summary>
        public RelayCommand BuildCommand { get; set; }

        /// <summary>
        /// Gets or sets the run command.
        /// </summary>
        public RelayCommand RunCommand { get; set; }

        /// <summary>
        /// Gets or sets the stop command.
        /// </summary>
        public RelayCommand StopCommand { get; set; }

        /// <summary>
        /// Gets or sets the toggle connection command.
        /// </summary>
        public RelayCommand ToggleConnectionCommand { get; set; }

        /// <summary>
        /// Gets or sets the open command.
        /// </summary>
        public RelayCommand OpenCommand { get; set; }

        /// <summary>
        /// Gets or sets the save command.
        /// </summary>
        public RelayCommand SaveCommand { get; set; }

        /// <summary>
        /// Gets or sets the save as command.
        /// </summary>
        public RelayCommand SaveAsCommand { get; set; }

        /// <summary>
        /// Gets or sets the clear command.
        /// </summary>
        public RelayCommand ClearCommand { get; set; }

        /// <summary>
        /// Gets or sets the stub snippet selected command.
        /// </summary>
        public RelayCommand StubSnippetSelectedCommand { get; set; }

        /// <summary>
        /// Gets or sets the insert snippet command.
        /// </summary>
        public RelayCommand<String> InsertSnippetCommand { get; set; }

        /// <summary>
        /// Gets or sets the create item command.
        /// </summary>
        public RelayCommand<CreateItemVM> CreateItemCommand { get; set; }

        /// <summary>
        /// Gets or sets the create example command.
        /// </summary>
        public RelayCommand<ExampleVM> CreateExampleCommand { get; set; }
        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="StubsViewVM"/> class.
        /// </summary>
        public StubsViewVM()
        {
            DisplayConnectionPane = true;

            _settings = SettingsManager.Default.GetOrCreate<StubsSettings>();

            Examples = new List<ExampleVM>();
            CodeTabs = new ObservableCollection<CodeTabVM>();
            NewCommand = new RelayCommand(CreateNewTab);
            CloseTabCommand = new RelayCommand<CodeTabVM>(OnTabClosing);
            RunCommand = new RelayCommand(RunTab, (x) => IsConnected && !IsRunning && SelectedCodeTab != null);
            BuildCommand = new RelayCommand(async () => await BuildTab(), (x) => !IsRunning && SelectedCodeTab != null);
            StopCommand = new RelayCommand(StopTab, (x) => IsConnected && IsRunning && SelectedCodeTab != null);
            InsertSnippetCommand = new RelayCommand<string>((x) => { });
            CreateExampleCommand = new RelayCommand<ExampleVM>(CreateExample);

            HighlightTypes = new ObservableCollection<KeyValuePair<string, Type>>();
            IntellisenseTypes = new ObservableCollection<KeyValuePair<string, Type>>();

            IntellisenseTypes.Add(new KeyValuePair<string, Type>("stubManager", typeof(StubManager)));

            foreach (var stubType in typeof(PMR.Common.MessageContainer).Assembly.GetTypes().Where(x => typeof(IMessage).IsAssignableFrom(x)))
            {
                HighlightTypes.Add(new KeyValuePair<string, Type>(stubType.Name, stubType));
            }

            HighlightTypes.Add(new KeyValuePair<string, Type>("Thread", typeof(Thread)));
            HighlightTypes.Add(new KeyValuePair<string, Type>("DateTime", typeof(DateTime)));
            HighlightTypes.Add(new KeyValuePair<string, Type>("TimeSpan", typeof(TimeSpan)));
            HighlightTypes.Add(new KeyValuePair<string, Type>("Dispatcher", typeof(Dispatcher)));
            HighlightTypes.Add(new KeyValuePair<string, Type>("Task", typeof(Task)));
            HighlightTypes.Add(new KeyValuePair<string, Type>("List", typeof(IList<Object>)));
            HighlightTypes.Add(new KeyValuePair<string, Type>("int", typeof(Int32)));
            HighlightTypes.Add(new KeyValuePair<string, Type>("double", typeof(Double)));
            HighlightTypes.Add(new KeyValuePair<string, Type>("String", typeof(String)));
            HighlightTypes.Add(new KeyValuePair<string, Type>("string", typeof(String)));

            foreach (var item in HighlightTypes)
            {
                IntellisenseTypes.Add(item);
            }

            StubSnippets = new ObservableCollection<StubSnippetVM>();

            foreach (var stubType in MessageFactory.GetAvailableRequestStubs())
            {
                StubSnippetVM snippet = new StubSnippetVM();
                snippet.Name = stubType.Name.Replace("Stub", "").Replace("Request", "").ToWords();

                snippet.Code = String.Empty;

                snippet.Code += "// " + "Request ----" + Environment.NewLine;

                foreach (var prop in stubType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
                {
                    snippet.Code += "// " + prop.PropertyType.Name + " : " + prop.Name + Environment.NewLine;
                }

                Type responseType = MessageFactory.GetAvailableRequestResponseStubs().SingleOrDefault(x => x.Name == stubType.Name.Replace("Request", "Response"));

                if (responseType != null)
                {
                    snippet.Code += Environment.NewLine + "// " + "Response ----" + Environment.NewLine;

                    foreach (var prop in responseType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
                    {
                        snippet.Code += "// " + prop.PropertyType.Name + " : " + prop.Name + Environment.NewLine;
                    }
                }

                snippet.Code += String.Format("var response = stubManager.Run<{2}>(\"{0}\" ,{1});", stubType.Name, String.Join(", ", stubType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Select(x => x.PropertyType.Name == "string" ? "\"string\"" : x.PropertyType.Name)), stubType.Name.Replace("Request", "Response"));
                StubSnippets.Add(snippet);
            }

            ToggleConnectionCommand = new RelayCommand(ToggleConnection, (x) => !IsRunning);
            OpenCommand = new RelayCommand(OpenFile);
            SaveCommand = new RelayCommand(SaveFile);
            SaveAsCommand = new RelayCommand(SaveAsFile);
            StubSnippetSelectedCommand = new RelayCommand(OnStubSnippetSelected);
            ClearCommand = new RelayCommand(ClearLog);

            Ports = new List<string>();

            for (int i = 1; i < 100; i++)
            {
                Ports.Add("COM" + i);
            }

            SelectedPort = _settings.SelectedPort != null ? _settings.SelectedPort : Ports.First();
            BaudRate = _settings.BaudRate;
            AppendLogAuto = _settings.AutoLogResponse;

            Status = "Ready";

            if (_settings.LastTabs.Count > 0)
            {
                foreach (var file in _settings.LastTabs)
                {
                    if (File.Exists(file))
                    {
                        OpenFile(file);
                    }
                }
            }
            else
            {
                CreateNewTab();
            }

            CreateGroups = new List<CreateGroupVM>();

            foreach (var typesGroup in typeof(PMR.Common.MessageContainer).Assembly.GetTypes().Where(x => x.IsClass && !x.IsGenericType && !x.Name.Contains("Reflection") && typeof(IMessage).IsAssignableFrom(x)).GroupBy(x => x.Namespace))
            {
                CreateGroupVM group = new CreateGroupVM();
                group.Name = typesGroup.First().Namespace.Split('.').Last();

                foreach (var type in typesGroup)
                {
                    group.Items.Add(new CreateItemVM()
                    {
                        Name = type.Name,
                        Type = type,
                    });
                }

                CreateGroups.Add(group);
            }

            CreateItemCommand = new RelayCommand<CreateItemVM>(CreateItem);

            foreach (var name in typeof(StubsViewVM).Assembly.GetManifestResourceNames())
            {
                if (name.Contains(".Examples."))
                {
                    using (Stream stream = typeof(StubsViewVM).Assembly.GetManifestResourceStream(name))
                    {
                        StreamReader reader = new StreamReader(stream);

                        ExampleVM example = new ExampleVM();
                        String[] str = name.Split('.');
                        example.Name = str[str.Length - 2].ToWords();
                        example.Code = reader.ReadToEnd();
                        Examples.Add(example);
                    }
                }
            }

            Examples = Examples.OrderBy(x => x.Name).ToList();
        }

        public StubsViewVM(ConnectionMode connectionMode) : this()
        {
            ConnectionMode = connectionMode;

            if (ConnectionMode == ConnectionMode.External)
            {
                IsConnected = true;
                DisplayConnectionPane = false;
            }
        }

        #endregion

        #region Virtual Methods

        /// <summary>
        /// Called when a stub snippet is double clicked.
        /// </summary>
        protected virtual void OnStubSnippetSelected()
        {
            if (SelectedStubSnippet != null)
            {
                if (InsertSnippetCommand != null)
                {
                    InsertSnippetCommand.Execute(SelectedStubSnippet.Code);
                }
            }
        }

        /// <summary>
        /// Called when user closes a script tab.
        /// </summary>
        /// <param name="codeTab">The code tab.</param>
        protected virtual void OnTabClosing(CodeTabVM codeTab)
        {
            CodeTabs.Remove(codeTab);
        }

        #endregion

        #region Private Methods

        private void CreateExample(ExampleVM example)
        {
            CreateNewTab();
            SelectedCodeTab.Code = example.Code;
            SelectedCodeTab.Title = example.Name;
        }

        private void CreateItem(CreateItemVM item)
        {
            if (item != null)
            {
                if (InsertSnippetCommand != null)
                {
                    String code = String.Empty;

                    FormatProperties(item.Type, ref code);

                    InsertSnippetCommand.Execute(code);
                }
            }
        }

        private void FormatProperties(Type type, ref String code)
        {
            code += Environment.NewLine + String.Format("{0} {1} = new {0}();", type.Name, type.Name.ToCamelCase()) + Environment.NewLine;

            foreach (var prop in type.GetProperties(BindingFlags.Instance | BindingFlags.Public))
            {
                if (prop.PropertyType == typeof(String))
                {
                    code += String.Format("{0}.{1} = {2};", type.Name.ToCamelCase(), prop.Name, "null") + Environment.NewLine;
                }
                else if (prop.PropertyType.IsEnum)
                {
                    code += String.Format("{0}.{1} = {2};", type.Name.ToCamelCase(), prop.Name, Activator.CreateInstance(prop.PropertyType).GetType().FullName + "." + Activator.CreateInstance(prop.PropertyType).ToString()) + Environment.NewLine;
                }
                else if (!prop.PropertyType.IsClass)
                {
                    code += String.Format("{0}.{1} = {2};", type.Name.ToCamelCase(), prop.Name, Activator.CreateInstance(prop.PropertyType).ToString().ToLower()) + Environment.NewLine;
                }
                else if (prop.PropertyType.IsGenericType)
                {
                    Type genericType = prop.PropertyType.GenericTypeArguments[0];
                    FormatProperties(genericType, ref code);
                    code += String.Format("{0}.{1}.Add({2});", type.Name.ToCamelCase(), prop.Name, genericType.Name.ToCamelCase()) + Environment.NewLine;
                }
                else
                {
                    FormatProperties(prop.PropertyType, ref code);
                    code += Environment.NewLine + String.Format("{0}.{1} = {2};", type.Name.ToCamelCase(), prop.Name, prop.Name.ToCamelCase()) + Environment.NewLine;
                }
            }
        }

        /// <summary>
        /// Clears the log.
        /// </summary>
        private void ClearLog()
        {
            _logTextBox.Clear();
        }

        /// <summary>
        /// Saves the selected script file.
        /// </summary>
        private async void SaveFile()
        {
            if (SelectedCodeTab != null)
            {
                if (SelectedCodeTab.File == null)
                {
                    SaveAsFile();
                }
                else
                {
                    Status = "Saving " + SelectedCodeTab.File + "...";
                    File.WriteAllText(SelectedCodeTab.File, SelectedCodeTab.Code);
                    await Task.Delay(1000);
                    Status = "Ready";

                    SaveSettings();
                }
            }
        }

        /// <summary>
        /// Saves the selected script file.
        /// </summary>
        private async void SaveAsFile()
        {
            if (SelectedCodeTab != null)
            {
                SaveFileDialog dlg = new SaveFileDialog();
                dlg.Filter = "C# Script Files|*.cs";
                dlg.DefaultExt = ".cs";
                if (dlg.ShowDialog().Value)
                {
                    Status = "Saving " + dlg.FileName + "...";
                    File.WriteAllText(dlg.FileName, SelectedCodeTab.Code);
                    SelectedCodeTab.File = dlg.FileName;
                    await Task.Delay(1000);
                    Status = "Ready";

                    SaveSettings();
                }
            }
        }

        public void SaveSettings()
        {
            _settings.AutoLogResponse = AppendLogAuto;
            _settings.SelectedPort = SelectedPort;
            _settings.BaudRate = BaudRate;
            _settings.LastTabs = CodeTabs.Select(x => x.File).ToList();
            _settings.Save();
        }

        /// <summary>
        /// Opens a script from HD.
        /// </summary>
        private void OpenFile()
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "C# Script Files|*.cs";
            dlg.Multiselect = true;
            if (dlg.ShowDialog().Value)
            {
                foreach (var file in dlg.FileNames)
                {
                    OpenFile(file);
                }
            }
        }

        /// <summary>
        /// Opens the file.
        /// </summary>
        /// <param name="file">The file.</param>
        private void OpenFile(String file)
        {
            var newTab = new CodeTabVM();
            newTab.File = file;
            newTab.Code = File.ReadAllText(file);
            CodeTabs.Add(newTab);
            SelectedCodeTab = newTab;
        }

        /// <summary>
        /// Toggles the USB adapter connection.
        /// </summary>
        private async void ToggleConnection()
        {
            try
            {
                if (!IsConnected)
                {
                    Mouse.OverrideCursor = Cursors.Wait;
                    AppendTextLog("Connecting..." + Environment.NewLine);
                    _machineOperator = new MachineOperator();
                    _machineOperator.EnableDiagnostics = false;
                    _machineOperator.EnableEmbeddedDebugging = false;
                    _machineOperator.EnableEventsNotification = false;
                    _machineOperator.EnableJobResume = false;
                    _machineOperator.UseKeepAlive = false;
                    _machineOperator.Adapter = new UsbTransportAdapter(SelectedPort, BaudRate);
                    await _machineOperator.Connect();
                    IsConnected = true;
                    AppendTextLog("Connected." + Environment.NewLine);
                    Mouse.OverrideCursor = null;
                }
                else
                {
                    AppendTextLog("Disconnecting..." + Environment.NewLine);
                    IsConnected = false;
                    await _machineOperator.Disconnect();
                    AppendTextLog("Disconnected." + Environment.NewLine);
                }
            }
            catch (Exception ex)
            {
                AppendTextLog(ex.Message + Environment.NewLine);
            }
            finally
            {
                Mouse.OverrideCursor = null;
            }
        }

        /// <summary>
        /// Creates a new script tab.
        /// </summary>
        private void CreateNewTab()
        {
            var newTab = new CodeTabVM();
            CodeTabs.Add(newTab);
            SelectedCodeTab = newTab;
        }

        /// <summary>
        /// Runs the selected script tab.
        /// </summary>
        private async void RunTab()
        {
            await BuildTab();

            if (SelectedCodeTab.Errors.Count > 0) return;

            if (MachineOperator == null || MachineOperator.State != TransportComponentState.Connected)
            {
                AppendTextLog("Machine operator is not initialized or connected. Could not execute script." + Environment.NewLine);
                return;
            }

            IsRunning = true;
            SelectedCodeTab.IsRunning = true;
            _logTextBox.Text = (DateTime.Now.ToTimeString() + ": ") + "Executing script '" + SelectedCodeTab.Title + "'..." + Environment.NewLine;

            await Task.Factory.StartNew(async () =>
            {
                try
                {
                    _stubManager = new StubManager(_machineOperator, (txt) =>
                     {
                         AppendTextLog(txt + Environment.NewLine);
                     }, (txt) =>
                     {
                         AppendTextLog(txt);
                     }, () =>
                     {

                     });
                    var thisStubManager = _stubManager;
                    _stubManager.Completed += Manager_Completed;
                    _stubManager.Failed += Manager_Failed;
                    _stubManager.Executed += Manager_Executed;
                    _stubManager.AutoLog = AppendLogAuto;

                    ScriptEngine engine = new ScriptEngine(new StubOnExecuteParameters(_stubManager));

                    engine.ReferencedAssemblies.Add(this.GetType());
                    engine.ReferencedAssemblies.Add(typeof(PMR.Stubs.CalculateRequest));
                    engine.ReferencedAssemblies.Add(typeof(IMessage));
                    await engine.Run(SelectedCodeTab.Code, Path.GetDirectoryName(SelectedCodeTab.File));

                    if (!thisStubManager.Aborted)
                    {
                        IsRunning = false;
                        SelectedCodeTab.IsRunning = false;
                    }
                }
                catch (Exception ex)
                {
                    IsRunning = false;
                    SelectedCodeTab.IsRunning = false;
                }
            });
        }

        /// <summary>
        /// Builds the tab.
        /// </summary>
        private Task BuildTab()
        {
            return Task.Factory.StartNew(() =>
            {
                try
                {
                    Status = "Compiling " + SelectedCodeTab.Title + "...";

                    var thisStubManager = _stubManager;

                    ScriptEngine engine = new ScriptEngine(new StubOnExecuteParameters(_stubManager));

                    engine.ReferencedAssemblies.Add(this.GetType());
                    engine.ReferencedAssemblies.Add(typeof(PMR.Stubs.CalculateRequest));
                    engine.ReferencedAssemblies.Add(typeof(IMessage));
                    var results = engine.Compile(SelectedCodeTab.Code, Path.GetDirectoryName(SelectedCodeTab.File)).Result;

                    if (results.Count == 0)
                    {
                        SelectedCodeTab.Errors = new ObservableCollection<CompilerError>();
                        Status = "Compiled successfully.";
                    }
                    else
                    {
                        SelectedCodeTab.Errors = results.ToObservableCollection();
                        Status = results.Count + " compilation errors found!";
                    }
                }
                catch (Exception ex)
                {
                    Status = "Error compiling!";
                    SelectedCodeTab.Errors = new ObservableCollection<CompilerError>() { new CompilerError() { Error = ex.Message } };
                }
            });
        }

        /// <summary>
        /// Stops the currently current script.
        /// </summary>
        private void StopTab()
        {
            if (_stubManager != null)
            {
                _stubManager.Abort();
                IsRunning = false;
                SelectedCodeTab.IsRunning = false;
                Status = "Stopped!";
                AppendTextLog((DateTime.Now.ToTimeString() + ": ") + "Stopped!" + Environment.NewLine);
            }
        }

        #endregion

        #region Public Methods

        public void SetLogTextBox(TextBox logTextBox)
        {
            _logTextBox = logTextBox;
        }

        #endregion

        #region Event Handlers

        /// <summary>
        /// Handled the <see cref="StubManager"/> Executed event.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="stubName">Name of the stub.</param>
        private void Manager_Executed(object sender, string stubName)
        {
            if (AppendLogAuto)
            {
                AppendTextLog((DateTime.Now.ToTimeString() + ": ") + "Executing '" + stubName + "'..." + Environment.NewLine);
            }

            Status = "Executing " + stubName + "...";
        }

        /// <summary>
        /// Handled the <see cref="StubManager"/> Failed event.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="ex">The exception.</param>
        private void Manager_Failed(object sender, Exception ex)
        {
            if (IsRunning)
            {
                if (AppendLogAuto)
                {
                    AppendTextLog((DateTime.Now.ToTimeString() + ": ") + ex.Message + Environment.NewLine);
                }

                Status = "Failed!";
            }
        }

        /// <summary>
        /// Handled the <see cref="StubManager"/> Completed event.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="response">The response.</param>
        private void Manager_Completed(object sender, string response)
        {
            if (AppendLogAuto)
            {
                AppendTextLog((DateTime.Now.ToTimeString() + ": ") + "Response Received:" + Environment.NewLine);
                AppendTextLog((DateTime.Now.ToTimeString() + ": ") + response + Environment.NewLine);
            }
            Status = "Completed";
        }

        private void AppendTextLog(String log)
        {
            LogManager.Log(log);

            InvokeUI(() =>
            {
                if (_logTextBox.Text.Length > 99999)
                {
                    _logTextBox.Clear();
                }
                _logTextBox.AppendText(log);
            });
        }

        private void ClearTextLog()
        {
            LogManager.Log("Log Cleared -----------------------------------------------------------------");

            InvokeUI(() =>
            {
                _logTextBox.Text = String.Empty;
            });
        }

        #endregion
    }
}