// Copyright (c) 2023 schick Informatik
// Description: Bremen calling main window
//
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using BreCalClient.misc.Api;
using BreCalClient.misc.Client;
using BreCalClient.misc.Model;
namespace BreCalClient
{
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow : Window
{
private const int SHIPCALL_UPDATE_INTERVAL_SECONDS = 30;
private DefaultApi _api;
private ObservableCollection _controlModels = new();
private List _ships = new();
private ConcurrentDictionary _shipLookupDict = new();
private List _berths = new();
private ConcurrentDictionary _berthLookupDict = new();
private List _participants = new();
private Dictionary _participantLookupDict = new();
private CancellationTokenSource _tokenSource = new CancellationTokenSource();
public MainWindow()
{
InitializeComponent();
_api = new DefaultApi();
_api.Configuration.ApiKeyPrefix["Authorization"] = "Bearer";
}
#region event handler
private void Window_Loaded(object sender, RoutedEventArgs e)
{
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
_tokenSource.Cancel();
}
private async void buttonLogin_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(this.textPassword.Password) || string.IsNullOrEmpty(this.textUsername.Text))
{
this.labelLoginResult.Content = Application.Current.FindResource("textUserNamePasswordEmpty").ToString();
return;
}
Credentials credentials = new(username: textUsername.Text.Trim(),
password: textPassword.Password.Trim());
try
{
LoginResult loginResult = await _api.LoginPostAsync(credentials);
if(loginResult != null)
{
if(loginResult.Id > 0)
{
this.busyIndicator.IsBusy = false;
this._api.Configuration.ApiKey["Authorization"] = loginResult.Token;
this.LoadStaticLists();
}
}
}
catch (ApiException ex)
{
this.labelLoginResult.Content = ex.Message;
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void buttonExit_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
#endregion
#region private methods
private async void LoadStaticLists()
{
this._berths = await _api.BerthsGetAsync();
foreach(var berth in this._berths)
_berthLookupDict[berth.Id] = berth;
this.searchFilterControl.SetBerths(this._berths);
this._ships = await _api.ShipsGetAsync();
foreach(var ship in this._ships)
_shipLookupDict[ship.Id] = ship;
this._participants = await _api.ParticipantGetAsync();
List agencies = new List();
foreach (Participant participant in this._participants)
{
this._participantLookupDict[participant.Id] = participant;
}
_ = Task.Run(() => RefreshShipcalls());
}
public async Task RefreshShipcalls()
{
while (!_tokenSource.Token.IsCancellationRequested)
{
List shipcalls = await _api.ShipcallsGetAsync();
foreach (Shipcall shipcall in shipcalls)
{
ShipcallControlModel? selectedSCMModel = null;
foreach(ShipcallControlModel scm in this._controlModels)
{
if(scm.Shipcall?.Id == shipcall.Id)
{
selectedSCMModel = scm;
break;
}
}
if(selectedSCMModel != null)
{
selectedSCMModel.Shipcall = shipcall;
}
else
{
// no: create new entry
ShipcallControlModel scm = new ShipcallControlModel();
scm.Shipcall = shipcall;
if (this._shipLookupDict.ContainsKey(shipcall.ShipId))
scm.Ship = this._shipLookupDict[shipcall.ShipId];
_controlModels.Add(scm);
this.Dispatcher.Invoke(new Action(() =>
{
ShipcallControl sc = new ShipcallControl();
sc.Height = 80;
sc.ShipcallControlModel = scm;
sc.TimesRequested += Sc_TimesRequested;
sc.EditRequested += Sc_EditRequested;
this.stackPanel.Children.Add(sc);
}));
}
}
// test for deletion, anything in the display that is not in the lookup result
foreach(ShipcallControlModel scm in this._controlModels)
{
}
await Task.Delay(TimeSpan.FromSeconds(SHIPCALL_UPDATE_INTERVAL_SECONDS), _tokenSource.Token);
}
}
private void Sc_EditRequested(ShipcallControl obj)
{
// TODO: get the shipcall from the control and show the edit control
}
private void Sc_TimesRequested(ShipcallControl obj)
{
// TODO: get the shipcall, load and show a list of the times
}
#endregion
}
}