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.
 
 
PadelClub/PadelClub/Utils/HtmlGenerator.swift

223 lines
8.7 KiB

//
// HtmlGenerator.swift
// Padel Tournament
//
// Created by Razmig Sarkissian on 23/10/2023.
//
import Foundation
import UIKit
import WebKit
import PDFKit
import PadelClubData
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
@Published var displayTeamIndex: Bool = false
@Published var displayScore: 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, withTeamIndex: displayTeamIndex, withScore: displayScore)
}
func generateLoserBracketHtml(upperRound: Round) -> String {
//HtmlService.groupstage(bracket: tournament.orderedBrackets.first!).html()
HtmlService.loserBracket(upperRound: upperRound, hideTitle: false).html(headName: displayHeads, withRank: displayRank, withTeamIndex: displayTeamIndex, withScore: displayScore)
}
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.localizedLevelLabel() + "-" + 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"))
}
}