using BettingPredictor.UI; using System; using System.Data; using System.IO; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace BettingPredictor { public partial class Main : Form { private readonly HorseRacingPredictor.Football.Main footballManager; private HorseRacingPredictor.HorseRacing.Main racingManager; private DataTable footballData; private DataTable racingData; // Credenziali predefinite Racing API private const string DefaultRacingUser = "qi1mHOHPquDY9KNDASAeGipy"; private const string DefaultRacingPass = "RXNFU1YX27R9rTnk8Vop8ZfH"; // Pagine e nav gestiti come array per semplificare la navigazione private Panel[] pages; private NavButton[] navButtons; private string[] pageTitles; public Main() { InitializeComponent(); footballManager = new HorseRacingPredictor.Football.Main(); racingManager = new HorseRacingPredictor.HorseRacing.Main(DefaultRacingUser, DefaultRacingPass); pages = new[] { pageFootball, pageHorseRacing, pageSettings, pageInfo }; navButtons = new[] { navFootball, navHorseRacing, navSettings, navInfo }; pageTitles = new[] { "Calcio", "Corse Cavalli", "Impostazioni", "Informazioni" }; } #region Navigation private void ShowPage(int index) { for (int i = 0; i < pages.Length; i++) { pages[i].Visible = (i == index); navButtons[i].IsActive = (i == index); } labelPageTitle.Text = pageTitles[index]; } private void navFootball_Click(object sender, EventArgs e) => ShowPage(0); private void navHorseRacing_Click(object sender, EventArgs e) => ShowPage(1); private void navSettings_Click(object sender, EventArgs e) => ShowPage(2); private void navInfo_Click(object sender, EventArgs e) => ShowPage(3); #endregion #region Football private async Task DownloadFootballFixturesAsync(DateTime selectedDate) { try { progressBarFootball.Minimum = 0; progressBarFootball.Maximum = 100; progressBarFootball.Value = 0; labelStatusFootball.Text = "Scaricamento elenco partite..."; dateTimePicker.Enabled = false; btnDownload.Enabled = false; btnExportCsv.Enabled = false; var progress = new Progress(v => progressBarFootball.Value = v); var status = new Progress(s => labelStatusFootball.Text = s); var table = await Task.Run(() => footballManager.GetTodayFixtures(selectedDate, progress, status)); footballData = table; dataGridViewFootball.DataSource = footballData; if (footballData != null && footballData.Rows.Count > 0) { btnExportCsv.Enabled = true; labelStatusFootball.Text = $"Scaricate {footballData.Rows.Count} partite"; } else { labelStatusFootball.Text = "Nessuna partita trovata per la data selezionata"; } } catch (Exception ex) { MessageBox.Show($"Errore durante lo scaricamento:\n{ex.Message}", "Errore", MessageBoxButtons.OK, MessageBoxIcon.Error); labelStatusFootball.Text = "Errore nello scaricamento"; progressBarFootball.Value = 0; } finally { dateTimePicker.Enabled = true; btnDownload.Enabled = true; } } private void ExportFootballToCsv() { if (footballData == null || footballData.Rows.Count == 0) { MessageBox.Show("Nessun dato da esportare. Scarica prima le partite.", "Nessun dato", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } string folder = txtExportPath.Text; string filePath = null; if (!string.IsNullOrEmpty(folder) && Directory.Exists(folder)) { filePath = Path.Combine(folder, $"Partite_{dateTimePicker.Value:yyyy-MM-dd}.csv"); } else { using (var dlg = new SaveFileDialog()) { dlg.Filter = "File CSV|*.csv"; dlg.FileName = $"Partite_{dateTimePicker.Value:yyyy-MM-dd}.csv"; if (dlg.ShowDialog() != DialogResult.OK) return; filePath = dlg.FileName; } } try { var sb = new StringBuilder(); var headers = new string[footballData.Columns.Count]; for (int i = 0; i < footballData.Columns.Count; i++) headers[i] = footballData.Columns[i].ColumnName; sb.AppendLine(string.Join(";", headers)); foreach (DataRow row in footballData.Rows) { var vals = new string[footballData.Columns.Count]; for (int i = 0; i < footballData.Columns.Count; i++) { var v = row[i]?.ToString() ?? ""; if (v.Contains(";") || v.Contains("\"")) v = "\"" + v.Replace("\"", "\"\"") + "\""; vals[i] = v; } sb.AppendLine(string.Join(";", vals)); } File.WriteAllText(filePath, sb.ToString(), Encoding.UTF8); labelStatusFootball.Text = $"CSV esportato: {Path.GetFileName(filePath)}"; MessageBox.Show($"Esportate {footballData.Rows.Count} partite in:\n{filePath}", "Esportazione completata", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { MessageBox.Show($"Errore durante l'esportazione CSV:\n{ex.Message}", "Errore", MessageBoxButtons.OK, MessageBoxIcon.Error); } } #endregion #region Horse Racing private async Task DownloadRacecardsAsync() { try { progressBarRacing.Minimum = 0; progressBarRacing.Maximum = 100; progressBarRacing.Value = 0; labelStatusRacing.Text = "Scaricamento racecard..."; cmbRacingDay.Enabled = false; btnDownloadRacing.Enabled = false; btnExportRacingCsv.Enabled = false; var progress = new Progress(v => progressBarRacing.Value = v); var status = new Progress(s => labelStatusRacing.Text = s); string day = cmbRacingDay.SelectedIndex == 0 ? "today" : "tomorrow"; var table = await Task.Run(() => racingManager.GetRacecards(day, progress, status)); racingData = table; dataGridViewRacing.DataSource = racingData; if (racingData != null && racingData.Rows.Count > 0) { btnExportRacingCsv.Enabled = true; labelStatusRacing.Text = $"Trovate {racingData.Rows.Count} corse"; } else { labelStatusRacing.Text = "Nessuna corsa trovata"; } } catch (Exception ex) { MessageBox.Show($"Errore durante lo scaricamento:\n{ex.Message}", "Errore", MessageBoxButtons.OK, MessageBoxIcon.Error); labelStatusRacing.Text = "Errore nello scaricamento"; progressBarRacing.Value = 0; } finally { cmbRacingDay.Enabled = true; btnDownloadRacing.Enabled = true; } } private void ExportRacingToCsv() { if (racingData == null || racingData.Rows.Count == 0) { MessageBox.Show("Nessun dato da esportare. Scarica prima le corse.", "Nessun dato", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } string folder = txtExportPath.Text; string dayLabel = cmbRacingDay.SelectedIndex == 0 ? "oggi" : "domani"; string filePath = null; if (!string.IsNullOrEmpty(folder) && Directory.Exists(folder)) { filePath = Path.Combine(folder, $"Corse_{dayLabel}_{DateTime.Now:yyyy-MM-dd}.csv"); } else { using (var dlg = new SaveFileDialog()) { dlg.Filter = "File CSV|*.csv"; dlg.FileName = $"Corse_{dayLabel}_{DateTime.Now:yyyy-MM-dd}.csv"; if (dlg.ShowDialog() != DialogResult.OK) return; filePath = dlg.FileName; } } try { var sb = new StringBuilder(); var headers = new string[racingData.Columns.Count]; for (int i = 0; i < racingData.Columns.Count; i++) headers[i] = racingData.Columns[i].ColumnName; sb.AppendLine(string.Join(";", headers)); foreach (DataRow row in racingData.Rows) { var vals = new string[racingData.Columns.Count]; for (int i = 0; i < racingData.Columns.Count; i++) { var v = row[i]?.ToString() ?? ""; if (v.Contains(";") || v.Contains("\"")) v = "\"" + v.Replace("\"", "\"\"") + "\""; vals[i] = v; } sb.AppendLine(string.Join(";", vals)); } File.WriteAllText(filePath, sb.ToString(), Encoding.UTF8); labelStatusRacing.Text = $"CSV esportato: {Path.GetFileName(filePath)}"; MessageBox.Show($"Esportate {racingData.Rows.Count} corse in:\n{filePath}", "Esportazione completata", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { MessageBox.Show($"Errore durante l'esportazione CSV:\n{ex.Message}", "Errore", MessageBoxButtons.OK, MessageBoxIcon.Error); } } #endregion #region Settings private string SettingsFilePath => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "settings.ini"); private void LoadSettings() { try { // Imposta valori predefiniti Racing API txtRacingUser.Text = DefaultRacingUser; txtRacingPass.Text = DefaultRacingPass; if (!File.Exists(SettingsFilePath)) return; foreach (var line in File.ReadAllLines(SettingsFilePath)) { var idx = line.IndexOf('='); if (idx < 0) continue; var key = line.Substring(0, idx).Trim(); var val = line.Substring(idx + 1).Trim(); if (key == "ApiKey") txtApiKey.Text = val; else if (key == "ExportPath") txtExportPath.Text = val; else if (key == "RacingUser") txtRacingUser.Text = val; else if (key == "RacingPass") txtRacingPass.Text = val; } // Aggiorna il manager con le credenziali caricate racingManager.UpdateCredentials(txtRacingUser.Text, txtRacingPass.Text); } catch { } } private void SaveSettings() { try { var sb = new StringBuilder(); sb.AppendLine($"ApiKey={txtApiKey.Text.Trim()}"); sb.AppendLine($"ExportPath={txtExportPath.Text.Trim()}"); sb.AppendLine($"RacingUser={txtRacingUser.Text.Trim()}"); sb.AppendLine($"RacingPass={txtRacingPass.Text.Trim()}"); File.WriteAllText(SettingsFilePath, sb.ToString(), Encoding.UTF8); // Aggiorna il manager con le nuove credenziali racingManager.UpdateCredentials(txtRacingUser.Text.Trim(), txtRacingPass.Text.Trim()); MessageBox.Show("Impostazioni salvate con successo.", "Salvato", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { MessageBox.Show($"Errore nel salvataggio:\n{ex.Message}", "Errore", MessageBoxButtons.OK, MessageBoxIcon.Error); } } #endregion #region Event handlers private void Main_Load(object sender, EventArgs e) { dateTimePicker.Value = DateTime.Today; progressBarFootball.Value = 0; labelStatusFootball.Text = "Pronto"; progressBarRacing.Value = 0; labelStatusRacing.Text = "Pronto"; LoadSettings(); LayoutToolbars(); } private void Main_Resize(object sender, EventArgs e) { LayoutToolbars(); } private void btnDownload_Click(object sender, EventArgs e) { _ = DownloadFootballFixturesAsync(dateTimePicker.Value); } private void btnExportCsv_Click(object sender, EventArgs e) { ExportFootballToCsv(); } private void btnDownloadRacing_Click(object sender, EventArgs e) { _ = DownloadRacecardsAsync(); } private void btnExportRacingCsv_Click(object sender, EventArgs e) { ExportRacingToCsv(); } private void btnBrowseExport_Click(object sender, EventArgs e) { using (var dlg = new FolderBrowserDialog()) { dlg.Description = "Seleziona la cartella di esportazione CSV"; if (dlg.ShowDialog() == DialogResult.OK) txtExportPath.Text = dlg.SelectedPath; } } private void btnSaveSettings_Click(object sender, EventArgs e) { SaveSettings(); } #endregion } }