diff --git a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/BetType.cs b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/BetType.cs index c44c58d..7a71681 100644 --- a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/BetType.cs +++ b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/BetType.cs @@ -1,20 +1,16 @@ using System; -using System.Collections.Generic; using System.Data.SqlClient; -using System.Linq; -using System.Text; -using System.Text.Json.Nodes; -using System.Threading.Tasks; +using Newtonsoft.Json.Linq; namespace HorseRacingPredictor.Football.Database { internal class BetType : HorseRacingPredictor.Football.Manager.Database { - public void Upsert(SqlConnection connection, JsonNode betType) + public void Upsert(SqlConnection connection, JToken betType) { try { - var id = betType["id"]?.GetValue(); + var id = betType["id"]?.Value(); if (id == null) return; // Salta il record se l'id è null var query = @" @@ -29,7 +25,7 @@ namespace HorseRacingPredictor.Football.Database using (var command = new SqlCommand(query, connection)) { command.Parameters.AddWithValue("@bet_type_id", id); - command.Parameters.AddWithValue("@name", betType["name"]?.GetValue() ?? ""); + command.Parameters.AddWithValue("@name", betType["name"]?.Value() ?? ""); command.ExecuteNonQuery(); } } diff --git a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Bookmaker.cs b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Bookmaker.cs index 1746424..2a4e08f 100644 --- a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Bookmaker.cs +++ b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Bookmaker.cs @@ -1,20 +1,16 @@ using System; -using System.Collections.Generic; using System.Data.SqlClient; -using System.Linq; -using System.Text; -using System.Text.Json.Nodes; -using System.Threading.Tasks; +using Newtonsoft.Json.Linq; namespace HorseRacingPredictor.Football.Database { internal class Bookmaker : HorseRacingPredictor.Football.Manager.Database { - public void Upsert(SqlConnection connection, JsonNode bookmaker) + public void Upsert(SqlConnection connection, JToken bookmaker) { try { - var id = bookmaker["id"]?.GetValue(); + var id = bookmaker["id"]?.Value(); if (id == null) return; // Salta il record se l'id è null var query = @" @@ -29,7 +25,7 @@ namespace HorseRacingPredictor.Football.Database using (var command = new SqlCommand(query, connection)) { command.Parameters.AddWithValue("@bookmaker_id", id); - command.Parameters.AddWithValue("@name", bookmaker["name"]?.GetValue() ?? ""); + command.Parameters.AddWithValue("@name", bookmaker["name"]?.Value() ?? ""); command.ExecuteNonQuery(); } } diff --git a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Comparison.cs b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Comparison.cs index 76c61d1..905307f 100644 --- a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Comparison.cs +++ b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Comparison.cs @@ -1,16 +1,12 @@ using System; -using System.Collections.Generic; using System.Data.SqlClient; -using System.Linq; -using System.Text; -using System.Text.Json.Nodes; -using System.Threading.Tasks; +using Newtonsoft.Json.Linq; namespace HorseRacingPredictor.Football.Database { internal class Comparison : HorseRacingPredictor.Football.Manager.Database { - public void Upsert(SqlConnection connection, int predictionId, JsonNode comparison) + public void Upsert(SqlConnection connection, int predictionId, JToken comparison) { try { @@ -56,20 +52,20 @@ namespace HorseRacingPredictor.Football.Database command.Parameters.AddWithValue("@prediction_id", predictionId); // Aggiungi tutti i parametri del confronto - command.Parameters.AddWithValue("@form_home", comparison["form"]?["home"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@form_away", comparison["form"]?["away"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@att_home", comparison["att"]?["home"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@att_away", comparison["att"]?["away"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@def_home", comparison["def"]?["home"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@def_away", comparison["def"]?["away"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@poisson_home", comparison["poisson_distribution"]?["home"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@poisson_away", comparison["poisson_distribution"]?["away"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@h2h_home", comparison["h2h"]?["home"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@h2h_away", comparison["h2h"]?["away"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@goals_home", comparison["goals"]?["home"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@goals_away", comparison["goals"]?["away"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@total_home", comparison["total"]?["home"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@total_away", comparison["total"]?["away"]?.GetValue() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@form_home", comparison["form"]?["home"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@form_away", comparison["form"]?["away"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@att_home", comparison["att"]?["home"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@att_away", comparison["att"]?["away"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@def_home", comparison["def"]?["home"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@def_away", comparison["def"]?["away"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@poisson_home", comparison["poisson_distribution"]?["home"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@poisson_away", comparison["poisson_distribution"]?["away"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@h2h_home", comparison["h2h"]?["home"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@h2h_away", comparison["h2h"]?["away"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@goals_home", comparison["goals"]?["home"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@goals_away", comparison["goals"]?["away"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@total_home", comparison["total"]?["home"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@total_away", comparison["total"]?["away"]?.Value() ?? (object)DBNull.Value); command.ExecuteNonQuery(); } diff --git a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Fixture.cs b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Fixture.cs index 41fba7e..9d18089 100644 --- a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Fixture.cs +++ b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Fixture.cs @@ -1,17 +1,17 @@ using System; using System.Data; using System.Data.SqlClient; -using System.Text.Json.Nodes; +using Newtonsoft.Json.Linq; namespace HorseRacingPredictor.Football.Database { internal class Fixture : HorseRacingPredictor.Football.Manager.Database { - public void Upsert(SqlConnection connection, SqlTransaction transaction, JsonNode fixture) + public void Upsert(SqlConnection connection, SqlTransaction transaction, JToken fixture) { try { - var id = fixture["id"]?.GetValue(); + var id = fixture["id"]?.Value(); if (id == null) return; // Salta il record se l'id è null var query = @" @@ -63,20 +63,20 @@ namespace HorseRacingPredictor.Football.Database // Parametri principali command.Parameters.AddWithValue("@fixture_id", id); - command.Parameters.AddWithValue("@timezone", fixture["timezone"]?.GetValue() ?? ""); - command.Parameters.AddWithValue("@date", fixture["date"]?.GetValue() ?? DateTime.MinValue); - command.Parameters.AddWithValue("@timestamp", fixture["timestamp"]?.GetValue() ?? 0L); - command.Parameters.AddWithValue("@referee", fixture["referee"]?.GetValue() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@timezone", fixture["timezone"]?.Value() ?? ""); + command.Parameters.AddWithValue("@date", fixture["date"]?.Value() ?? DateTime.MinValue); + command.Parameters.AddWithValue("@timestamp", fixture["timestamp"]?.Value() ?? 0L); + command.Parameters.AddWithValue("@referee", fixture["referee"]?.Value() ?? (object)DBNull.Value); // Parametri venue - int? venueId = venue?["id"]?.GetValue(); + int? venueId = venue?["id"]?.Value(); command.Parameters.AddWithValue("@venue_id", venueId.HasValue ? (object)venueId.Value : DBNull.Value); // Parametri status - command.Parameters.AddWithValue("@status_long", status?["long"]?.GetValue() ?? ""); - command.Parameters.AddWithValue("@status_short", status?["short"]?.GetValue() ?? ""); + command.Parameters.AddWithValue("@status_long", status?["long"]?.Value() ?? ""); + command.Parameters.AddWithValue("@status_short", status?["short"]?.Value() ?? ""); - int? elapsed = status?["elapsed"]?.GetValue(); + int? elapsed = status?["elapsed"]?.Value(); int? extra = null; // Assumo che l'API restituisca questo valore, altrimenti va gestito come gli altri command.Parameters.AddWithValue("@status_elapsed", elapsed.HasValue ? (object)elapsed.Value : DBNull.Value); @@ -101,11 +101,11 @@ namespace HorseRacingPredictor.Football.Database /// /// Metodo di supporto per inserire/aggiornare le informazioni sulla venue /// - private void UpsertVenue(SqlConnection connection, SqlTransaction transaction, JsonNode venue) + private void UpsertVenue(SqlConnection connection, SqlTransaction transaction, JToken venue) { try { - var id = venue["id"]?.GetValue(); + var id = venue["id"]?.Value(); if (id == null) return; var query = @" @@ -121,8 +121,8 @@ namespace HorseRacingPredictor.Football.Database using (var command = new SqlCommand(query, connection, transaction)) { command.Parameters.AddWithValue("@venue_id", id); - command.Parameters.AddWithValue("@name", venue["name"]?.GetValue() ?? ""); - command.Parameters.AddWithValue("@city", venue["city"]?.GetValue() ?? ""); + command.Parameters.AddWithValue("@name", venue["name"]?.Value() ?? ""); + command.Parameters.AddWithValue("@city", venue["city"]?.Value() ?? ""); command.ExecuteNonQuery(); } } diff --git a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/FixtureLeague.cs b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/FixtureLeague.cs index ae95b57..8faf7b2 100644 --- a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/FixtureLeague.cs +++ b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/FixtureLeague.cs @@ -3,20 +3,20 @@ using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using System.Text; -using System.Text.Json.Nodes; +using Newtonsoft.Json.Linq; using System.Threading.Tasks; namespace HorseRacingPredictor.Football.Database { internal class FixtureLeague : HorseRacingPredictor.Football.Manager.Database { - public void Upsert(SqlConnection connection, SqlTransaction transaction, int fixtureId, int leagueId, JsonNode leagueData) + public void Upsert(SqlConnection connection, SqlTransaction transaction, int fixtureId, int leagueId, JToken leagueData) { try { // Estrai i valori prima della query per utilizzarli nel log - string round = leagueData["round"]?.GetValue() ?? ""; - bool? standings = leagueData["standings"]?.GetValue(); + string round = leagueData["round"]?.Value() ?? ""; + bool? standings = leagueData["standings"]?.Value(); string standingsValue = standings.HasValue ? standings.Value.ToString() : "NULL"; // Log dell'operazione prima di tentare l'upsert diff --git a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Goals.cs b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Goals.cs index b2de854..1dd96b9 100644 --- a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Goals.cs +++ b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Goals.cs @@ -1,12 +1,12 @@ using System; using System.Data.SqlClient; -using System.Text.Json.Nodes; +using Newtonsoft.Json.Linq; namespace HorseRacingPredictor.Football.Database { internal class Goals : HorseRacingPredictor.Football.Manager.Database { - public void Upsert(SqlConnection connection, JsonNode goals, int fixtureId) + public void Upsert(SqlConnection connection, JToken goals, int fixtureId) { try { @@ -27,8 +27,8 @@ namespace HorseRacingPredictor.Football.Database END"; using (var command = new SqlCommand(query, connection)) { - command.Parameters.AddWithValue("@home", goals["home"]?.GetValue() ?? 0); - command.Parameters.AddWithValue("@away", goals["away"]?.GetValue() ?? 0); + command.Parameters.AddWithValue("@home", goals["home"]?.Value() ?? 0); + command.Parameters.AddWithValue("@away", goals["away"]?.Value() ?? 0); command.Parameters.AddWithValue("@fixture_id", fixtureId); command.ExecuteNonQuery(); } diff --git a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/League.cs b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/League.cs index 7bbe13b..d452002 100644 --- a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/League.cs +++ b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/League.cs @@ -1,16 +1,16 @@ using System; using System.Data.SqlClient; -using System.Text.Json.Nodes; +using Newtonsoft.Json.Linq; namespace HorseRacingPredictor.Football.Database { internal class League : HorseRacingPredictor.Football.Manager.Database { - public void Upsert(SqlConnection connection, JsonNode league) + public void Upsert(SqlConnection connection, JToken league) { try { - var id = league["id"]?.GetValue(); + var id = league["id"]?.Value(); if (id == null) return; // Salta il record se l'id è null var query = @" @@ -25,11 +25,11 @@ namespace HorseRacingPredictor.Football.Database using (var command = new SqlCommand(query, connection)) { command.Parameters.AddWithValue("@league_id", id); - command.Parameters.AddWithValue("@name", league["name"]?.GetValue() ?? ""); - command.Parameters.AddWithValue("@country", league["country"]?.GetValue() ?? ""); - command.Parameters.AddWithValue("@logo", league["logo"]?.GetValue() ?? ""); - command.Parameters.AddWithValue("@flag", league["flag"]?.GetValue() ?? ""); - command.Parameters.AddWithValue("@season", league["season"]?.GetValue() ?? 0); + command.Parameters.AddWithValue("@name", league["name"]?.Value() ?? ""); + command.Parameters.AddWithValue("@country", league["country"]?.Value() ?? ""); + command.Parameters.AddWithValue("@logo", league["logo"]?.Value() ?? ""); + command.Parameters.AddWithValue("@flag", league["flag"]?.Value() ?? ""); + command.Parameters.AddWithValue("@season", league["season"]?.Value() ?? 0); command.ExecuteNonQuery(); } } @@ -39,11 +39,11 @@ namespace HorseRacingPredictor.Football.Database } } - public void Upsert(SqlConnection connection, SqlTransaction transaction, JsonNode league) + public void Upsert(SqlConnection connection, SqlTransaction transaction, JToken league) { try { - var id = league["id"]?.GetValue(); + var id = league["id"]?.Value(); if (id == null) return; // Salta il record se l'id è null var query = @" @@ -58,11 +58,11 @@ namespace HorseRacingPredictor.Football.Database using (var command = new SqlCommand(query, connection, transaction)) { command.Parameters.AddWithValue("@league_id", id); - command.Parameters.AddWithValue("@name", league["name"]?.GetValue() ?? ""); - command.Parameters.AddWithValue("@country", league["country"]?.GetValue() ?? ""); - command.Parameters.AddWithValue("@logo", league["logo"]?.GetValue() ?? ""); - command.Parameters.AddWithValue("@flag", league["flag"]?.GetValue() ?? ""); - command.Parameters.AddWithValue("@season", league["season"]?.GetValue() ?? 0); + command.Parameters.AddWithValue("@name", league["name"]?.Value() ?? ""); + command.Parameters.AddWithValue("@country", league["country"]?.Value() ?? ""); + command.Parameters.AddWithValue("@logo", league["logo"]?.Value() ?? ""); + command.Parameters.AddWithValue("@flag", league["flag"]?.Value() ?? ""); + command.Parameters.AddWithValue("@season", league["season"]?.Value() ?? 0); command.ExecuteNonQuery(); } } diff --git a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/LeagueStats.cs b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/LeagueStats.cs index 44598f7..b561545 100644 --- a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/LeagueStats.cs +++ b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/LeagueStats.cs @@ -1,12 +1,12 @@ using System; using System.Data.SqlClient; -using System.Text.Json.Nodes; +using Newtonsoft.Json.Linq; namespace HorseRacingPredictor.Football.Database { internal class LeagueStats : HorseRacingPredictor.Football.Manager.Database { - public int Insert(SqlConnection connection, int? teamId, int? predictionId, bool isHome, JsonNode stats) + public int Insert(SqlConnection connection, int? teamId, int? predictionId, bool isHome, JToken stats) { try { @@ -35,27 +35,27 @@ namespace HorseRacingPredictor.Football.Database command.Parameters.AddWithValue("@team_id", teamId.HasValue ? (object)teamId.Value : DBNull.Value); command.Parameters.AddWithValue("@prediction_id", predictionId.HasValue ? (object)predictionId.Value : DBNull.Value); command.Parameters.AddWithValue("@is_home", isHome); - command.Parameters.AddWithValue("@form", stats["form"]?.GetValue() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@form", stats["form"]?.Value() ?? (object)DBNull.Value); var fixtures = stats["fixtures"]; - command.Parameters.AddWithValue("@fixtures_played_home", fixtures?["played"]?["home"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@fixtures_played_away", fixtures?["played"]?["away"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@fixtures_played_total", fixtures?["played"]?["total"]?.GetValue() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@fixtures_played_home", fixtures?["played"]?["home"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@fixtures_played_away", fixtures?["played"]?["away"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@fixtures_played_total", fixtures?["played"]?["total"]?.Value() ?? (object)DBNull.Value); var wins = stats["fixtures"]?["wins"]; - command.Parameters.AddWithValue("@wins_home", wins?["home"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@wins_away", wins?["away"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@wins_total", wins?["total"]?.GetValue() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@wins_home", wins?["home"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@wins_away", wins?["away"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@wins_total", wins?["total"]?.Value() ?? (object)DBNull.Value); var draws = stats["fixtures"]?["draws"]; - command.Parameters.AddWithValue("@draws_home", draws?["home"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@draws_away", draws?["away"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@draws_total", draws?["total"]?.GetValue() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@draws_home", draws?["home"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@draws_away", draws?["away"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@draws_total", draws?["total"]?.Value() ?? (object)DBNull.Value); var loses = stats["fixtures"]?["loses"]; - command.Parameters.AddWithValue("@loses_home", loses?["home"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@loses_away", loses?["away"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@loses_total", loses?["total"]?.GetValue() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@loses_home", loses?["home"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@loses_away", loses?["away"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@loses_total", loses?["total"]?.Value() ?? (object)DBNull.Value); command.ExecuteNonQuery(); } diff --git a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Odds.cs b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Odds.cs index e396613..c9282ed 100644 --- a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Odds.cs +++ b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Odds.cs @@ -1,26 +1,27 @@ using System; using System.Data.SqlClient; -using System.Text.Json.Nodes; +using System.Linq; +using Newtonsoft.Json.Linq; namespace HorseRacingPredictor.Football.Database { internal class Odds : HorseRacingPredictor.Football.Manager.Database { - public void Upsert(SqlConnection connection, JsonNode bookmakers, int fixtureId) + public void Upsert(SqlConnection connection, JToken bookmakers, int fixtureId) { try { // Aggiungiamo log per tracciare la struttura dei dati - LogError($"Inizio elaborazione quote per fixture {fixtureId} con {bookmakers?.AsArray().Count ?? 0} bookmakers", null); + LogError($"Inizio elaborazione quote per fixture {fixtureId} con {bookmakers?.Children().Count() ?? 0} bookmakers", null); // Per ogni bookmaker - foreach (var bookmaker in bookmakers.AsArray()) + foreach (var bookmaker in bookmakers.Children()) { - int bookmakerId = bookmaker["id"].GetValue(); + int bookmakerId = bookmaker["id"].Value(); var bets = bookmaker["bets"]; // Cerchiamo le quote di tipo Match Winner (1X2) - foreach (var bet in bets.AsArray()) + foreach (var bet in bets.Children()) { // Gestiamo in modo più sicuro il recupero di valori dal JSON string betName = GetStringValueSafe(bet, "name"); @@ -35,7 +36,7 @@ namespace HorseRacingPredictor.Football.Database if (betTypeId == 0) continue; // Estrai e salva le quote - foreach (var value in bet["values"].AsArray()) + foreach (var value in bet["values"].Children()) { // Gestiamo in modo più sicuro il recupero di valori dal JSON string valueType = GetStringValueSafe(value, "value"); @@ -128,9 +129,9 @@ namespace HorseRacingPredictor.Football.Database } /// - /// Ottiene un valore stringa da un JsonNode in modo sicuro + /// Ottiene un valore stringa da un JToken in modo sicuro /// - private string GetStringValueSafe(JsonNode node, string propertyName) + private string GetStringValueSafe(JToken node, string propertyName) { try { @@ -140,10 +141,10 @@ namespace HorseRacingPredictor.Football.Database var value = node[propertyName]; // Gestiamo diversi tipi di nodi - if (value.GetValueKind() == System.Text.Json.JsonValueKind.String) - return value.GetValue(); - else if (value.GetValueKind() == System.Text.Json.JsonValueKind.Number) - return value.GetValue().ToString(); + if (value.Type == JTokenType.String) + return value.Value(); + else if (value.Type == JTokenType.Float || value.Type == JTokenType.Integer) + return value.Value().ToString(); else return value.ToString(); } @@ -155,9 +156,9 @@ namespace HorseRacingPredictor.Football.Database } /// - /// Ottiene un valore decimale da un JsonNode in modo sicuro + /// Ottiene un valore decimale da un JToken in modo sicuro /// - private decimal GetDecimalValueSafe(JsonNode node, string propertyName) + private decimal GetDecimalValueSafe(JToken node, string propertyName) { try { @@ -167,15 +168,15 @@ namespace HorseRacingPredictor.Football.Database var value = node[propertyName]; // Gestiamo diversi tipi di nodi - if (value.GetValueKind() == System.Text.Json.JsonValueKind.Number) + if (value.Type == JTokenType.Float || value.Type == JTokenType.Integer) { // Assicuriamoci che il valore sia esattamente quello originale - return value.GetValue(); + return value.Value(); } - else if (value.GetValueKind() == System.Text.Json.JsonValueKind.String) + else if (value.Type == JTokenType.String) { // Utilizziamo InvariantCulture per garantire una corretta interpretazione dei decimali - if (decimal.TryParse(value.GetValue(), + if (decimal.TryParse(value.Value(), System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out decimal result)) @@ -185,7 +186,7 @@ namespace HorseRacingPredictor.Football.Database } // Aggiungiamo un log più dettagliato per aiutare il debug - LogError($"Impossibile convertire '{value}' (tipo: {value.GetValueKind()}) in decimal per proprietà '{propertyName}'", null); + LogError($"Impossibile convertire '{value}' (tipo: {value.Type}) in decimal per proprietà '{propertyName}'", null); return 0; } catch (Exception ex) diff --git a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Prediction.cs b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Prediction.cs index cc1f9ec..2251004 100644 --- a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Prediction.cs +++ b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Prediction.cs @@ -1,30 +1,30 @@ using System; using System.Data.SqlClient; -using System.Text.Json.Nodes; +using Newtonsoft.Json.Linq; namespace HorseRacingPredictor.Football.Database { internal class Prediction : HorseRacingPredictor.Football.Manager.Database { - public void Upsert(SqlConnection connection, JsonNode predictions, int fixtureId) + public void Upsert(SqlConnection connection, JToken predictions, int fixtureId) { try { // Estrazione dei dati dalla risposta JSON - string advice = predictions["advice"]?.GetValue(); + string advice = predictions["advice"]?.Value(); if (string.IsNullOrEmpty(advice)) return; // Nessuna previsione se non c'è consiglio // Estrazione degli altri valori, con gestione null - int? winnerId = predictions["winner"]?["id"]?.GetValue(); - string winnerName = predictions["winner"]?["name"]?.GetValue(); - string winnerComment = predictions["winner"]?["comment"]?.GetValue(); - bool? winOrDraw = predictions["win_or_draw"]?.GetValue(); - string underOver = predictions["under_over"]?.GetValue(); - string goalsHome = predictions["goals"]?["home"]?.GetValue(); - string goalsAway = predictions["goals"]?["away"]?.GetValue(); - string percentHome = predictions["percent"]?["home"]?.GetValue(); - string percentDraw = predictions["percent"]?["draw"]?.GetValue(); - string percentAway = predictions["percent"]?["away"]?.GetValue(); + int? winnerId = predictions["winner"]?["id"]?.Value(); + string winnerName = predictions["winner"]?["name"]?.Value(); + string winnerComment = predictions["winner"]?["comment"]?.Value(); + bool? winOrDraw = predictions["win_or_draw"]?.Value(); + string underOver = predictions["under_over"]?.Value(); + string goalsHome = predictions["goals"]?["home"]?.Value(); + string goalsAway = predictions["goals"]?["away"]?.Value(); + string percentHome = predictions["percent"]?["home"]?.Value(); + string percentDraw = predictions["percent"]?["draw"]?.Value(); + string percentAway = predictions["percent"]?["away"]?.Value(); // Query per l'upsert con tutti i campi disponibili var query = @" diff --git a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Score.cs b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Score.cs index 5dd730f..02308e1 100644 --- a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Score.cs +++ b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Score.cs @@ -1,12 +1,12 @@ using System; using System.Data.SqlClient; -using System.Text.Json.Nodes; +using Newtonsoft.Json.Linq; namespace HorseRacingPredictor.Football.Database { internal class Score : HorseRacingPredictor.Football.Manager.Database { - public void Upsert(SqlConnection connection, JsonNode score, int fixtureId) + public void Upsert(SqlConnection connection, JToken score, int fixtureId) { try { @@ -26,14 +26,14 @@ namespace HorseRacingPredictor.Football.Database END"; using (var command = new SqlCommand(query, connection)) { - command.Parameters.AddWithValue("@home_halftime", score["halftime"]["home"]?.GetValue() ?? 0); - command.Parameters.AddWithValue("@away_halftime", score["halftime"]["away"]?.GetValue() ?? 0); - command.Parameters.AddWithValue("@home_fulltime", score["fulltime"]["home"]?.GetValue() ?? 0); - command.Parameters.AddWithValue("@away_fulltime", score["fulltime"]["away"]?.GetValue() ?? 0); - command.Parameters.AddWithValue("@home_extratime", score["extratime"]["home"]?.GetValue() ?? 0); - command.Parameters.AddWithValue("@away_extratime", score["extratime"]["away"]?.GetValue() ?? 0); - command.Parameters.AddWithValue("@home_penalty", score["penalty"]["home"]?.GetValue() ?? 0); - command.Parameters.AddWithValue("@away_penalty", score["penalty"]["away"]?.GetValue() ?? 0); + command.Parameters.AddWithValue("@home_halftime", score["halftime"]?["home"]?.Value() ?? 0); + command.Parameters.AddWithValue("@away_halftime", score["halftime"]?["away"]?.Value() ?? 0); + command.Parameters.AddWithValue("@home_fulltime", score["fulltime"]?["home"]?.Value() ?? 0); + command.Parameters.AddWithValue("@away_fulltime", score["fulltime"]?["away"]?.Value() ?? 0); + command.Parameters.AddWithValue("@home_extratime", score["extratime"]?["home"]?.Value() ?? 0); + command.Parameters.AddWithValue("@away_extratime", score["extratime"]?["away"]?.Value() ?? 0); + command.Parameters.AddWithValue("@home_penalty", score["penalty"]?["home"]?.Value() ?? 0); + command.Parameters.AddWithValue("@away_penalty", score["penalty"]?["away"]?.Value() ?? 0); command.Parameters.AddWithValue("@fixture_id", fixtureId); command.ExecuteNonQuery(); } diff --git a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Team.cs b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Team.cs index 8efa9b0..3f51d6c 100644 --- a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Team.cs +++ b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/Team.cs @@ -1,17 +1,17 @@ using System; using System.Data.SqlClient; -using System.Text.Json.Nodes; +using Newtonsoft.Json.Linq; namespace HorseRacingPredictor.Football.Database { internal class Team : HorseRacingPredictor.Football.Manager.Database { - public void UpsertTeams(SqlConnection connection, SqlTransaction transaction, JsonNode teams, int fixtureId) + public void UpsertTeams(SqlConnection connection, SqlTransaction transaction, JToken teams, int fixtureId) { try { - var homeTeamId = teams["home"]["id"]?.GetValue(); - var awayTeamId = teams["away"]["id"]?.GetValue(); + var homeTeamId = teams["home"]["id"]?.Value(); + var awayTeamId = teams["away"]["id"]?.Value(); if (homeTeamId == null || awayTeamId == null) return; // Salta il record se uno degli id è null var queryTeam = @" @@ -31,14 +31,14 @@ namespace HorseRacingPredictor.Football.Database // Upsert home team command.Parameters.AddWithValue("@team_id", homeTeamId); - command.Parameters.AddWithValue("@name", homeTeam["name"]?.GetValue() ?? ""); - command.Parameters.AddWithValue("@logo", homeTeam["logo"]?.GetValue() ?? ""); + command.Parameters.AddWithValue("@name", homeTeam["name"]?.Value() ?? ""); + command.Parameters.AddWithValue("@logo", homeTeam["logo"]?.Value() ?? ""); command.ExecuteNonQuery(); // Upsert away team command.Parameters["@team_id"].Value = awayTeamId; - command.Parameters["@name"].Value = awayTeam["name"]?.GetValue() ?? ""; - command.Parameters["@logo"].Value = awayTeam["logo"]?.GetValue() ?? ""; + command.Parameters["@name"].Value = awayTeam["name"]?.Value() ?? ""; + command.Parameters["@logo"].Value = awayTeam["logo"]?.Value() ?? ""; command.ExecuteNonQuery(); } diff --git a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/TeamStats.cs b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/TeamStats.cs index b5a26e8..f082c93 100644 --- a/HorseRacingPredictor/HorseRacingPredictor/Football/Database/TeamStats.cs +++ b/HorseRacingPredictor/HorseRacingPredictor/Football/Database/TeamStats.cs @@ -1,16 +1,12 @@ using System; -using System.Collections.Generic; using System.Data.SqlClient; -using System.Linq; -using System.Text; -using System.Text.Json.Nodes; -using System.Threading.Tasks; +using Newtonsoft.Json.Linq; namespace HorseRacingPredictor.Football.Database { internal class TeamStats : HorseRacingPredictor.Football.Manager.Database { - public int Insert(SqlConnection connection, int? teamId, int? predictionId, bool isHome, JsonNode stats) + public int Insert(SqlConnection connection, int? teamId, int? predictionId, bool isHome, JToken stats) { try { @@ -35,18 +31,18 @@ namespace HorseRacingPredictor.Football.Database command.Parameters.AddWithValue("@team_id", teamId.HasValue ? (object)teamId.Value : DBNull.Value); command.Parameters.AddWithValue("@prediction_id", predictionId.HasValue ? (object)predictionId.Value : DBNull.Value); command.Parameters.AddWithValue("@is_home", isHome); - command.Parameters.AddWithValue("@played", stats["played"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@form", stats["form"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@att", stats["att"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@def", stats["def"]?.GetValue() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@played", stats["played"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@form", stats["form"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@att", stats["att"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@def", stats["def"]?.Value() ?? (object)DBNull.Value); var goalsFor = stats["goals"]?["for"]; - command.Parameters.AddWithValue("@goals_for_total", goalsFor?["total"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@goals_for_average", goalsFor?["average"]?.GetValue() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@goals_for_total", goalsFor?["total"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@goals_for_average", goalsFor?["average"]?.Value() ?? (object)DBNull.Value); var goalsAgainst = stats["goals"]?["against"]; - command.Parameters.AddWithValue("@goals_against_total", goalsAgainst?["total"]?.GetValue() ?? (object)DBNull.Value); - command.Parameters.AddWithValue("@goals_against_average", goalsAgainst?["average"]?.GetValue() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@goals_against_total", goalsAgainst?["total"]?.Value() ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@goals_against_average", goalsAgainst?["average"]?.Value() ?? (object)DBNull.Value); command.ExecuteNonQuery(); } diff --git a/HorseRacingPredictor/HorseRacingPredictor/Football/Manager/API.cs b/HorseRacingPredictor/HorseRacingPredictor/Football/Manager/API.cs index e52d117..2488532 100644 --- a/HorseRacingPredictor/HorseRacingPredictor/Football/Manager/API.cs +++ b/HorseRacingPredictor/HorseRacingPredictor/Football/Manager/API.cs @@ -2,7 +2,6 @@ using System; using System.Threading.Tasks; using RestSharp; using HorseRacingPredictor.Football.Database; -using HorseRacingPredictor.Football.API; using League = HorseRacingPredictor.Football.API.League; using Fixture = HorseRacingPredictor.Football.API.Fixture; diff --git a/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernButton.cs b/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernButton.cs new file mode 100644 index 0000000..8a03a2d --- /dev/null +++ b/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernButton.cs @@ -0,0 +1,107 @@ +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace BettingPredictor.UI.Controls +{ + /// + /// Pulsante moderno con tema scuro e effetti hover + /// + public class ModernButton : Button + { + private bool isHovering = false; + private Color normalColor = ModernTheme.Colors.AccentPrimary; + private Color hoverColor = ModernTheme.Colors.AccentSecondary; + private int borderRadius = ModernTheme.BorderRadius.Medium; + + public ModernButton() + { + // Configurazione base + FlatStyle = FlatStyle.Flat; + FlatAppearance.BorderSize = 0; + BackColor = normalColor; + ForeColor = ModernTheme.Colors.TextPrimary; + Font = ModernTheme.Fonts.ButtonFont; + Cursor = Cursors.Hand; + Size = new Size(100, 35); + + // Abilita il double buffering per evitare flickering + SetStyle(ControlStyles.UserPaint | + ControlStyles.AllPaintingInWmPaint | + ControlStyles.OptimizedDoubleBuffer, true); + } + + public Color NormalColor + { + get => normalColor; + set + { + normalColor = value; + if (!isHovering) BackColor = value; + } + } + + public Color HoverColor + { + get => hoverColor; + set => hoverColor = value; + } + + public int BorderRadius + { + get => borderRadius; + set + { + borderRadius = value; + Invalidate(); + } + } + + protected override void OnMouseEnter(EventArgs e) + { + base.OnMouseEnter(e); + isHovering = true; + BackColor = hoverColor; + } + + protected override void OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + isHovering = false; + BackColor = normalColor; + } + + protected override void OnPaint(PaintEventArgs e) + { + e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; + + // Disegna il background con bordi arrotondati + using (GraphicsPath path = GetRoundedRectangle(ClientRectangle, borderRadius)) + { + using (SolidBrush brush = new SolidBrush(BackColor)) + { + e.Graphics.FillPath(brush, path); + } + } + + // Disegna il testo centrato + TextRenderer.DrawText(e.Graphics, Text, Font, ClientRectangle, + ForeColor, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter); + } + + private GraphicsPath GetRoundedRectangle(Rectangle rect, int radius) + { + GraphicsPath path = new GraphicsPath(); + int diameter = radius * 2; + + path.AddArc(rect.X, rect.Y, diameter, diameter, 180, 90); + path.AddArc(rect.Right - diameter, rect.Y, diameter, diameter, 270, 90); + path.AddArc(rect.Right - diameter, rect.Bottom - diameter, diameter, diameter, 0, 90); + path.AddArc(rect.X, rect.Bottom - diameter, diameter, diameter, 90, 90); + path.CloseFigure(); + + return path; + } + } +} diff --git a/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernDataGridView.cs b/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernDataGridView.cs new file mode 100644 index 0000000..9ff5dd4 --- /dev/null +++ b/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernDataGridView.cs @@ -0,0 +1,104 @@ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace BettingPredictor.UI.Controls +{ + /// + /// DataGridView moderna con tema scuro + /// + public class ModernDataGridView : DataGridView + { + public ModernDataGridView() + { + // Configurazione base + BackgroundColor = ModernTheme.Colors.PrimaryBackground; + GridColor = ModernTheme.Colors.BorderPrimary; + BorderStyle = BorderStyle.None; + + // Colori delle celle + DefaultCellStyle.BackColor = ModernTheme.Colors.GridRowEven; + DefaultCellStyle.ForeColor = ModernTheme.Colors.TextPrimary; + DefaultCellStyle.SelectionBackColor = ModernTheme.Colors.GridSelected; + DefaultCellStyle.SelectionForeColor = ModernTheme.Colors.TextPrimary; + DefaultCellStyle.Font = ModernTheme.Fonts.RegularFont; + + // Alternating row color + AlternatingRowsDefaultCellStyle.BackColor = ModernTheme.Colors.GridRowOdd; + AlternatingRowsDefaultCellStyle.ForeColor = ModernTheme.Colors.TextPrimary; + + // Header + ColumnHeadersDefaultCellStyle.BackColor = ModernTheme.Colors.GridHeader; + ColumnHeadersDefaultCellStyle.ForeColor = ModernTheme.Colors.TextPrimary; + ColumnHeadersDefaultCellStyle.Font = ModernTheme.Fonts.SubtitleFont; + ColumnHeadersDefaultCellStyle.SelectionBackColor = ModernTheme.Colors.GridHeader; + ColumnHeadersDefaultCellStyle.SelectionForeColor = ModernTheme.Colors.TextPrimary; + ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single; + ColumnHeadersHeight = 35; + + // Row + RowHeadersDefaultCellStyle.BackColor = ModernTheme.Colors.GridHeader; + RowHeadersDefaultCellStyle.ForeColor = ModernTheme.Colors.TextPrimary; + RowHeadersDefaultCellStyle.SelectionBackColor = ModernTheme.Colors.GridHeader; + RowHeadersDefaultCellStyle.SelectionForeColor = ModernTheme.Colors.TextPrimary; + RowHeadersVisible = false; + + // Altre impostazioni + EnableHeadersVisualStyles = false; + AllowUserToAddRows = false; + AllowUserToDeleteRows = false; + ReadOnly = true; + SelectionMode = DataGridViewSelectionMode.FullRowSelect; + MultiSelect = false; + AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; + RowTemplate.Height = 30; + + // Abilita il double buffering per evitare flickering + DoubleBuffered = true; + + // Eventi per l'hover effect + CellMouseEnter += OnCellMouseEnterHandler; + CellMouseLeave += OnCellMouseLeaveHandler; + } + + private void OnCellMouseEnterHandler(object sender, DataGridViewCellEventArgs e) + { + if (e.RowIndex >= 0) + { + Rows[e.RowIndex].DefaultCellStyle.BackColor = ModernTheme.Colors.GridHover; + } + } + + private void OnCellMouseLeaveHandler(object sender, DataGridViewCellEventArgs e) + { + if (e.RowIndex >= 0) + { + // Ripristina il colore originale in base all'indice della riga + if (e.RowIndex % 2 == 0) + Rows[e.RowIndex].DefaultCellStyle.BackColor = ModernTheme.Colors.GridRowEven; + else + Rows[e.RowIndex].DefaultCellStyle.BackColor = ModernTheme.Colors.GridRowOdd; + } + } + + public void HighlightWinnerRows() + { + if (Columns.Contains("Risultato Reale")) + { + foreach (DataGridViewRow row in Rows) + { + if (row.Cells["Risultato Reale"].Value != null && + row.Cells["Risultato Reale"].Value.ToString() == "1") + { + row.DefaultCellStyle.BackColor = ModernTheme.Colors.StatusWin; + } + else if (row.Cells["Risultato Reale"].Value != null && + int.TryParse(row.Cells["Risultato Reale"].Value.ToString(), out int pos) && pos <= 3) + { + row.DefaultCellStyle.BackColor = ModernTheme.Colors.StatusPlace; + } + } + } + } + } +} diff --git a/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernDateTimePicker.cs b/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernDateTimePicker.cs new file mode 100644 index 0000000..f584784 --- /dev/null +++ b/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernDateTimePicker.cs @@ -0,0 +1,48 @@ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace BettingPredictor.UI.Controls +{ + /// + /// DateTimePicker moderna con tema scuro + /// Nota: Il controllo DateTimePicker di WinForms non supporta completamente il custom painting, + /// quindi alcuni elementi potrebbero mantenere lo stile di sistema + /// + public class ModernDateTimePicker : DateTimePicker + { + public ModernDateTimePicker() + { + // Configurazione base + Font = ModernTheme.Fonts.RegularFont; + Format = DateTimePickerFormat.Custom; + CustomFormat = "dd/MM/yyyy"; + + // Imposta i colori per il calendario + CalendarMonthBackground = ModernTheme.Colors.TertiaryBackground; + CalendarForeColor = ModernTheme.Colors.TextPrimary; + CalendarTitleBackColor = ModernTheme.Colors.SecondaryBackground; + CalendarTitleForeColor = ModernTheme.Colors.TextPrimary; + CalendarTrailingForeColor = ModernTheme.Colors.TextDisabled; + + // Dimensioni + Height = 30; + } + + /// + /// Imposta il formato lungo (con ora) + /// + public void SetLongFormat() + { + CustomFormat = "dd/MM/yyyy HH:mm"; + } + + /// + /// Imposta il formato corto (solo data) + /// + public void SetShortFormat() + { + CustomFormat = "dd/MM/yyyy"; + } + } +} diff --git a/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernLabel.cs b/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernLabel.cs new file mode 100644 index 0000000..7b79b0c --- /dev/null +++ b/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernLabel.cs @@ -0,0 +1,78 @@ +using System.Drawing; +using System.Windows.Forms; + +namespace BettingPredictor.UI.Controls +{ + /// + /// Label moderna con tema scuro e testo ben visibile + /// + public class ModernLabel : Label + { + public ModernLabel() + { + // Configurazione base per visibilità su sfondo scuro + ForeColor = ModernTheme.Colors.TextSecondary; + Font = ModernTheme.Fonts.RegularFont; + BackColor = Color.Transparent; + AutoSize = true; + + // Abilita anti-aliasing per testo più leggibile + SetStyle(ControlStyles.OptimizedDoubleBuffer | + ControlStyles.AllPaintingInWmPaint, true); + } + + /// + /// Imposta lo stile del label come titolo + /// + public void SetAsTitleLabel() + { + Font = ModernTheme.Fonts.TitleFont; + ForeColor = ModernTheme.Colors.TextPrimary; + } + + /// + /// Imposta lo stile del label come sottotitolo + /// + public void SetAsSubtitleLabel() + { + Font = ModernTheme.Fonts.SubtitleFont; + ForeColor = ModernTheme.Colors.TextPrimary; + } + + /// + /// Imposta lo stile del label come testo di stato + /// + public void SetAsStatusLabel() + { + Font = ModernTheme.Fonts.RegularFont; + ForeColor = ModernTheme.Colors.TextSecondary; + } + + /// + /// Imposta lo stile del label come testo di successo + /// + public void SetAsSuccessLabel() + { + Font = ModernTheme.Fonts.RegularFont; + ForeColor = ModernTheme.Colors.AccentSuccess; + } + + /// + /// Imposta lo stile del label come testo di errore + /// + public void SetAsErrorLabel() + { + Font = ModernTheme.Fonts.RegularFont; + ForeColor = ModernTheme.Colors.AccentError; + } + + /// + /// Imposta lo stile del label come testo di warning + /// + public void SetAsWarningLabel() + { + Font = ModernTheme.Fonts.RegularFont; + ForeColor = ModernTheme.Colors.AccentWarning; + } + } +} diff --git a/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernPanel.cs b/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernPanel.cs new file mode 100644 index 0000000..328de84 --- /dev/null +++ b/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernPanel.cs @@ -0,0 +1,99 @@ +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace BettingPredictor.UI.Controls +{ + /// + /// Panel moderno con tema scuro e bordi arrotondati + /// + public class ModernPanel : Panel + { + private int borderRadius = ModernTheme.BorderRadius.Medium; + private Color borderColor = ModernTheme.Colors.BorderPrimary; + private int borderWidth = 1; + + public ModernPanel() + { + BackColor = ModernTheme.Colors.SecondaryBackground; + + // Abilita il double buffering + SetStyle(ControlStyles.UserPaint | + ControlStyles.AllPaintingInWmPaint | + ControlStyles.OptimizedDoubleBuffer | + ControlStyles.ResizeRedraw, true); + } + + public int BorderRadius + { + get => borderRadius; + set + { + borderRadius = value; + Invalidate(); + } + } + + public Color BorderColor + { + get => borderColor; + set + { + borderColor = value; + Invalidate(); + } + } + + public int BorderWidth + { + get => borderWidth; + set + { + borderWidth = value; + Invalidate(); + } + } + + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; + + // Disegna il background con bordi arrotondati + using (GraphicsPath path = GetRoundedRectangle(ClientRectangle, borderRadius)) + { + // Background + using (SolidBrush brush = new SolidBrush(BackColor)) + { + e.Graphics.FillPath(brush, path); + } + + // Bordo + if (borderWidth > 0) + { + using (Pen pen = new Pen(borderColor, borderWidth)) + { + e.Graphics.DrawPath(pen, path); + } + } + } + } + + private GraphicsPath GetRoundedRectangle(Rectangle rect, int radius) + { + GraphicsPath path = new GraphicsPath(); + int diameter = radius * 2; + + rect.Inflate(-borderWidth / 2, -borderWidth / 2); + + path.AddArc(rect.X, rect.Y, diameter, diameter, 180, 90); + path.AddArc(rect.Right - diameter, rect.Y, diameter, diameter, 270, 90); + path.AddArc(rect.Right - diameter, rect.Bottom - diameter, diameter, diameter, 0, 90); + path.AddArc(rect.X, rect.Bottom - diameter, diameter, diameter, 90, 90); + path.CloseFigure(); + + return path; + } + } +} diff --git a/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernProgressBar.cs b/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernProgressBar.cs new file mode 100644 index 0000000..33fde74 --- /dev/null +++ b/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernProgressBar.cs @@ -0,0 +1,54 @@ +using System.Drawing; +using System.Windows.Forms; + +namespace BettingPredictor.UI.Controls +{ + /// + /// ProgressBar moderna con tema scuro e animazioni fluide + /// + public class ModernProgressBar : ProgressBar + { + public ModernProgressBar() + { + // Configurazione base + SetStyle(ControlStyles.UserPaint | + ControlStyles.AllPaintingInWmPaint | + ControlStyles.OptimizedDoubleBuffer, true); + + Height = 6; + BackColor = ModernTheme.Colors.TertiaryBackground; + ForeColor = ModernTheme.Colors.AccentPrimary; + } + + protected override void OnPaint(PaintEventArgs e) + { + Rectangle rect = ClientRectangle; + Graphics g = e.Graphics; + + // Disegna il background + using (SolidBrush brush = new SolidBrush(ModernTheme.Colors.TertiaryBackground)) + { + g.FillRectangle(brush, rect); + } + + // Calcola la larghezza del progresso + int progressWidth = (int)(rect.Width * ((double)Value / Maximum)); + + // Disegna la barra di progresso + if (progressWidth > 0) + { + Rectangle progressRect = new Rectangle(rect.X, rect.Y, progressWidth, rect.Height); + using (SolidBrush brush = new SolidBrush(ForeColor)) + { + g.FillRectangle(brush, progressRect); + } + } + } + + public void SetProgressColor(Color color) + { + ForeColor = color; + Invalidate(); + } + } +} diff --git a/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernTabControl.cs b/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernTabControl.cs new file mode 100644 index 0000000..96288b9 --- /dev/null +++ b/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernTabControl.cs @@ -0,0 +1,98 @@ +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace BettingPredictor.UI.Controls +{ + /// + /// TabControl moderna con tema scuro + /// + public class ModernTabControl : TabControl + { + public ModernTabControl() + { + SetStyle(ControlStyles.UserPaint | + ControlStyles.AllPaintingInWmPaint | + ControlStyles.OptimizedDoubleBuffer | + ControlStyles.ResizeRedraw, true); + + DrawMode = TabDrawMode.OwnerDrawFixed; + SizeMode = TabSizeMode.Fixed; + ItemSize = new Size(120, 40); + Padding = new Point(20, 0); + } + + protected override void OnPaint(PaintEventArgs e) + { + e.Graphics.Clear(ModernTheme.Colors.PrimaryBackground); + e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; + + // Disegna il background del tab panel + Rectangle tabPanelRect = new Rectangle(0, ItemSize.Height, Width, Height - ItemSize.Height); + using (SolidBrush brush = new SolidBrush(ModernTheme.Colors.SecondaryBackground)) + { + e.Graphics.FillRectangle(brush, tabPanelRect); + } + } + + protected override void OnDrawItem(DrawItemEventArgs e) + { + Graphics g = e.Graphics; + g.SmoothingMode = SmoothingMode.AntiAlias; + + // Get tab rectangle + Rectangle tabRect = GetTabRect(e.Index); + + bool isSelected = (e.Index == SelectedIndex); + + // Disegna il background della tab + Color backColor = isSelected ? ModernTheme.Colors.SecondaryBackground : ModernTheme.Colors.PrimaryBackground; + using (SolidBrush brush = new SolidBrush(backColor)) + { + g.FillRectangle(brush, tabRect); + } + + // Disegna la linea di selezione in alto + if (isSelected) + { + Rectangle accentRect = new Rectangle(tabRect.X, tabRect.Y, tabRect.Width, 3); + using (SolidBrush brush = new SolidBrush(ModernTheme.Colors.AccentPrimary)) + { + g.FillRectangle(brush, accentRect); + } + } + + // Disegna il testo della tab + string tabText = TabPages[e.Index].Text; + Color textColor = isSelected ? ModernTheme.Colors.TextPrimary : ModernTheme.Colors.TextSecondary; + Font tabFont = isSelected ? ModernTheme.Fonts.SubtitleFont : ModernTheme.Fonts.RegularFont; + + StringFormat sf = new StringFormat + { + Alignment = StringAlignment.Center, + LineAlignment = StringAlignment.Center + }; + + using (SolidBrush brush = new SolidBrush(textColor)) + { + g.DrawString(tabText, tabFont, brush, tabRect, sf); + } + + // Disegna il bordo tra le tabs + if (e.Index < TabCount - 1) + { + using (Pen pen = new Pen(ModernTheme.Colors.BorderPrimary, 1)) + { + g.DrawLine(pen, tabRect.Right, tabRect.Top + 10, tabRect.Right, tabRect.Bottom - 10); + } + } + } + + protected override void OnSelectedIndexChanged(EventArgs e) + { + base.OnSelectedIndexChanged(e); + Invalidate(); + } + } +} diff --git a/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernTextBox.cs b/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernTextBox.cs new file mode 100644 index 0000000..86f91a7 --- /dev/null +++ b/HorseRacingPredictor/HorseRacingPredictor/UI/Controls/ModernTextBox.cs @@ -0,0 +1,139 @@ +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace BettingPredictor.UI.Controls +{ + /// + /// TextBox moderno con tema scuro e bordi arrotondati + /// + public class ModernTextBox : TextBox + { + private Color borderColor = ModernTheme.Colors.BorderPrimary; + private Color focusBorderColor = ModernTheme.Colors.BorderAccent; + private bool isFocused = false; + private int borderRadius = ModernTheme.BorderRadius.Medium; + + public ModernTextBox() + { + // Configurazione base + BorderStyle = BorderStyle.None; + BackColor = ModernTheme.Colors.TertiaryBackground; + ForeColor = ModernTheme.Colors.TextPrimary; + Font = ModernTheme.Fonts.RegularFont; + Padding = new Padding(8, 8, 8, 8); + + // Abilita il double buffering + SetStyle(ControlStyles.UserPaint | + ControlStyles.AllPaintingInWmPaint | + ControlStyles.OptimizedDoubleBuffer, true); + } + + public Color BorderColor + { + get => borderColor; + set + { + borderColor = value; + Invalidate(); + } + } + + public Color FocusBorderColor + { + get => focusBorderColor; + set + { + focusBorderColor = value; + Invalidate(); + } + } + + public int BorderRadius + { + get => borderRadius; + set + { + borderRadius = value; + Invalidate(); + } + } + + protected override void OnEnter(EventArgs e) + { + base.OnEnter(e); + isFocused = true; + Invalidate(); + } + + protected override void OnLeave(EventArgs e) + { + base.OnLeave(e); + isFocused = false; + Invalidate(); + } + + protected override void OnReadOnlyChanged(EventArgs e) + { + base.OnReadOnlyChanged(e); + // Cambia il colore del testo per i campi read-only + if (ReadOnly) + { + ForeColor = ModernTheme.Colors.TextSecondary; + BackColor = ModernTheme.Colors.SecondaryBackground; + } + else + { + ForeColor = ModernTheme.Colors.TextPrimary; + BackColor = ModernTheme.Colors.TertiaryBackground; + } + Invalidate(); + } + + protected override void OnPaint(PaintEventArgs e) + { + e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; + + // Disegna il background + using (GraphicsPath path = GetRoundedRectangle(ClientRectangle, borderRadius)) + { + using (SolidBrush brush = new SolidBrush(BackColor)) + { + e.Graphics.FillPath(brush, path); + } + + // Disegna il bordo + Color currentBorderColor = isFocused ? focusBorderColor : borderColor; + using (Pen pen = new Pen(currentBorderColor, 1.5f)) + { + e.Graphics.DrawPath(pen, path); + } + } + + // Disegna il testo + if (!string.IsNullOrEmpty(Text)) + { + TextRenderer.DrawText(e.Graphics, Text, Font, + new Rectangle(8, 0, Width - 16, Height), + ForeColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter); + } + } + + private GraphicsPath GetRoundedRectangle(Rectangle rect, int radius) + { + GraphicsPath path = new GraphicsPath(); + int diameter = radius * 2; + + rect.Inflate(-1, -1); + + path.AddArc(rect.X, rect.Y, diameter, diameter, 180, 90); + path.AddArc(rect.Right - diameter, rect.Y, diameter, diameter, 270, 90); + path.AddArc(rect.Right - diameter, rect.Bottom - diameter, diameter, diameter, 0, 90); + path.AddArc(rect.X, rect.Bottom - diameter, diameter, diameter, 90, 90); + path.CloseFigure(); + + return path; + } + } +} diff --git a/HorseRacingPredictor/HorseRacingPredictor/packages.config b/HorseRacingPredictor/HorseRacingPredictor/packages.config index 026db5e..65052d6 100644 --- a/HorseRacingPredictor/HorseRacingPredictor/packages.config +++ b/HorseRacingPredictor/HorseRacingPredictor/packages.config @@ -1,23 +1,28 @@  - - + + - + - - - - - + + + + + + - - + + + - + - + + + + \ No newline at end of file