using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Threading;
using Tango.Core.Commands;
using Tango.Core.Helpers;
using Tango.MachineStudio.Common.Modules;
using Tango.MachineStudio.Common.Notifications;
using Tango.Scripting;
using Tango.SharedUI;
namespace Tango.MachineStudio.UI.Console
{
public class ConsoleWindowVM : ViewModel
{
private IStudioModuleLoader _moduleLoader;
private INotificationProvider _notificatrion;
private TextBox _txtLog;
private String _currentFile;
private ScriptEngine _engine;
/// <summary>
/// Gets or sets the additional highlight C# types.
/// </summary>
public ObservableCollection<KeyValuePair<String, Type>> HighlightTypes { get; set; }
internal void SetLogTextBox(TextBox txtLog)
{
_txtLog = txtLog;
}
/// <summary>
/// Gets or sets the intellisense types.
/// </summary>
public ObservableCollection<KeyValuePair<String, Type>> IntellisenseTypes { get; set; }
private String _code;
/// <summary>
/// Gets or sets the code.
/// </summary>
public String Code
{
get { return _code; }
set { _code = value; RaisePropertyChangedAuto(); }
}
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(); }
}
/// <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 clear command.
/// </summary>
public RelayCommand ClearCommand { get; set; }
/// <summary>
/// Gets or sets the new command.
/// </summary>
public RelayCommand NewCommand { 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; }
public ConsoleWindowVM(IStudioModuleLoader moduleLoader, INotificationProvider notification)
{
_moduleLoader = moduleLoader;
_notificatrion = notification;
RunCommand = new RelayCommand(Run);
StopCommand = new RelayCommand(Stop);
HighlightTypes = new ObservableCollection<KeyValuePair<string, Type>>();
IntellisenseTypes = new ObservableCollection<KeyValuePair<string, Type>>();
IntellisenseTypes.Add(new KeyValuePair<string, Type>("manager", typeof(ConsoleManager)));
foreach (var moduleType in moduleLoader.UserModules.SelectMany(x => x.MainViewType.Assembly.GetTypes()))
{
if (!moduleType.FullName.Contains("<") && !moduleType.FullName.Contains(">"))
{
HighlightTypes.Add(new KeyValuePair<string, Type>(moduleType.FullName, moduleType));
}
}
foreach (var type in this.GetType().Assembly.GetTypes())
{
if (!type.FullName.Contains("<") && !type.FullName.Contains(">"))
{
HighlightTypes.Add(new KeyValuePair<string, Type>(type.Name, type));
}
}
foreach (var type in typeof(INotificationProvider).Assembly.GetTypes())
{
if (!type.FullName.Contains("<") && !type.FullName.Contains(">"))
{
HighlightTypes.Add(new KeyValuePair<string, Type>(type.Name, type));
}
}
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);
}
Code = EmbeddedResourceHelper.GetEmbeddedResourceText("Tango.MachineStudio.UI.Console.CodeTemplate.cs");
NewCommand = new RelayCommand(CreateNew);
OpenCommand = new RelayCommand(OpenFile);
SaveCommand = new RelayCommand(SaveFile);
SaveAsCommand = new RelayCommand(SaveAsFile);
ClearCommand = new RelayCommand(ClearLog);
}
private void Stop()
{
if (_engine != null)
{
_engine.Stop();
}
}
private async void Run()
{
_engine = new ScriptEngine(new ConsoleOnExecuteParameters(new ConsoleManager(WriteLine)));
_engine.ReferencedAssemblies.Add(this.GetType());
_engine.ReferencedAssemblies.Add(typeof(INotificationProvider));
foreach (var module in _moduleLoader.AllModules)
{
_engine.ReferencedAssemblies.Add(module.GetType());
}
await _engine.Run(Code, null);
}
private void WriteLine(String text)
{
InvokeUI(() =>
{
_txtLog.AppendText(text);
});
}
/// <summary>
/// Clears the log.
/// </summary>
private void ClearLog()
{
_txtLog.Clear();
}
/// <summary>
/// Saves the selected script file.
/// </summary>
private void SaveFile()
{
if (_currentFile == null)
{
SaveAsFile();
}
else
{
File.WriteAllText(_currentFile, Code);
}
}
/// <summary>
/// Saves the selected script file.
/// </summary>
private void SaveAsFile()
{
SaveFileDialog dlg = new SaveFileDialog();
dlg.Filter = "C# Script Files|*.cs";
dlg.DefaultExt = ".cs";
if (dlg.ShowDialog().Value)
{
File.WriteAllText(dlg.FileName, Code);
_currentFile = dlg.FileName;
}
}
/// <summary>
/// Opens a script from HD.
/// </summary>
private void OpenFile()
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = "C# Script Files|*.cs";
if (dlg.ShowDialog().Value)
{
OpenFile(dlg.FileName);
}
}
/// <summary>
/// Opens the file.
/// </summary>
/// <param name="file">The file.</param>
private void OpenFile(String file)
{
Code = File.ReadAllText(file);
_currentFile = file;
}
private void CreateNew()
{
_txtLog.Clear();
_currentFile = null;
Code = String.Empty;
}
}
}