|
|
|
|
@ -8,6 +8,29 @@ |
|
|
|
|
import Foundation |
|
|
|
|
import PadelClubData |
|
|
|
|
|
|
|
|
|
struct HtmlOptions { |
|
|
|
|
let headName: Bool |
|
|
|
|
let withRank: Bool |
|
|
|
|
let withTeamIndex: Bool |
|
|
|
|
let withScore: Bool |
|
|
|
|
let withPlannedDate: Bool |
|
|
|
|
|
|
|
|
|
// Default initializer with all options defaulting to true |
|
|
|
|
init( |
|
|
|
|
headName: Bool = true, |
|
|
|
|
withRank: Bool = true, |
|
|
|
|
withTeamIndex: Bool = true, |
|
|
|
|
withScore: Bool = true, |
|
|
|
|
withPlannedDate: Bool = true |
|
|
|
|
) { |
|
|
|
|
self.headName = headName |
|
|
|
|
self.withRank = withRank |
|
|
|
|
self.withTeamIndex = withTeamIndex |
|
|
|
|
self.withScore = withScore |
|
|
|
|
self.withPlannedDate = withPlannedDate |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
enum HtmlService { |
|
|
|
|
|
|
|
|
|
case template(tournament: Tournament) |
|
|
|
|
@ -51,7 +74,7 @@ enum HtmlService { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func html(headName: Bool, withRank: Bool, withTeamIndex: Bool, withScore: Bool) -> String { |
|
|
|
|
func html(options: HtmlOptions = HtmlOptions()) -> String { |
|
|
|
|
guard let file = Bundle.main.path(forResource: self.fileName, ofType: "html") else { |
|
|
|
|
fatalError() |
|
|
|
|
} |
|
|
|
|
@ -74,8 +97,8 @@ enum HtmlService { |
|
|
|
|
var col = "" |
|
|
|
|
var row = "" |
|
|
|
|
bracket.teams().forEach { entrant in |
|
|
|
|
col = col.appending(HtmlService.groupstageColumn(entrant: entrant, position: "col").html(headName: headName, withRank: withRank, withTeamIndex: withTeamIndex, withScore: withScore)) |
|
|
|
|
row = row.appending(HtmlService.groupstageRow(entrant: entrant, teamsPerBracket: bracket.size).html(headName: headName, withRank: withRank, withTeamIndex: withTeamIndex, withScore: withScore)) |
|
|
|
|
col = col.appending(HtmlService.groupstageColumn(entrant: entrant, position: "col").html(options: options)) |
|
|
|
|
row = row.appending(HtmlService.groupstageRow(entrant: entrant, teamsPerBracket: bracket.size).html(options: options)) |
|
|
|
|
} |
|
|
|
|
template = template.replacingOccurrences(of: "{{teamsCol}}", with: col) |
|
|
|
|
template = template.replacingOccurrences(of: "{{teamsRow}}", with: row) |
|
|
|
|
@ -83,7 +106,7 @@ enum HtmlService { |
|
|
|
|
return template |
|
|
|
|
case .groupstageEntrant(let entrant): |
|
|
|
|
var template = html |
|
|
|
|
if withTeamIndex == false { |
|
|
|
|
if options.withTeamIndex == false { |
|
|
|
|
template = template.replacingOccurrences(of: #"<div class="player">{{teamIndex}}</div>"#, with: "") |
|
|
|
|
} else { |
|
|
|
|
template = template.replacingOccurrences(of: "{{teamIndex}}", with: entrant.seedIndex() ?? "") |
|
|
|
|
@ -91,7 +114,7 @@ enum HtmlService { |
|
|
|
|
|
|
|
|
|
if let playerOne = entrant.players()[safe: 0] { |
|
|
|
|
template = template.replacingOccurrences(of: "{{playerOne}}", with: playerOne.playerLabel()) |
|
|
|
|
if withRank { |
|
|
|
|
if options.withRank { |
|
|
|
|
template = template.replacingOccurrences(of: "{{weightOne}}", with: "(\(playerOne.formattedRank()))") |
|
|
|
|
} else { |
|
|
|
|
template = template.replacingOccurrences(of: "{{weightOne}}", with: "") |
|
|
|
|
@ -103,7 +126,7 @@ enum HtmlService { |
|
|
|
|
|
|
|
|
|
if let playerTwo = entrant.players()[safe: 1] { |
|
|
|
|
template = template.replacingOccurrences(of: "{{playerTwo}}", with: playerTwo.playerLabel()) |
|
|
|
|
if withRank { |
|
|
|
|
if options.withRank { |
|
|
|
|
template = template.replacingOccurrences(of: "{{weightTwo}}", with: "(\(playerTwo.formattedRank()))") |
|
|
|
|
} else { |
|
|
|
|
template = template.replacingOccurrences(of: "{{weightTwo}}", with: "") |
|
|
|
|
@ -115,7 +138,7 @@ enum HtmlService { |
|
|
|
|
return template |
|
|
|
|
case .groupstageRow(let entrant, let teamsPerBracket): |
|
|
|
|
var template = html |
|
|
|
|
template = template.replacingOccurrences(of: "{{team}}", with: HtmlService.groupstageColumn(entrant: entrant, position: "row").html(headName: headName, withRank: withRank, withTeamIndex: withTeamIndex, withScore: withScore)) |
|
|
|
|
template = template.replacingOccurrences(of: "{{team}}", with: HtmlService.groupstageColumn(entrant: entrant, position: "row").html(options: options)) |
|
|
|
|
|
|
|
|
|
var scores = "" |
|
|
|
|
(0..<teamsPerBracket).forEach { index in |
|
|
|
|
@ -124,18 +147,18 @@ enum HtmlService { |
|
|
|
|
if shouldHide == false { |
|
|
|
|
match = entrant.groupStageObject()?.matchPlayed(by: entrant.groupStagePosition!, againstPosition: index) |
|
|
|
|
} |
|
|
|
|
scores.append(HtmlService.groupstageScore(score: match, shouldHide: shouldHide).html(headName: headName, withRank: withRank, withTeamIndex: withTeamIndex, withScore: withScore)) |
|
|
|
|
scores.append(HtmlService.groupstageScore(score: match, shouldHide: shouldHide).html(options: options)) |
|
|
|
|
} |
|
|
|
|
template = template.replacingOccurrences(of: "{{scores}}", with: scores) |
|
|
|
|
return template |
|
|
|
|
case .groupstageColumn(let entrant, let position): |
|
|
|
|
var template = html |
|
|
|
|
template = template.replacingOccurrences(of: "{{tablePosition}}", with: position) |
|
|
|
|
template = template.replacingOccurrences(of: "{{team}}", with: HtmlService.groupstageEntrant(entrant: entrant).html(headName: headName, withRank: withRank, withTeamIndex: withTeamIndex, withScore: withScore)) |
|
|
|
|
template = template.replacingOccurrences(of: "{{team}}", with: HtmlService.groupstageEntrant(entrant: entrant).html(options: options)) |
|
|
|
|
return template |
|
|
|
|
case .groupstageScore(let match, let shouldHide): |
|
|
|
|
var template = html |
|
|
|
|
if match == nil || withScore == false { |
|
|
|
|
if match == nil || options.withScore == false { |
|
|
|
|
template = template.replacingOccurrences(of: "{{winner}}", with: "") |
|
|
|
|
template = template.replacingOccurrences(of: "{{score}}", with: "") |
|
|
|
|
} else if let match, let winner = match.winner() { |
|
|
|
|
@ -146,7 +169,7 @@ enum HtmlService { |
|
|
|
|
return template |
|
|
|
|
case .player(let entrant): |
|
|
|
|
var template = html |
|
|
|
|
if withTeamIndex == false { |
|
|
|
|
if options.withTeamIndex == false { |
|
|
|
|
template = template.replacingOccurrences(of: #"<div class="player">{{teamIndex}}</div>"#, with: "") |
|
|
|
|
} else { |
|
|
|
|
template = template.replacingOccurrences(of: "{{teamIndex}}", with: entrant.formattedSeed()) |
|
|
|
|
@ -155,7 +178,7 @@ enum HtmlService { |
|
|
|
|
|
|
|
|
|
if let playerOne = entrant.players()[safe: 0] { |
|
|
|
|
template = template.replacingOccurrences(of: "{{playerOne}}", with: playerOne.playerLabel()) |
|
|
|
|
if withRank { |
|
|
|
|
if options.withRank { |
|
|
|
|
template = template.replacingOccurrences(of: "{{weightOne}}", with: "(\(playerOne.formattedRank()))") |
|
|
|
|
} else { |
|
|
|
|
template = template.replacingOccurrences(of: "{{weightOne}}", with: "") |
|
|
|
|
@ -167,7 +190,7 @@ enum HtmlService { |
|
|
|
|
|
|
|
|
|
if let playerTwo = entrant.players()[safe: 1] { |
|
|
|
|
template = template.replacingOccurrences(of: "{{playerTwo}}", with: playerTwo.playerLabel()) |
|
|
|
|
if withRank { |
|
|
|
|
if options.withRank { |
|
|
|
|
template = template.replacingOccurrences(of: "{{weightTwo}}", with: "(\(playerTwo.formattedRank()))") |
|
|
|
|
} else { |
|
|
|
|
template = template.replacingOccurrences(of: "{{weightTwo}}", with: "") |
|
|
|
|
@ -179,27 +202,32 @@ enum HtmlService { |
|
|
|
|
return template |
|
|
|
|
case .hiddenPlayer: |
|
|
|
|
var template = html + html |
|
|
|
|
if withTeamIndex { |
|
|
|
|
if options.withTeamIndex { |
|
|
|
|
template += html |
|
|
|
|
} |
|
|
|
|
return template |
|
|
|
|
case .match(let match): |
|
|
|
|
var template = html |
|
|
|
|
if options.withPlannedDate, let plannedStartDate = match.plannedStartDate { |
|
|
|
|
template = template.replacingOccurrences(of: "{{centerMatchText}}", with: plannedStartDate.localizedDate()) |
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
if let entrantOne = match.team(.one) { |
|
|
|
|
template = template.replacingOccurrences(of: "{{entrantOne}}", with: HtmlService.player(entrant: entrantOne).html(headName: headName, withRank: withRank, withTeamIndex: withTeamIndex, withScore: withScore)) |
|
|
|
|
if withScore, let top = match.topPreviousRoundMatch(), top.hasEnded() { |
|
|
|
|
template = template.replacingOccurrences(of: "{{entrantOne}}", with: HtmlService.player(entrant: entrantOne).html(options: options)) |
|
|
|
|
if options.withScore, let top = match.topPreviousRoundMatch(), top.hasEnded() { |
|
|
|
|
template = template.replacingOccurrences(of: "{{matchDescriptionTop}}", with: [top.scoreLabel(winnerFirst:true)].compactMap({ $0 }).joined(separator: "\n")) |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
template = template.replacingOccurrences(of: "{{entrantOne}}", with: HtmlService.hiddenPlayer.html(headName: headName, withRank: withRank, withTeamIndex: withTeamIndex, withScore: withScore)) |
|
|
|
|
template = template.replacingOccurrences(of: "{{entrantOne}}", with: HtmlService.hiddenPlayer.html(options: options)) |
|
|
|
|
} |
|
|
|
|
if let entrantTwo = match.team(.two) { |
|
|
|
|
template = template.replacingOccurrences(of: "{{entrantTwo}}", with: HtmlService.player(entrant: entrantTwo).html(headName: headName, withRank: withRank, withTeamIndex: withTeamIndex, withScore: withScore)) |
|
|
|
|
if withScore, let bottom = match.bottomPreviousRoundMatch(), bottom.hasEnded() { |
|
|
|
|
template = template.replacingOccurrences(of: "{{entrantTwo}}", with: HtmlService.player(entrant: entrantTwo).html(options: options)) |
|
|
|
|
if options.withScore, let bottom = match.bottomPreviousRoundMatch(), bottom.hasEnded() { |
|
|
|
|
template = template.replacingOccurrences(of: "{{matchDescriptionBottom}}", with: [bottom.scoreLabel(winnerFirst:true)].compactMap({ $0 }).joined(separator: "\n")) |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
template = template.replacingOccurrences(of: "{{entrantTwo}}", with: HtmlService.hiddenPlayer.html(headName: headName, withRank: withRank, withTeamIndex: withTeamIndex, withScore: withScore)) |
|
|
|
|
template = template.replacingOccurrences(of: "{{entrantTwo}}", with: HtmlService.hiddenPlayer.html(options: options)) |
|
|
|
|
} |
|
|
|
|
if match.disabled { |
|
|
|
|
template = template.replacingOccurrences(of: "{{hidden}}", with: "hidden") |
|
|
|
|
@ -216,12 +244,13 @@ enum HtmlService { |
|
|
|
|
} |
|
|
|
|
template = template.replacingOccurrences(of: "{{matchDescriptionTop}}", with: "") |
|
|
|
|
template = template.replacingOccurrences(of: "{{matchDescriptionBottom}}", with: "") |
|
|
|
|
template = template.replacingOccurrences(of: "{{centerMatchText}}", with: "") |
|
|
|
|
return template |
|
|
|
|
case .bracket(let round): |
|
|
|
|
var template = "" |
|
|
|
|
var bracket = "" |
|
|
|
|
for (_, match) in round._matches().enumerated() { |
|
|
|
|
template = template.appending(HtmlService.match(match: match).html(headName: headName, withRank: withRank, withTeamIndex: withTeamIndex, withScore: withScore)) |
|
|
|
|
template = template.appending(HtmlService.match(match: match).html(options: options)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bracket = html.replacingOccurrences(of: "{{match-template}}", with: template) |
|
|
|
|
@ -230,7 +259,7 @@ enum HtmlService { |
|
|
|
|
return bracket |
|
|
|
|
case .loserBracket(let upperRound, let hideTitle): |
|
|
|
|
var template = html |
|
|
|
|
template = template.replacingOccurrences(of: "{{minHeight}}", with: withTeamIndex ? "226" : "156") |
|
|
|
|
template = template.replacingOccurrences(of: "{{minHeight}}", with: options.withTeamIndex ? "226" : "156") |
|
|
|
|
template = template.replacingOccurrences(of: "{{tournamentTitle}}", with: upperRound.correspondingLoserRoundTitle()) |
|
|
|
|
if let tournamentStartDate = upperRound.initialStartDate()?.localizedDate() { |
|
|
|
|
template = template.replacingOccurrences(of: "{{tournamentStartDate}}", with: tournamentStartDate) |
|
|
|
|
@ -242,10 +271,10 @@ enum HtmlService { |
|
|
|
|
|
|
|
|
|
var brackets = "" |
|
|
|
|
for round in upperRound.loserRounds() { |
|
|
|
|
brackets = brackets.appending(HtmlService.bracket(round: round).html(headName: headName, withRank: withRank, withTeamIndex: withTeamIndex, withScore: withScore)) |
|
|
|
|
brackets = brackets.appending(HtmlService.bracket(round: round).html(options: options)) |
|
|
|
|
|
|
|
|
|
if round.index == 1 { |
|
|
|
|
let sub = HtmlService.loserBracket(upperRound: round, hideTitle: true).html(headName: headName, withRank: withRank, withTeamIndex: withTeamIndex, withScore: withScore) |
|
|
|
|
let sub = HtmlService.loserBracket(upperRound: round, hideTitle: true).html(options: options) |
|
|
|
|
template = template.appending(sub) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -265,7 +294,7 @@ enum HtmlService { |
|
|
|
|
|
|
|
|
|
for round in upperRound.loserRounds() { |
|
|
|
|
if round.index > 1 { |
|
|
|
|
let sub = HtmlService.loserBracket(upperRound: round, hideTitle: true).html(headName: headName, withRank: withRank, withTeamIndex: withTeamIndex, withScore: withScore) |
|
|
|
|
let sub = HtmlService.loserBracket(upperRound: round, hideTitle: true).html(options: options) |
|
|
|
|
template = template.appending(sub) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -273,17 +302,17 @@ enum HtmlService { |
|
|
|
|
return template |
|
|
|
|
case .template(let tournament): |
|
|
|
|
var template = html |
|
|
|
|
template = template.replacingOccurrences(of: "{{minHeight}}", with: withTeamIndex ? "226" : "156") |
|
|
|
|
template = template.replacingOccurrences(of: "{{minHeight}}", with: options.withTeamIndex ? "226" : "156") |
|
|
|
|
template = template.replacingOccurrences(of: "{{tournamentTitle}}", with: tournament.tournamentTitle(.title)) |
|
|
|
|
template = template.replacingOccurrences(of: "{{tournamentStartDate}}", with: tournament.formattedDate()) |
|
|
|
|
var brackets = "" |
|
|
|
|
for round in tournament.rounds() { |
|
|
|
|
brackets = brackets.appending(HtmlService.bracket(round: round).html(headName: headName, withRank: withRank, withTeamIndex: withTeamIndex, withScore: withScore)) |
|
|
|
|
brackets = brackets.appending(HtmlService.bracket(round: round).html(options: options)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var winnerName = "" |
|
|
|
|
if let tournamentWinner = tournament.tournamentWinner() { |
|
|
|
|
winnerName = HtmlService.player(entrant: tournamentWinner).html(headName: headName, withRank: withRank, withTeamIndex: withTeamIndex, withScore: withScore) |
|
|
|
|
winnerName = HtmlService.player(entrant: tournamentWinner).html(options: options) |
|
|
|
|
} |
|
|
|
|
let winner = """ |
|
|
|
|
<ul class="round" scope="last"> |
|
|
|
|
|