import { IconHelp, IconWindowMaximize, IconWindowMinimize } from '@tabler/icons-react' import React, { useEffect, useRef, useState } from 'react' import { clearPrintArea, PrintScale, setPreviousView, setPrintScale, setPrintScaleLine, useMapStore } from '../../../store/map' import { PrintFormat, PrintOrientation, printResolutions, setPrintOrientation, setPrintResolution, usePrintStore } from '../../../store/print' import { printDimensions, scaleOptions } from '../../../constants/map' import { useObjectsStore } from '../../../store/objects' import jsPDF from 'jspdf' import { getCenter } from 'ol/extent' import ScaleLine from 'ol/control/ScaleLine' import { Button, Checkbox, Dialog, DialogActions, DialogBody, DialogContent, DialogSurface, DialogTitle, Dropdown, Field, Option, Radio, RadioGroup } from '@fluentui/react-components' import { Dismiss24Regular } from '@fluentui/react-icons' const MapPrint = ({ id, mapElement }: { id: string mapElement: React.MutableRefObject }) => { const [fullscreen, setFullscreen] = useState(false) const { printOrientation, printResolution, printFormat } = usePrintStore() const { selectedYear, selectedRegion, selectedDistrict } = useObjectsStore().id[id] const { map, mode, previousView, printArea, printSource, printAreaDraw, printScale, printScaleLine, } = useMapStore().id[id] const exportToPDF = (format: PrintFormat, resolution: number, orientation: PrintOrientation) => { const dim = printDimensions[format] const width = Math.round((dim[orientation === 'horizontal' ? 0 : 1] * resolution) / 25.4) const height = Math.round((dim[orientation === 'horizontal' ? 1 : 0] * resolution) / 25.4) if (!map) return // Store original size and scale const originalSize = map.getSize() const originalResolution = map.getView().getResolution() if (!originalSize || !originalResolution) return // Calculate new resolution to fit high DPI const scaleFactor = width / originalSize[0] const newResolution = originalResolution / scaleFactor // Set new high-resolution rendering map.setSize([width, height]) map.getView().setResolution(newResolution) map.renderSync() map.once("rendercomplete", function () { const mapCanvas = document.createElement("canvas") mapCanvas.width = width mapCanvas.height = height const mapContext = mapCanvas.getContext("2d") if (!mapContext) return const canvas = document.querySelector('canvas') if (canvas) { if (canvas.width > 0) { const opacity = canvas.parentElement?.style.opacity || "1" mapContext.globalAlpha = parseFloat(opacity) const transform = canvas.style.transform const matrixMatch = transform.match(/^matrix\(([^)]+)\)$/) if (matrixMatch) { const matrix = matrixMatch[1].split(",").map(Number) mapContext.setTransform(...matrix as [number, number, number, number, number, number]) } mapContext.drawImage(canvas, 0, 0) } } mapContext.globalAlpha = 1 mapContext.setTransform(1, 0, 0, 1, 0, 0) // Restore original map settings map.setSize(originalSize) map.getView().setResolution(originalResolution) map.renderSync() const dimensions = { w: orientation === 'horizontal' ? dim[0] : dim[1], h: orientation === 'horizontal' ? dim[1] : dim[0] } // Generate PDF const pdf = new jsPDF(orientation === 'horizontal' ? "landscape" : 'portrait', undefined, format) pdf.addImage(mapCanvas.toDataURL("image/jpeg"), "JPEG", 0, 0, dimensions.w, dimensions.h) const filename = `${selectedYear}-${selectedRegion}-${selectedDistrict}-${new Date().toISOString()}.pdf` pdf.save(filename, { returnPromise: true }).then(() => { }) }) } const scaleLine = useRef(new ScaleLine({ bar: true, text: true, minWidth: 125 })) const [opened, setOpened] = useState(false) useEffect(() => { if (printArea && opened) { // backup view before entering print mode setPreviousView(id, map?.getView()) map?.setTarget('print-portal') printSource.clear() map?.getView().setCenter(getCenter(printArea)) map?.getView().fit(printArea, { size: printOrientation === 'horizontal' ? [594, 420] : [420, 594] }) map?.removeInteraction(printAreaDraw) } }, [printArea, map, opened]) useEffect(() => { if (printScaleLine && printArea) { map?.addControl(scaleLine.current) } else { map?.removeControl(scaleLine.current) } }, [printScaleLine, printArea]) useEffect(() => { if (!!printArea) { setOpened(true) } }, [printArea]) useEffect(() => { if (!opened && mode === 'print') { clearPrintArea(id) map?.setTarget(mapElement.current as HTMLDivElement) map?.addInteraction(printAreaDraw) } }, [opened]) return ( ) } export default MapPrint