using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Ookii.Dialogs.Wpf;
using EDPlayerJournal;
using EDPlayerJournal.BGS;
using EDPlayerJournal.Entries;
using EliteBGS.BGS;
using EliteBGS.Util;
using System.Windows.Forms;
namespace EliteBGS;
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow : Window {
private PlayerJournal journal;
private Report report;
public Config Config { get; set; } = new Config();
private LoadEntriesWindow loadentries = null;
private static readonly List logtypes = new List() {
new NonaDiscordLog(),
new GenericDiscordLog(),
};
public MainWindow() {
InitializeComponent();
try {
Config.LoadGlobal();
} catch (Exception) {
/* ignored */
}
foreach (DiscordLogGenerator type in logtypes) {
LogType.Items.Add(type);
}
string lastused = Config.Global.LastUsedDiscordTemplate;
int lastindex = logtypes.FindIndex(x => x.ToString() == lastused);
if (lastindex > -1) {
LogType.SelectedIndex = lastindex;
} else {
LogType.SelectedIndex = 0;
}
journal = new PlayerJournal(Config.Global.JournalLocation);
// Set both to now
startdate.SelectedDate = DateTime.Now;
enddate.SelectedDate = DateTime.Now;
journallocation.Text = Config.Global.JournalLocation;
}
private void TreeView_CheckBox_Updated(object sender, RoutedEventArgs args) {
GenerateLog();
}
private void HandleEntries(List entries) {
try {
TransactionParser parser = new TransactionParser();
List transactions = parser.Parse(entries);
List incompletes = transactions.OfType().ToList();
// Log incomplete and remove them from the results.
foreach (var incomplete in incompletes) {
Log(incomplete.Reason);
}
transactions.RemoveAll(x => incompletes.Contains(x));
report = new Report(transactions);
this.entries.ItemsSource = report.Objectives;
} catch (Exception exception) {
Log("Something went terribly wrong while parsing the E:D player journal.");
Log("Please send this to CMDR Hekateh:");
Log(exception.ToString());
}
}
private void Loadentries_EntriesLoaded(List lines) {
HandleEntries(lines);
}
private void Report_OnLog(string message) {
StringBuilder builder = new StringBuilder();
builder.Append(DateTime.Now.ToString());
builder.Append(": ");
builder.Append(message);
builder.Append("\n");
log.AppendText(builder.ToString());
}
private void Log(string message) {
Report_OnLog(message);
}
private void ParseJournal_Click(object sender, RoutedEventArgs e) {
try {
TransactionParser parser = new TransactionParser();
DateTime start = startdate.SelectedDate ?? DateTime.Now;
DateTime end = enddate.SelectedDate ?? DateTime.Now;
journal.Open(); // Load all files
// Log files only get rotated if you restart the game client. This means that there might
// be - say - entries from the 4th of May in the file with a timestamp of 3rd of May. This
// happens if you happen to play a session late into the night.
// At first I tried extracting the first and last line of a file to see the date range, but
// if you have a lot of files this becomes quite slow, and quite the memory hog (as journal
// files have to be read in their entirety to check this). So we assume that you can't play
// three days straight, and keep the code fast.
DateTime actualstart = start.AddDays(-3);
List entries = journal.Files
.Where(f => f.NormalisedDateTime >= actualstart && f.NormalisedDateTime <= end)
.SelectMany(e => e.Entries)
.ToList()
;
// Now further sort the list down to entries that are actually within the given datetime
// Note that entry datetimes are not normalised, so we have to sort until end + 1 day
DateTime actualend = end.AddDays(1);
entries = entries
.Where(e => e.Timestamp >= start && e.Timestamp < actualend)
.ToList()
;
HandleEntries(entries);
GenerateLog();
} catch (Exception exception) {
Log("Something went terribly wrong while parsing the E:D player journal.");
Log("Please send this to CMDR Hekateh:");
Log(exception.ToString());
}
}
private void GenerateLog() {
try {
DiscordLogGenerator discord = LogType.SelectedItem as DiscordLogGenerator;
string report = discord.GenerateDiscordLog(this.report);
DiscordLog.Text = report;
} catch (Exception exception) {
Log("Something went terribly wrong while generating the Discord log.");
Log("Please send this to CMDR Hekateh:");
Log(exception.ToString());
}
}
private void GenerateDiscord_Click(object sender, RoutedEventArgs e) {
GenerateLog();
}
private void RemoveCurrentObjective() {
if (entries.SelectedItem == null) {
return;
}
object obj = entries.SelectedItem;
bool removed = false;
if (obj.GetType() == typeof(Objective)) {
removed = report.Objectives.Remove(obj as Objective);
} else if (obj.GetType() == typeof(UITransaction) ||
obj.GetType().IsSubclassOf(typeof(UITransaction))) {
foreach (Objective parent in report.Objectives) {
if (parent.UITransactions.Remove(obj as UITransaction)) {
removed = true;
}
}
}
if (removed) {
RefreshView();
}
}
private void entries_KeyUp(object sender, System.Windows.Input.KeyEventArgs e) {
if (e.Key == Key.Delete) {
RemoveCurrentObjective();
}
}
private void browsejournallocation_Click(object sender, RoutedEventArgs e) {
var dialog = new VistaFolderBrowserDialog();
if ((bool)!dialog.ShowDialog()) {
return;
}
Config.Global.JournalLocation = dialog.SelectedPath;
journallocation.Text = Config.Global.JournalLocation;
journal = new PlayerJournal(Config.Global.JournalLocation);
}
private void AddCombatZone_Click(object sender, RoutedEventArgs e) {
System.Windows.Controls.Control control = sender as System.Windows.Controls.Control;
if (control == null || control.DataContext == null) {
return;
}
Objective objective = control.DataContext as Objective;
if (objective == null) {
return;
}
CombatZone zone = new CombatZone {
Faction = objective.Faction,
System = objective.System,
Grade = "Low",
Type = "Ship",
};
UITransaction uitransaction = new UITransaction(zone);
objective.UITransactions.Add(uitransaction);
RefreshView();
}
private void RefreshView() {
entries.Items.Refresh();
GenerateLog();
}
private void LogType_SelectionChanged(object sender, SelectionChangedEventArgs e) {
if (LogType.SelectedItem == null) {
return;
}
string template = LogType.SelectedItem.ToString();
Config.Global.LastUsedDiscordTemplate = template;
GenerateLog();
}
private void ManuallyParse_Click(object sender, RoutedEventArgs e) {
if (loadentries != null) {
loadentries.Show();
return;
}
loadentries = new LoadEntriesWindow();
loadentries.Closed += Loadentries_Closed;
loadentries.EntriesLoaded += Loadentries_EntriesLoaded;
loadentries.Show();
}
private void Loadentries_Closed(object sender, EventArgs e) {
loadentries = null;
}
private void window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
loadentries?.Close();
loadentries = null;
}
private void Transaction_Initialized(object sender, EventArgs e) {
}
private TransactionType GetTransaction(object sender) where TransactionType : Transaction {
System.Windows.Controls.Control button = sender as System.Windows.Controls.Control;
if (button == null || button.DataContext == null) {
return null;
}
UITransaction transaction = button.DataContext as UITransaction;
if (transaction == null) {
return null;
}
return transaction.Transaction as TransactionType;
}
private void Low_Click(object sender, RoutedEventArgs e) {
CombatZone transaction = GetTransaction(sender);
if (transaction == null) {
return;
}
transaction.Grade = CombatZone.DifficultyLow;
RefreshView();
}
private void Med_Click(object sender, RoutedEventArgs e) {
CombatZone transaction = GetTransaction(sender);
if (transaction == null) {
return;
}
transaction.Grade = CombatZone.DifficultyMedium;
RefreshView();
}
private void High_Click(object sender, RoutedEventArgs e) {
CombatZone transaction = GetTransaction(sender);
if (transaction == null) {
return;
}
transaction.Grade = CombatZone.DifficultyHigh;
RefreshView();
}
private void Ground_Click(object sender, RoutedEventArgs e) {
CombatZone transaction = GetTransaction(sender);
if (transaction == null) {
return;
}
transaction.Type = CombatZone.GroundCombatZone;
RefreshView();
}
private void Ship_Click(object sender, RoutedEventArgs e) {
CombatZone transaction = GetTransaction(sender);
if (transaction == null) {
return;
}
transaction.Type = CombatZone.ShipCombatZone;
RefreshView();
}
private void Profit_LostFocus(object sender, RoutedEventArgs e) {
RefreshView();
}
private void Profit_KeyUp(object sender, System.Windows.Input.KeyEventArgs e) {
if (e.Key == Key.Enter) {
RefreshView();
}
}
}