You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
252 lines
13 KiB
252 lines
13 KiB
//
|
|
// HtmlService.swift
|
|
// Padel Tournament
|
|
//
|
|
// Created by Razmig Sarkissian on 25/10/2023.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
enum HtmlService {
|
|
|
|
case template(tournament: Tournament)
|
|
case bracket(round: Round)
|
|
case loserBracket(upperRound: Round)
|
|
case match(match: Match)
|
|
case player(entrant: TeamRegistration)
|
|
case hiddenPlayer
|
|
case groupstage(groupStage: GroupStage)
|
|
case groupstageEntrant(entrant: TeamRegistration)
|
|
case groupstageColumn(entrant: TeamRegistration, position: String)
|
|
case groupstageRow(entrant: TeamRegistration, teamsPerBracket: Int)
|
|
case groupstageScore(score: Match?, shouldHide: Bool)
|
|
|
|
var url: URL {
|
|
return URL(fileURLWithPath: "\(self.fileName)")
|
|
}
|
|
|
|
var fileName: String {
|
|
switch self {
|
|
case .template, .loserBracket:
|
|
return "tournament-template"
|
|
case .bracket:
|
|
return "bracket-template"
|
|
case .match:
|
|
return "match-template"
|
|
case .player:
|
|
return "player-template"
|
|
case .hiddenPlayer:
|
|
return "hiddenplayer-template"
|
|
case .groupstage:
|
|
return "groupstage-template"
|
|
case .groupstageEntrant:
|
|
return "groupstageentrant-template"
|
|
case .groupstageRow:
|
|
return "groupstagerow-template"
|
|
case .groupstageColumn:
|
|
return "groupstagecol-template"
|
|
case .groupstageScore:
|
|
return "groupstagescore-template"
|
|
}
|
|
}
|
|
|
|
func html(headName: Bool, withRank: Bool, withScore: Bool) -> String {
|
|
guard let file = Bundle.main.path(forResource: self.fileName, ofType: "html") else {
|
|
fatalError()
|
|
}
|
|
|
|
guard let html = try? String(contentsOfFile: file, encoding: String.Encoding.utf8) else {
|
|
fatalError()
|
|
}
|
|
|
|
switch self {
|
|
case .groupstage(let bracket):
|
|
var template = html
|
|
if let startDate = bracket.startDate {
|
|
template = template.replacingOccurrences(of: "{{bracketStartDate}}", with: startDate.formatted())
|
|
} else {
|
|
template = template.replacingOccurrences(of: "{{bracketStartDate}}", with: "")
|
|
}
|
|
template = template.replacingOccurrences(of: "{{tournamentTitle}}", with: bracket.tournamentObject()!.tournamentTitle(.short))
|
|
template = template.replacingOccurrences(of: "{{bracketTitle}}", with: bracket.groupStageTitle())
|
|
|
|
var col = ""
|
|
var row = ""
|
|
bracket.teams().forEach { entrant in
|
|
col = col.appending(HtmlService.groupstageColumn(entrant: entrant, position: "col").html(headName: headName, withRank: withRank, withScore: withScore))
|
|
row = row.appending(HtmlService.groupstageRow(entrant: entrant, teamsPerBracket: bracket.size).html(headName: headName, withRank: withRank, withScore: withScore))
|
|
}
|
|
template = template.replacingOccurrences(of: "{{teamsCol}}", with: col)
|
|
template = template.replacingOccurrences(of: "{{teamsRow}}", with: row)
|
|
|
|
return template
|
|
case .groupstageEntrant(let entrant):
|
|
var template = html
|
|
if let playerOne = entrant.players()[safe: 0] {
|
|
template = template.replacingOccurrences(of: "{{playerOne}}", with: playerOne.playerLabel())
|
|
if withRank {
|
|
template = template.replacingOccurrences(of: "{{weightOne}}", with: "(\(playerOne.formattedRank()))")
|
|
} else {
|
|
template = template.replacingOccurrences(of: "{{weightOne}}", with: "")
|
|
}
|
|
} else {
|
|
template = template.replacingOccurrences(of: "{{playerOne}}", with: "--")
|
|
template = template.replacingOccurrences(of: "{{weightOne}}", with: "")
|
|
}
|
|
|
|
if let playerTwo = entrant.players()[safe: 1] {
|
|
template = template.replacingOccurrences(of: "{{playerTwo}}", with: playerTwo.playerLabel())
|
|
if withRank {
|
|
template = template.replacingOccurrences(of: "{{weightTwo}}", with: "(\(playerTwo.formattedRank()))")
|
|
} else {
|
|
template = template.replacingOccurrences(of: "{{weightTwo}}", with: "")
|
|
}
|
|
} else {
|
|
template = template.replacingOccurrences(of: "{{playerTwo}}", with: "--")
|
|
template = template.replacingOccurrences(of: "{{weightTwo}}", with: "")
|
|
}
|
|
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, withScore: withScore))
|
|
|
|
var scores = ""
|
|
(0..<teamsPerBracket).forEach { index in
|
|
let shouldHide = entrant.groupStagePosition! == index
|
|
var match: Match? = nil
|
|
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, withScore: withScore))
|
|
}
|
|
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, withScore: withScore))
|
|
return template
|
|
case .groupstageScore(let match, let shouldHide):
|
|
var template = html
|
|
if match == nil || withScore == false {
|
|
template = template.replacingOccurrences(of: "{{winner}}", with: "")
|
|
template = template.replacingOccurrences(of: "{{score}}", with: "")
|
|
} else {
|
|
template = template.replacingOccurrences(of: "{{winner}}", with: match!.winner()!.teamLabel())
|
|
template = template.replacingOccurrences(of: "{{score}}", with: match!.scoreLabel())
|
|
}
|
|
template = template.replacingOccurrences(of: "{{hide}}", with: shouldHide ? "hide" : "")
|
|
return template
|
|
case .player(let entrant):
|
|
var template = html
|
|
if let playerOne = entrant.players()[safe: 0] {
|
|
template = template.replacingOccurrences(of: "{{playerOne}}", with: playerOne.playerLabel())
|
|
if withRank {
|
|
template = template.replacingOccurrences(of: "{{weightOne}}", with: "(\(playerOne.formattedRank()))")
|
|
} else {
|
|
template = template.replacingOccurrences(of: "{{weightOne}}", with: "")
|
|
}
|
|
} else {
|
|
template = template.replacingOccurrences(of: "{{playerOne}}", with: "--")
|
|
template = template.replacingOccurrences(of: "{{weightOne}}", with: "")
|
|
}
|
|
|
|
if let playerTwo = entrant.players()[safe: 1] {
|
|
template = template.replacingOccurrences(of: "{{playerTwo}}", with: playerTwo.playerLabel())
|
|
if withRank {
|
|
template = template.replacingOccurrences(of: "{{weightTwo}}", with: "(\(playerTwo.formattedRank()))")
|
|
} else {
|
|
template = template.replacingOccurrences(of: "{{weightTwo}}", with: "")
|
|
}
|
|
} else {
|
|
template = template.replacingOccurrences(of: "{{playerTwo}}", with: "--")
|
|
template = template.replacingOccurrences(of: "{{weightTwo}}", with: "")
|
|
}
|
|
return template
|
|
case .hiddenPlayer:
|
|
return html + html
|
|
case .match(let match):
|
|
var template = html
|
|
if let entrantOne = match.team(.one) {
|
|
template = template.replacingOccurrences(of: "{{entrantOne}}", with: HtmlService.player(entrant: entrantOne).html(headName: headName, withRank: withRank, withScore: withScore))
|
|
} else {
|
|
template = template.replacingOccurrences(of: "{{entrantOne}}", with: HtmlService.hiddenPlayer.html(headName: headName, withRank: withRank, withScore: withScore))
|
|
}
|
|
if let entrantTwo = match.team(.two) {
|
|
template = template.replacingOccurrences(of: "{{entrantTwo}}", with: HtmlService.player(entrant: entrantTwo).html(headName: headName, withRank: withRank, withScore: withScore))
|
|
} else {
|
|
template = template.replacingOccurrences(of: "{{entrantTwo}}", with: HtmlService.hiddenPlayer.html(headName: headName, withRank: withRank, withScore: withScore))
|
|
}
|
|
if match.disabled {
|
|
template = template.replacingOccurrences(of: "{{hidden}}", with: "hidden")
|
|
} else {
|
|
template = template.replacingOccurrences(of: "{{hidden}}", with: "")
|
|
}
|
|
if match.hasEnded() {
|
|
if match.teamWon(atPosition: .one) == true {
|
|
template = template.replacingOccurrences(of: "{{entrantOneWon}}", with: "winner")
|
|
} else if match.teamWon(atPosition: .two) == true {
|
|
template = template.replacingOccurrences(of: "{{entrantTwoWon}}", with: "winner")
|
|
}
|
|
template = template.replacingOccurrences(of: "{{matchDescription}}", with: [match.localizedStartDate(), match.scoreLabel()].joined(separator: "\n"))
|
|
}
|
|
template = template.replacingOccurrences(of: "{{matchDescription}}", 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, withScore: withScore))
|
|
}
|
|
bracket = html.replacingOccurrences(of: "{{match-template}}", with: template)
|
|
bracket = bracket.replacingOccurrences(of: "{{roundLabel}}", with: round.roundTitle())
|
|
return bracket
|
|
case .loserBracket(let upperRound):
|
|
var template = html
|
|
template = template.replacingOccurrences(of: "{{tournamentTitle}}", with: upperRound.correspondingLoserRoundTitle())
|
|
var brackets = ""
|
|
for round in upperRound.loserRounds() {
|
|
brackets = brackets.appending(HtmlService.bracket(round: round).html(headName: headName, withRank: withRank, withScore: withScore))
|
|
}
|
|
var winnerName = ""
|
|
let winner = """
|
|
<ul class="round" scope="last">
|
|
<li class="spacer"> </li>
|
|
<li class="game game-top winner">\(winnerName)</li>
|
|
<li class="spacer"> </li>
|
|
</ul>
|
|
<ul class="main" style="visibility:hidden">
|
|
</ul>
|
|
"""
|
|
brackets = brackets.appending(winner)
|
|
|
|
template = template.replacingOccurrences(of: "{{brackets}}", with: brackets)
|
|
return template
|
|
case .template(let tournament):
|
|
var template = html
|
|
template = template.replacingOccurrences(of: "{{tournamentTitle}}", with: tournament.tournamentTitle(.short))
|
|
var brackets = ""
|
|
for round in tournament.rounds() {
|
|
brackets = brackets.appending(HtmlService.bracket(round: round).html(headName: headName, withRank: withRank, withScore: withScore))
|
|
}
|
|
|
|
var winnerName = ""
|
|
if let tournamentWinner = tournament.tournamentWinner() {
|
|
winnerName = HtmlService.player(entrant: tournamentWinner).html(headName: headName, withRank: withRank, withScore: withScore)
|
|
}
|
|
let winner = """
|
|
<ul class="round" scope="last">
|
|
<li class="spacer"> </li>
|
|
<li class="game game-top winner">\(winnerName)</li>
|
|
<li class="spacer"> </li>
|
|
</ul>
|
|
<ul class="main" style="visibility:hidden">
|
|
</ul>
|
|
"""
|
|
brackets = brackets.appending(winner)
|
|
|
|
template = template.replacingOccurrences(of: "{{brackets}}", with: brackets)
|
|
return template
|
|
}
|
|
}
|
|
}
|
|
|