using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.Core.Commands;
using Tango.SharedUI;
namespace Tango.Console
{
///
/// Represents a command prompt console control view model.
///
///
public class ConsoleControlVM : ViewModel
{
private int _historyIndex;
private List _knownSuggestions;
///
/// Occurs when a command is executing.
///
public event EventHandler CommandExecuting;
///
/// Gets the commands history.
///
public ObservableCollection Commands { get; private set; }
private ConsoleCommand _currentCommand;
///
/// Gets or sets the current command.
///
public ConsoleCommand CurrentCommand
{
get { return _currentCommand; }
set { _currentCommand = value; RaisePropertyChangedAuto(); }
}
private List _suggestions;
///
/// Gets or sets the available auto complete suggestions.
///
public List Suggestions
{
get { return _suggestions; }
set { _suggestions = value; RaisePropertyChangedAuto(); }
}
///
/// Executes the current command.
///
public RelayCommand ExecuteCommand { get; set; }
///
/// Navigates down through the commands history.
///
public RelayCommand HistoryDownCommand { get; set; }
///
/// Navigates up through the commands history.
///
public RelayCommand HistoryUpCommand { get; set; }
///
/// Initializes a new instance of the class.
///
public ConsoleControlVM()
{
Commands = new ObservableCollection();
CurrentCommand = new ConsoleCommand()
{
WorkingFolder = Environment.CurrentDirectory
};
ExecuteCommand = new RelayCommand(Execute);
HistoryDownCommand = new RelayCommand(HistoryDown);
HistoryUpCommand = new RelayCommand(HistoryUp);
_knownSuggestions = new List(ConsoleDictionary.GetKnownCommands().Select(x => new ConsoleSuggestion()
{
Type = ConsoleSuggestionType.Command,
Name = x.Name,
Description = x.Description
}));
Suggestions = new List(_knownSuggestions);
}
private void HistoryUp()
{
if (_historyIndex > 0)
{
_historyIndex--;
CreateNew(CurrentCommand.WorkingFolder, false, GetDistinctCommands()[_historyIndex].CommandText, true);
}
}
private void HistoryDown()
{
if (_historyIndex < GetDistinctCommands().Count - 1)
{
_historyIndex++;
CreateNew(CurrentCommand.WorkingFolder, false, GetDistinctCommands()[_historyIndex].CommandText, true);
}
}
private void Execute()
{
if (CurrentCommand != null)
{
if (!CurrentCommand.CommandText.IsNotNullOrEmpty())
{
CreateNew(CurrentCommand.WorkingFolder, true);
return;
}
if (CurrentCommand.CommandText.ToLower() == "clear")
{
Clear();
return;
}
CurrentCommand.IsExecuting = true;
ConsoleCommandExecutingEventArgs args = new ConsoleCommandExecutingEventArgs(CurrentCommand, (result) =>
{
CurrentCommand.IsExecuting = false;
CurrentCommand.Output = result.Output;
CreateNew(result.WorkingFolder, true);
AppendSuggestions(result.Suggestions);
});
CommandExecuting?.Invoke(this, args);
}
}
///
/// Concatenates the specified suggestions to the current suggestions.
///
/// The suggestions.
public void AppendSuggestions(List suggestions)
{
Suggestions = _knownSuggestions.Concat(suggestions).OrderBy(x => x.Name).ToList();
}
///
/// Clears the console.
///
public void Clear()
{
Commands.Clear();
CreateNew(CurrentCommand.WorkingFolder, false);
}
///
/// Clears and creates a new current command with the specified working folder.
///
/// The working folder.
public void Clear(String workingFolder)
{
Commands.Clear();
CreateNew(workingFolder, false);
}
private void CreateNew(String workingFolder, bool pushCurrent, String commandText = null, bool fromHistory = false)
{
if (pushCurrent)
{
Commands.Add(CurrentCommand);
_historyIndex = GetDistinctCommands().Count;
}
CurrentCommand = new ConsoleCommand()
{
WorkingFolder = workingFolder != null ? workingFolder : CurrentCommand.WorkingFolder,
CommandText = commandText,
IsFromHistory = fromHistory
};
}
private List GetDistinctCommands()
{
return Commands.Where(x => !x.IsFromHistory).ToList();
}
}
}