using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using MaterialDesignThemes.Wpf;
using Tango.MachineStudio.Common.Notifications;
using Tango.MachineStudio.UI.Windows;
using System.Windows.Media;
using Tango.Core;
using System.Collections.ObjectModel;
using Tango.SharedUI;
using System.Collections.Concurrent;
namespace Tango.MachineStudio.UI.Notifications
{
///
/// Represents the default Machine Studio Notification Provider.
///
///
///
public class DefaultNotificationProvider : ExtendedObject, INotificationProvider
{
private int _message_count = 0;
///
/// The view types
///
private static List viewTypes;
///
/// Gets the collection of active task items.
///
public ObservableCollection TaskItems { get; private set; }
///
/// Gets the collection of active bar items.
///
public ObservableCollection BarItems { get; private set; }
///
/// Gets a value indicating whether there are any queued task items.
///
public bool HasTaskItems
{
get { return TaskItems.Count > 0; }
}
///
/// The current task item
///
private TaskItem _currentTaskItem;
///
/// Gets the current displayed task item.
///
public TaskItem CurrentTaskItem
{
get { return _currentTaskItem; }
set { _currentTaskItem = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(HasTaskItems)); }
}
///
/// Initializes a new instance of the class.
///
public DefaultNotificationProvider()
{
TaskItems = new ObservableCollection();
BarItems = new ObservableCollection();
}
///
/// Display a message box.
///
/// The icon.
/// Color of the icon.
/// The message.
/// if set to true displays the cancel button.
///
public bool? ShowMessageBox(PackIconKind icon, Brush iconColor, string message, bool hasCancel)
{
MainWindow.Instance.shadowGrid.Visibility = Visibility.Visible;
_message_count++;
var result = new MessageBoxWindow()
{
Owner = Application.Current.MainWindow,
Message = message,
IconKind = icon,
IconColor = iconColor,
HasCancel = hasCancel
}.ShowDialog();
_message_count--;
if (_message_count == 0)
{
MainWindow.Instance.shadowGrid.Visibility = Visibility.Hidden;
}
return result;
}
///
/// Shows the specified view with the specified view model as it's data context.
///
/// The type of the mm.
/// The type of the view.
/// The view model.
/// The view.
/// The accept action.
/// The cancel action.
public void ShowModalDialog(VM vm, View view, Action onAccept, Action onCancel) where View : FrameworkElement where VM : DialogViewVM
{
try
{
DialogWindow dialog = new DialogWindow();
dialog.Owner = Application.Current.MainWindow;
dialog.InnerContent = view;
MainWindow.Instance.shadowGrid.Visibility = Visibility.Visible;
view.Loaded += (x, y) =>
{
try
{
VM context = vm;
dialog.DataContext = context;
Action onAcceptAction = null;
Action onCancelAction = null;
onAcceptAction = new Action(() =>
{
dialog.Close();
onAccept(context);
context.Accepted -= onAcceptAction;
context.Canceled -= onCancelAction;
});
onCancelAction = new Action(() =>
{
dialog.Close();
if (onCancel != null)
{
onCancel();
}
context.Canceled -= onCancelAction;
context.Accepted -= onAcceptAction;
});
context.Accepted += onAcceptAction;
context.Canceled += onCancelAction;
context.OnShow();
}
catch (Exception ex)
{
LogManager.Log(ex, $"Error display modal dialog. {typeof(VM).Name}");
onCancel?.Invoke();
}
};
dialog.ShowDialog();
}
catch (Exception ex)
{
LogManager.Log(ex, $"Error display modal dialog. {typeof(VM).Name}");
onCancel?.Invoke();
}
finally
{
MainWindow.Instance.shadowGrid.Visibility = Visibility.Hidden;
}
}
///
/// Creates a new instance of the specified View type and displays it as a modal dialog.
///
/// The type of the view.
/// The type of the view model.
/// Accept button callback.
/// Cancel button callback.
public void ShowModalDialog(Action onAccept, Action onCancel) where View : FrameworkElement where VM : DialogViewVM
{
try
{
var view = Activator.CreateInstance();
DialogWindow dialog = new DialogWindow();
dialog.Owner = Application.Current.MainWindow;
dialog.InnerContent = view;
MainWindow.Instance.shadowGrid.Visibility = Visibility.Visible;
view.Loaded += (x, y) =>
{
try
{
VM context = view.DataContext as VM;
dialog.DataContext = context;
Action onAcceptAction = null;
Action onCancelAction = null;
onAcceptAction = new Action(() =>
{
dialog.Close();
onAccept(context);
context.Accepted -= onAcceptAction;
context.Canceled -= onCancelAction;
});
onCancelAction = new Action(() =>
{
dialog.Close();
if (onCancel != null)
{
onCancel();
}
context.Accepted -= onAcceptAction;
context.Canceled -= onCancelAction;
});
context.Accepted += onAcceptAction;
context.Canceled += onCancelAction;
context.OnShow();
}
catch (Exception ex)
{
LogManager.Log(ex, $"Error display modal dialog. {typeof(VM).Name}");
onCancel?.Invoke();
}
};
dialog.ShowDialog();
MainWindow.Instance.shadowGrid.Visibility = Visibility.Hidden;
}
catch (Exception ex)
{
LogManager.Log(ex, $"Error display modal dialog. {typeof(VM).Name}");
onCancel?.Invoke();
}
finally
{
MainWindow.Instance.shadowGrid.Visibility = Visibility.Hidden;
}
}
///
/// Shows the specified view with the specified view model as it's data context.
///
/// The type of the mm.
/// The type of the view.
/// The view model.
/// The view.
/// The accept action.
/// The cancel action.
public void ShowModalDialog(VM vm, Action onAccept, Action onCancel) where View : FrameworkElement where VM : DialogViewVM
{
try
{
var view = Activator.CreateInstance();
DialogWindow dialog = new DialogWindow();
dialog.Owner = Application.Current.MainWindow;
dialog.InnerContent = view;
MainWindow.Instance.shadowGrid.Visibility = Visibility.Visible;
view.Loaded += (x, y) =>
{
try
{
VM context = vm;
dialog.DataContext = context;
Action onAcceptAction = null;
Action onCancelAction = null;
onAcceptAction = new Action(() =>
{
dialog.Close();
onAccept(context);
context.Accepted -= onAcceptAction;
context.Canceled -= onCancelAction;
});
onCancelAction = new Action(() =>
{
dialog.Close();
if (onCancel != null)
{
onCancel();
}
context.Accepted -= onAcceptAction;
context.Canceled -= onCancelAction;
});
context.Accepted += onAcceptAction;
context.Canceled += onCancelAction;
context.OnShow();
}
catch (Exception ex)
{
LogManager.Log(ex, $"Error display modal dialog. {typeof(VM).Name}");
onCancel?.Invoke();
}
};
dialog.ShowDialog();
}
catch (Exception ex)
{
LogManager.Log(ex, $"Error display modal dialog. {typeof(VM).Name}");
onCancel?.Invoke();
}
finally
{
MainWindow.Instance.shadowGrid.Visibility = Visibility.Hidden;
}
}
///
/// Creates a new view by a naming convention of the specified view model type.
///
/// The type of the view model.
/// Accept button callback.
/// Cancel button callback.
/// Could not locate view " + viewName
public void ShowModalDialog(Action onAccept, Action onCancel) where VM : DialogViewVM
{
try
{
String viewName = typeof(VM).Name.Replace("VM", "");
if (viewTypes == null)
{
viewTypes = AppDomain.CurrentDomain.GetAssemblies().Where(x => x.FullName.Contains("MachineStudio")).SelectMany(x => x.GetTypes()).ToList();
}
var viewType = viewTypes.SingleOrDefault(x => x.Name == viewName);
if (viewType == null)
{
throw new NullReferenceException("Could not locate view " + viewName);
}
var view = Activator.CreateInstance(viewType) as FrameworkElement;
DialogWindow dialog = new DialogWindow();
dialog.Owner = Application.Current.MainWindow;
dialog.InnerContent = view;
MainWindow.Instance.shadowGrid.Visibility = Visibility.Visible;
view.Loaded += (x, y) =>
{
try
{
VM context = view.DataContext as VM;
if (context == null)
{
context = Activator.CreateInstance();
}
dialog.DataContext = context;
Action onCancelAction = null;
Action onAcceptAction = null;
onAcceptAction = new Action(() =>
{
dialog.Close();
onAccept(context);
context.Canceled -= onCancelAction;
context.Accepted -= onAcceptAction;
});
onCancelAction = new Action(() =>
{
dialog.Close();
if (onCancel != null)
{
onCancel();
}
context.Canceled -= onCancelAction;
context.Accepted -= onAcceptAction;
});
context.Accepted += onAcceptAction;
context.Canceled += onCancelAction;
context.OnShow();
}
catch (Exception ex)
{
LogManager.Log(ex, $"Error display modal dialog. {typeof(VM).Name}");
onCancel?.Invoke();
return;
}
};
dialog.ShowDialog();
}
catch (Exception ex)
{
LogManager.Log(ex, $"Error display modal dialog. {typeof(VM).Name}");
onCancel?.Invoke();
}
finally
{
MainWindow.Instance.shadowGrid.Visibility = Visibility.Hidden;
}
}
///
/// Creates a new view by a naming convention of the specified view model type.
///
/// The type of the view model.
/// Accept button callback.
public void ShowModalDialog(Action onAccept) where VM : DialogViewVM
{
ShowModalDialog(onAccept, null);
}
///
/// Shows an error message box.
///
/// The message.
public void ShowError(string message)
{
ShowMessageBox(PackIconKind.AlertOctagon, (SolidColorBrush)Application.Current.Resources["RedBrush100"], message, false);
}
///
/// Shows an information message box.
///
/// The message.
public void ShowInfo(string message)
{
ShowMessageBox(PackIconKind.CommentAlertOutline, (SolidColorBrush)Application.Current.Resources["Dialog.Foreground"], message, false);
}
///
/// Shows a question message box.
///
/// The message.
///
public bool ShowQuestion(string message)
{
return ShowMessageBox(PackIconKind.CommentQuestionOutline, (SolidColorBrush)Application.Current.Resources["Dialog.Foreground"], message, true).Value;
}
///
/// Shows warning message box.
///
/// The message.
public void ShowWarning(string message)
{
ShowMessageBox(PackIconKind.AlertOutline, (SolidColorBrush)Application.Current.Resources["OrangeUploadBrush"], message, false);
}
///
/// Shows a question message box with an error icon.
///
/// The message.
///
public bool ShowErrorQuestion(string message)
{
return ShowMessageBox(PackIconKind.CommentAlertOutline, (SolidColorBrush)Application.Current.Resources["OrangeUploadBrush"], message, true).Value;
}
///
/// Pushes the specified task item to the queue.
///
/// The task item.
public void PushTaskItem(TaskItem taskItem)
{
InvokeUI(() =>
{
TaskItems.Add(taskItem);
CurrentTaskItem = taskItem;
});
}
///
/// Create and push a new task item from the specified message.
///
/// The message.
///
public TaskItem PushTaskItem(string message)
{
TaskItem item = new TaskItem(this);
item.Message = message;
PushTaskItem(item);
return item;
}
///
/// Removed the specified task item from the queue.
///
/// The task item.
public void PopTaskItem(TaskItem taskItem)
{
Task.Delay(1000).ContinueWith((x) =>
{
InvokeUI(() =>
{
TaskItems.Remove(taskItem);
if (TaskItems.Count > 0)
{
CurrentTaskItem = TaskItems.Last();
}
RaisePropertyChanged(nameof(HasTaskItems));
});
});
}
///
/// Pushes the specified bar item.
///
/// The bar item.
///
public BarItem PushBarItem(BarItem barItem)
{
BarItems.Add(barItem);
return barItem;
}
///
/// Creates and push a new bar item from the specified framework element.
///
/// The element.
///
public BarItem PushBarItem(FrameworkElement element)
{
BarItem item = new BarItem(this);
item.Element = element;
PushBarItem(item);
return item;
}
///
/// Removed the specified bar item.
///
/// The bar item.
public void PopBarItem(BarItem barItem)
{
BarItems.Remove(barItem);
}
///
/// Shows a dialog with a text input field and returns the response.
///
/// The message.
/// Text field hint.
/// Optional default response.
///
public string ShowTextInput(string message, string hint, string defaultResponse = null)
{
MainWindow.Instance.shadowGrid.Visibility = Visibility.Visible;
TextInputBoxWindow dlg = new TextInputBoxWindow()
{
Owner = Application.Current.MainWindow,
Message = message,
IconKind = PackIconKind.Pencil,
IconColor = (SolidColorBrush)Application.Current.Resources["DimGrayBrush"],
Hint = hint,
Response = defaultResponse
};
var result = dlg.ShowDialog();
MainWindow.Instance.shadowGrid.Visibility = Visibility.Hidden;
return (result.Value ? dlg.Response : null);
}
}
}