Files
TrackTrends/Test_Merge/Form1.cs
T
2023-05-25 14:15:12 +02:00

385 lines
16 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace Test_Merge
{
public partial class Main : Form
{
//private Reader Reader = null;
private F1TVEmulator Emulator = null;
private DataWrapper Wrapper = null;
private bool cancelRequested = false;
private SemaphoreSlim semaphore = new SemaphoreSlim(1);
string ConfigFile = "";
string GpUrl = "";
//For the responsive content
Size oldSize = new Size();
Size oldRankingSize = new Size();
Size oldLapTimesSize = new Size();
Size oldBattles = new Size();
Size oldPnlBattles = new Size();
Size oldPnlRankings = new Size();
Size oldPnlFastest = new Size();
Size oldPnlSlowest = new Size();
Point oldRankingPosition = new Point();
Point oldBattlePosition = new Point();
Point oldDriverInfoPosition = new Point();
Point olPnlFastestPosition = new Point();
Point oldPnlSlowestPosition = new Point();
public Main()
{
InitializeComponent();
}
public async void RefreshUI()
{
if (Directory.Exists(ConfigurationTool.CONFIGS_FOLDER_NAME))
{
lsbPresets.DataSource = null;
lsbPresets.DataSource = Directory.GetFiles(ConfigurationTool.CONFIGS_FOLDER_NAME);
}
}
private async void btnSettings_Click(object sender, EventArgs e)
{
if (Emulator != null)
Emulator.ResetDriver();
Emulator = null;
Wrapper = null;
GC.Collect();
Settings settingsForm = new Settings();
settingsForm.ShowDialog();
RefreshUI();
//MessageBox.Show(settingsForm.GrandPrixUrl + Environment.NewLine + settingsForm.GrandPrixName + Environment.NewLine + settingsForm.GrandPrixYear);
if (settingsForm.GrandPrixUrl != "" && settingsForm.SelectedConfigFile != "")
{
GpUrl = settingsForm.GrandPrixUrl;
if (File.Exists(settingsForm.SelectedConfigFile))
{
ConfigFile = settingsForm.SelectedConfigFile;
}
else
{
MessageBox.Show("The config file has not been found please return to the config and change it");
}
}
else
{
//WE dont care anymore, the user will choose its Grand Prix himself in the main program
//MessageBox.Show("There is no URL for the Grand Prix you want to decode. Please return to the config and add a valid one");
}
}
private async void Form1_Load(object sender, EventArgs e)
{
//Those are the default values but they will need to be changed later when the configuration has been done
ConfigFile = "./Presets/Clean_4K_2023.json";
GpUrl = "https://f1tv.formula1.com/detail/1000006688/2023-azerbaijan-grand-prix?action=play";
tbxGpUrl.Text = GpUrl;
oldSize = this.Size;
oldRankingSize = gpbxRanking.Size;
oldLapTimesSize = gpbxLapTimes.Size;
oldBattles = gpbxBattles.Size;
oldPnlRankings = pnlLiveRanking.Size;
oldPnlBattles = pnlBattles.Size;
oldPnlFastest = pnlFastest.Size;
oldPnlSlowest = pnlSlowest.Size;
oldRankingPosition = gpbxRanking.Location;
oldBattlePosition = gpbxBattles.Location;
oldDriverInfoPosition = gpbxDriverInfos.Location;
olPnlFastestPosition = pnlFastest.Location;
oldPnlSlowestPosition = pnlSlowest.Location;
tip1.SetToolTip(btnResetEmulator, "Starts or restarts the emulator. You need to start this to use the app");
tip1.SetToolTip(btnSettings, "Opens the configuration menu");
tip1.SetToolTip(tbxGpUrl, "Insert the URL of the Grand Prix you want to track. Dont forget the \"?action=play\" at the end");
tip1.SetToolTip(lsbPresets, "Select a configuration preset to use with the decoding");
tip1.SetToolTip(pbxResult,"A preview of what the program sees. You should see the DATA page of the F1TV here");
tip1.SetToolTip(lsbOvertakes,"A list of all the activity. You can scroll to see the most recent overtakes");
tip1.SetToolTip(gpbxBattles,"The four first battles in the field. A battle is two drivers less than 3 seconds apart");
tip1.SetToolTip(gpbxLapTimes,"The fastest and slowest drivers on track at the moment. It takes the average lapTime of the last 5 laps to choose who is the fastes or the slowest");
RefreshUI();
}
private async void btnUpdate_Click(object sender, EventArgs e)
{
cancelRequested = false;
if (Emulator != null && Wrapper != null)
{
// Disable UI controls to prevent re-entrancy
btnResetEmulator.Enabled = false;
btnStartDecoding.Enabled = false;
btnStopUpdating.Enabled = true;
btnSettings.Enabled = false;
while (!cancelRequested)
{
await semaphore.WaitAsync();
try
{
// Start the time-consuming task on a separate thread
await Task.Run(async () =>
{
Stopwatch sw = new Stopwatch();
sw.Start();
Bitmap screen = Emulator.Screenshot();
screen.Save("HopefullyDataScreenshot.png");
Invoke((MethodInvoker)delegate
{
pbxResult.Image = (Bitmap)screen.Clone();
});
Wrapper.ChangeImage(screen);
int errorCode = Wrapper.Refresh();
sw.Stop();
// Task completed
Invoke((MethodInvoker)delegate
{
DisplayResults(errorCode, sw, screen);
DisplayBattles();
DisplayDeltas();
DisplayOvertakes();
});
});
}
finally
{
semaphore.Release();
}
}
// Re-enable UI controls
btnStopUpdating.Text = "Stop";
btnStartDecoding.Enabled = true;
btnStopUpdating.Enabled = false;
btnResetEmulator.Enabled = true;
btnSettings.Enabled = true;
}
}
private void DisplayOvertakes()
{
Wrapper.DisplayOvertakes(lsbOvertakes);
}
private void DisplayBattles()
{
Wrapper.DisplayBattles(pnlBattles, this);
}
private void DisplayDeltas()
{
Wrapper.DisplayTimesDeltas(pnlFastest, pnlSlowest, this);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (Emulator != null)
{
Emulator.Stop();
}
}
private void DisplayResults(int errorCode, Stopwatch sw, Bitmap screen)
{
if (errorCode != 0)
{
cancelRequested = true;
MessageBox.Show("An error has occured while trying to recover data from live feed. This can happen sometimes. I would advise you to restart a few times. If the problem persists check your configuration.");
}
else
{
Wrapper.DisplayLiveRanking(pnlLiveRanking, this);
}
}
private void btnStopUpdating_Click(object sender, EventArgs e)
{
// Set the cancellation flag
cancelRequested = true;
btnStopUpdating.Enabled = false;
btnResetEmulator.Enabled = false;
btnStopUpdating.Text = "Stopping";
}
private async void button1_Click(object sender, EventArgs e)
{
lsbOvertakes.Items.Clear();
btnResetEmulator.Text = "Launching";
btnResetEmulator.Enabled = false;
btnSettings.Enabled = true;
btnStartDecoding.Enabled = false;
btnStopUpdating.Enabled = false;
btnSettings.Enabled = false;
int errorCode = -1;
await Task.Run(async () =>
{
if (Emulator != null)
Emulator.ResetDriver();
Emulator = null;
Wrapper = null;
GC.Collect();
Emulator = new F1TVEmulator(GpUrl);
errorCode = await Emulator.Start();
});
if (errorCode != 0)
{
//IMPLEMENT MORE SPECIFIC ERROR CODES !!
MessageBox.Show("An error has occured while trying to start the driver.");
btnResetEmulator.Enabled = true;
btnSettings.Enabled = true;
btnResetEmulator.Text = "Retry";
}
else
{
Wrapper = new DataWrapper(ConfigFile, Emulator.Screenshot());
btnResetEmulator.Text = "Re launch";
btnResetEmulator.Enabled = true;
btnSettings.Enabled = true;
btnStartDecoding.Enabled = true;
}
}
private void removeBorders(object sender, PaintEventArgs e)
{
GroupBox gpbx = (GroupBox)sender;
using (Pen pen = new Pen(gpbx.BackColor, 50))
{
e.Graphics.DrawRectangle(pen, 0, 0, gpbx.Width - 1, gpbx.Height - 1);
e.Graphics.DrawRectangle(pen, 0, 0, gpbx.Width - 1, gpbx.Height - 1);
}
using (var brush = new SolidBrush(gpbx.ForeColor))
{
var textPosition = new Point(5, 0); // Adjust the X and Y values as needed
e.Graphics.DrawString(gpbx.Text, gpbx.Font, brush, textPosition);
}
}
private void lsbPresets_SelectedIndexChanged(object sender, EventArgs e)
{
if (lsbPresets.SelectedIndex >= 0)
ConfigFile = lsbPresets.Items[lsbPresets.SelectedIndex].ToString();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (tbxGpUrl.Text != "")
GpUrl = tbxGpUrl.Text;
}
public void btnDriver_Click(object sender, EventArgs e)
{
//Removes the cover
if (pnlCover.Visible = true)
pnlCover.Visible = false;
//Happens when a driver button has been clicked
//MessageBox.Show((sender as Button).Name + " has been selected");
Button btn = (sender as Button);
string[] parts = btn.Name.Split('_');
DriverData driver = Wrapper.GetFullDriverData(parts[0], pnlCurrentDriverLapsHistory, this);
lblCurrentDriverName.Text = driver.Name;
lblCurrentDriverPosition.Text = driver.Position.ToString();
lblCurrentDriverGapToLeader.Text = Reader.ConvertMsToTime(driver.GapToLeader);
lblCurrentDriverLapTime.Text = Reader.ConvertMsToTime(driver.LapTime);
lblCurrentDriverTyreAge.Text = driver.CurrentTyre.NumberOfLaps.ToString();
if (driver.DRS)
{
lblCurrentDriverDRS.Text = "Open";
lblCurrentDriverDRS.ForeColor = Color.FromArgb(0, 164, 46);
}
else
{
lblCurrentDriverDRS.Text = "Closed";
lblCurrentDriverDRS.ForeColor = Color.Black;
}
switch (driver.CurrentTyre.Coumpound)
{
case Tyre.Type.Undefined:
lblCurrentDriverTyreType.Text = "uuuuh...";
lblCurrentDriverTyreType.ForeColor = Color.Violet;
break;
case Tyre.Type.Hard:
lblCurrentDriverTyreType.Text = "Hard";
lblCurrentDriverTyreType.ForeColor = Color.FromArgb(164, 165, 168);
break;
case Tyre.Type.Medium:
lblCurrentDriverTyreType.Text = "Medium";
lblCurrentDriverTyreType.ForeColor = Color.FromArgb(245, 191, 0);
break;
case Tyre.Type.Soft:
lblCurrentDriverTyreType.Text = "Soft";
lblCurrentDriverTyreType.ForeColor = Color.FromArgb(255, 0, 0);
break;
case Tyre.Type.Inter:
lblCurrentDriverTyreType.Text = "Intermediate";
lblCurrentDriverTyreType.ForeColor = Color.FromArgb(0, 164, 46);
break;
case Tyre.Type.Wet:
lblCurrentDriverTyreType.Text = "Wet";
lblCurrentDriverTyreType.ForeColor = Color.FromArgb(39, 96, 166);
break;
}
}
public void btnLapTime_Click(object sender, EventArgs e)
{
//Happens when a lapTime has been clicked
Button btn = sender as Button;
string[] parts = btn.Name.Split('_');
Wrapper.DisplayLapTimeInfos(parts[0], Convert.ToInt32(parts[1]), btn.Text);
}
private void Main_Resize(object sender, EventArgs e)
{
int xDiff = this.Width - oldSize.Width;
int yDiff = this.Height - oldSize.Height;
int padding = 10;
//This will take half the newly created space
gpbxRanking.Size = new Size(oldRankingSize.Width + xDiff / 2, oldRankingSize.Height + yDiff);
gpbxRanking.Location = new Point(oldRankingPosition.X + xDiff / 2, gpbxRanking.Location.Y);
//Will take half the new height and half the new height
gpbxLapTimes.Size = new Size(oldLapTimesSize.Width + xDiff / 2, oldLapTimesSize.Height + yDiff / 2);
//Will take half the new height and half the new width
gpbxBattles.Size = new Size(oldBattles.Width + xDiff / 2, oldBattles.Height + yDiff / 2);
gpbxBattles.Location = new Point(gpbxBattles.Location.X, oldBattlePosition.Y + yDiff / 2);
//The infos wont change width but will need to be centerd
Point startOfZone = new Point(gpbxOvertakes.Width + gpbxOvertakes.Location.X, gpbxOvertakes.Location.Y);
Point endOfZone = new Point(gpbxRanking.Location.X, gpbxOvertakes.Location.Y);
int totalWidth = endOfZone.X - startOfZone.X;
gpbxDriverInfos.Location = new Point(startOfZone.X + (totalWidth / 2 - gpbxDriverInfos.Width / 2), oldDriverInfoPosition.Y + yDiff);
//Now resizing internals
pnlFastest.Size = new Size(oldPnlFastest.Width + xDiff / 4,oldPnlFastest.Height + yDiff / 4);
pnlFastest.Location = new Point(olPnlFastestPosition.X,olPnlFastestPosition.Y + yDiff / 4);
pnlSlowest.Size = new Size(oldPnlSlowest.Width + xDiff / 4, oldPnlSlowest.Height + yDiff / 4);
pnlSlowest.Location = new Point(oldPnlSlowestPosition.X + xDiff / 4, oldPnlSlowestPosition.Y + yDiff / 4);
pnlBattles.Size = new Size(oldPnlBattles.Width + xDiff / 2,oldPnlBattles.Height + yDiff / 2);
pnlLiveRanking.Size = new Size(oldPnlRankings.Width + xDiff / 2,oldPnlRankings.Height + yDiff);
}
}
}