using InABox.Clients;
using InABox.Core;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.IO;
namespace InABox.Wpf;
public enum MessageWindowButtonPosition
{
Left,
Right
}
public enum MessageWindowResult
{
None,
OK,
Cancel,
Other
}
public class MessageWindowButton : INotifyPropertyChanged
{
public delegate void MessageWindowButtonDelegate(MessageWindow window, MessageWindowButton button);
public MessageWindowButtonPosition Position { get; set; }
private string _content;
public string Content
{
get => _content;
[MemberNotNull(nameof(_content))]
set
{
_content = value;
OnPropertyChanged();
}
}
public MessageWindowButtonDelegate Action { get; set; }
public MessageWindowButton(string content, MessageWindowButtonDelegate action, MessageWindowButtonPosition position)
{
Content = content;
Action = action;
Position = position;
}
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
///
/// Interaction logic for MessageWindow.xaml
///
public partial class MessageWindow : Window, INotifyPropertyChanged
{
public ObservableCollection Buttons { get; private set; } = new();
public IEnumerable LeftButtons => Buttons.Where(x => x.Position == MessageWindowButtonPosition.Left);
public IEnumerable RightButtons => Buttons.Where(x => x.Position == MessageWindowButtonPosition.Right);
private string _message = "";
public string Message
{
get => _message;
set
{
_message = value;
OnPropertyChanged();
}
}
private string _details = "";
public string Details
{
get => _details;
set
{
_details = value;
OnPropertyChanged();
}
}
public static readonly DependencyProperty ShowDetailsProperty = DependencyProperty.Register(nameof(ShowDetails), typeof(bool), typeof(MessageWindow));
public bool ShowDetails
{
get => (bool)GetValue(ShowDetailsProperty);
set => SetValue(ShowDetailsProperty, value);
}
public MessageWindowResult Result { get; set; } = MessageWindowResult.None;
public object? OtherResult { get; set; }
public MessageWindow()
{
InitializeComponent();
Buttons.CollectionChanged += Buttons_CollectionChanged;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (sender is not Button button || button.Tag is not MessageWindowButton winButton) return;
winButton.Action(this, winButton);
}
private void Buttons_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
OnPropertyChanged(nameof(LeftButtons));
OnPropertyChanged(nameof(RightButtons));
}
public void AddButton(MessageWindowButton button)
{
Buttons.Add(button);
}
public void AddOKButton(string content = "OK")
{
Buttons.Add(new MessageWindowButton(content, OKButton_Click, MessageWindowButtonPosition.Right));
}
public void AddCancelButton(string content = "Cancel")
{
Buttons.Add(new MessageWindowButton(content, CancelButton_Click, MessageWindowButtonPosition.Right));
}
private void CancelButton_Click(MessageWindow window, MessageWindowButton button)
{
Result = MessageWindowResult.Cancel;
Close();
}
private void OKButton_Click(MessageWindow window, MessageWindowButton button)
{
Result = MessageWindowResult.OK;
Close();
}
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#region Static Constructors
public static void ShowMessage(string message, string title)
{
var window = new MessageWindow
{
Message = message,
Title = title
};
window.AddOKButton();
window.ShowDialog();
}
public static bool ShowOKCancel(string message, string title)
{
var window = new MessageWindow
{
Message = message,
Title = title
};
window.AddOKButton();
window.AddCancelButton();
window.ShowDialog();
return window.Result == MessageWindowResult.OK;
}
public static bool ShowYesNo(string message, string title)
{
var window = new MessageWindow
{
Message = message,
Title = title
};
window.AddOKButton("Yes");
window.AddCancelButton("No");
window.ShowDialog();
return window.Result == MessageWindowResult.OK;
}
///
/// Display a message box for an exception, giving options to view the logs.
///
/// The message to display. Set to to default to the exception message.
///
///
/// If , also logs the exception.
public static void ShowError(string? message, Exception exception, string title = "Error", bool shouldLog = true)
{
if (shouldLog)
{
CoreUtils.LogException(ClientFactory.UserID, exception);
}
var window = new MessageWindow
{
Message = message ?? exception.Message,
Title = title,
Details = CoreUtils.FormatException(exception)
};
window.AddButton(new MessageWindowButton("Show Logs", ShowLogs_Click, MessageWindowButtonPosition.Left));
var showDetailsButton = new MessageWindowButton("Show Details", (win, button) =>
{
win.ShowDetails = !win.ShowDetails;
button.Content = win.ShowDetails
? "Hide Details"
: "Show Details";
}, MessageWindowButtonPosition.Left);
window.AddButton(showDetailsButton);
window.AddOKButton();
window.ShowDialog();
}
private static void ShowLogs_Click(MessageWindow window, MessageWindowButton button)
{
var console = new MessageWindowConsole("Logs", Path.Combine(CoreUtils.GetPath(), string.Format("{0:yyyy-MM-dd}.log", DateTime.Today)));
console.ShowDialog();
}
#endregion
}
public class MessageWindowConsole : Console.Console
{
public string FileName { get; set; }
public MessageWindowConsole(string description, string file) : base(description)
{
FileName = file;
ConsoleControl.AllowLoadLogButton = false;
}
protected override void OnLoaded()
{
base.OnLoaded();
if (File.Exists(FileName))
{
var lines = File.ReadLines(FileName);
ConsoleControl.LoadLogEntries(lines);
}
}
protected override string GetLogDirectory()
{
return CoreUtils.GetPath();
}
}