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.
219 lines
8.5 KiB
219 lines
8.5 KiB
//
|
|
// HtmlGenerator.swift
|
|
// Padel Tournament
|
|
//
|
|
// Created by Razmig Sarkissian on 23/10/2023.
|
|
//
|
|
|
|
import Foundation
|
|
import UIKit
|
|
import WebKit
|
|
import PDFKit
|
|
|
|
class HtmlGenerator: ObservableObject {
|
|
|
|
init(tournament: Tournament) {
|
|
self.tournament = tournament
|
|
}
|
|
|
|
let tournament: Tournament
|
|
@Published var zoomLevel: CGFloat? = 2.0
|
|
@Published var includeBracket: Bool = true
|
|
@Published var includeGroupStage: Bool = true
|
|
@Published var includeLoserBracket: Bool = false
|
|
@Published var displayHeads: Bool = false
|
|
@Published var groupStageIsReady: Bool = false
|
|
@Published var displayRank: Bool = false
|
|
private var pdfDocument: PDFDocument = PDFDocument()
|
|
private var rects: [CGRect] = []
|
|
private var completionHandler: ((Result<Bool, Error>) -> ())?
|
|
@Published var width: CGFloat = 0
|
|
@Published var height: CGFloat = 0
|
|
private var webView: WKWebView = WKWebView()
|
|
private var groupStageDone: Int = 0
|
|
@Published var landscape: Bool = false
|
|
|
|
var baseWidth: CGFloat {
|
|
landscape ? 842 : 595
|
|
}
|
|
|
|
var baseHeight: CGFloat {
|
|
landscape ? 595 : 842
|
|
}
|
|
|
|
var estimatedPageCount: Int {
|
|
if let zoomLevel {
|
|
let pageSize = CGSize(width: baseWidth * (1 + zoomLevel), height: baseHeight * (1 + zoomLevel))
|
|
let numberOfPageInWidth = Int(width / pageSize.width) + 1
|
|
let numberOfPageInHeight = Int(height / pageSize.height) + 1
|
|
return numberOfPageInWidth * numberOfPageInHeight
|
|
} else {
|
|
return 1
|
|
}
|
|
}
|
|
|
|
func preparePDF(completionHandler: @escaping ((Result<Bool, Error>) -> ())) {
|
|
self.completionHandler = completionHandler
|
|
}
|
|
|
|
func generateWebView(webView: WKWebView) {
|
|
self.webView = webView
|
|
self.webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in
|
|
print("evaluateJavaScript", "readystage", complete, error)
|
|
if complete != nil {
|
|
self.webView.evaluateJavaScript("document.documentElement.scrollHeight", completionHandler: { (height, error) in
|
|
print("evaluateJavaScript", "height", height, error)
|
|
self.height = height as! CGFloat
|
|
self.webView.evaluateJavaScript("document.documentElement.scrollWidth", completionHandler: { (width, error) in
|
|
print("evaluateJavaScript", "width", width, error)
|
|
self.width = width as! CGFloat
|
|
if self.completionHandler != nil {
|
|
self.buildPDF()
|
|
}
|
|
})
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
func generateGroupStage(webView: WKWebView) {
|
|
webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in
|
|
if complete != nil {
|
|
webView.evaluateJavaScript("document.documentElement.scrollHeight", completionHandler: { (height, error) in
|
|
let height = height as! CGFloat
|
|
webView.evaluateJavaScript("document.documentElement.scrollWidth", completionHandler: { (width, error) in
|
|
let width = width as! CGFloat
|
|
|
|
print("bracket", width, height)
|
|
let config = WKPDFConfiguration()
|
|
config.rect = CGRect(origin: .zero, size: CGSize(width: Int(width), height: Int(height)))
|
|
webView.createPDF(configuration: config){ result in
|
|
switch result{
|
|
case .success(let data):
|
|
let newPage = PDFDocument(data: data)!
|
|
let page = newPage.page(at: 0)!
|
|
let copiedPage = page.copy() as! PDFPage
|
|
self.pdfDocument.insert(copiedPage, at: self.pdfDocument.pageCount)
|
|
|
|
DispatchQueue.main.async {
|
|
self.groupStageDone += 1
|
|
if self.groupStageDone == self.tournament.groupStages().count {
|
|
self.groupStageIsReady = true
|
|
self.completionHandler?(.success(self.savePDF()))
|
|
}
|
|
}
|
|
case .failure(let error):
|
|
self.completionHandler?(.failure(error))
|
|
}
|
|
}
|
|
|
|
})
|
|
})
|
|
}
|
|
})
|
|
|
|
}
|
|
|
|
func buildPDF() {
|
|
groupStageDone = 0
|
|
groupStageIsReady = false
|
|
pdfDocument = PDFDocument()
|
|
rects.removeAll()
|
|
try? FileManager.default.removeItem(at: pdfURL!)
|
|
print("buildPDF", width, height, zoomLevel ?? 0)
|
|
if let zoomLevel {
|
|
let pageSize = CGSize(width: baseWidth * (1 + zoomLevel), height: baseHeight * (1 + zoomLevel))
|
|
let numberOfPageInWidth = Int(width / pageSize.width) + 1
|
|
let numberOfPageInHeight = Int(height / pageSize.height) + 1
|
|
for w in 0..<numberOfPageInWidth {
|
|
for h in 0..<numberOfPageInHeight {
|
|
let rect = CGRect(x: CGFloat(w) * pageSize.width, y: CGFloat(h) * pageSize.height, width: pageSize.width, height: pageSize.height)
|
|
rects.append(rect)
|
|
}
|
|
}
|
|
} else {
|
|
rects = [CGRect(origin: .zero, size: CGSize(width: Int(width), height: Int(height)))]
|
|
}
|
|
|
|
if includeBracket {
|
|
createPage()
|
|
} else {
|
|
DispatchQueue.main.async {
|
|
self.completionHandler?(.success(true))
|
|
}
|
|
}
|
|
}
|
|
|
|
func createPage() {
|
|
let config = WKPDFConfiguration()
|
|
config.rect = rects[pdfDocument.pageCount]
|
|
webView.createPDF(configuration: config){ result in
|
|
switch result{
|
|
case .success(let data):
|
|
let newPage = PDFDocument(data: data)!
|
|
let page = newPage.page(at: 0)!
|
|
let copiedPage = page.copy() as! PDFPage
|
|
self.pdfDocument.insert(copiedPage, at: self.pdfDocument.pageCount)
|
|
if self.pdfDocument.pageCount < self.rects.count {
|
|
self.createPage()
|
|
} else {
|
|
self.completionHandler?(.success(self.savePDF()))
|
|
}
|
|
case .failure(let error):
|
|
self.completionHandler?(.failure(error))
|
|
}
|
|
}
|
|
}
|
|
|
|
func generateHtml() -> String {
|
|
//HtmlService.groupstage(bracket: tournament.orderedBrackets.first!).html()
|
|
HtmlService.template(tournament: tournament).html(headName: displayHeads, withRank: displayRank, withScore: false)
|
|
}
|
|
|
|
func generateLoserBracketHtml(upperRound: Round) -> String {
|
|
//HtmlService.groupstage(bracket: tournament.orderedBrackets.first!).html()
|
|
HtmlService.loserBracket(upperRound: upperRound).html(headName: displayHeads, withRank: displayRank, withScore: false)
|
|
}
|
|
|
|
var pdfURL: URL? {
|
|
guard let pdfFolderURL = getFilePath() else {
|
|
return nil
|
|
}
|
|
let date = tournament.startDate
|
|
let stringDate = date.formatted(.iso8601
|
|
.year()
|
|
.month()
|
|
.day()
|
|
.dateSeparator(.dash))
|
|
|
|
let name = tournament.tournamentLevel.localizedLabel() + "-" + tournament.tournamentCategory.importingRawValue
|
|
return pdfFolderURL.appendingPathComponent(stringDate + "-" + name + ".pdf")
|
|
}
|
|
|
|
func savePDF() -> Bool {
|
|
pdfDocument.write(to: pdfURL!)
|
|
}
|
|
|
|
var isReady: Bool {
|
|
FileManager.default.fileExists(atPath: pdfURL!.path())
|
|
}
|
|
|
|
func getFilePath() -> URL? {
|
|
if FileManager.default.fileExists(atPath: pdfFolderURL.path) {
|
|
return pdfFolderURL
|
|
} else {
|
|
do {
|
|
try FileManager.default.createDirectory(at: pdfFolderURL, withIntermediateDirectories: true, attributes: nil)
|
|
return pdfFolderURL
|
|
} catch {
|
|
print("getFilePath", error.localizedDescription)
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
|
|
var pdfFolderURL: URL {
|
|
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
|
|
return URL(fileURLWithPath: documentsPath.appending("/pdfs"))
|
|
}
|
|
}
|
|
|