<?php
namespace Endroid\QrCode\Writer;

class PngWriter {
    public function write(\Endroid\QrCode\QrCode $qrCode): PngResult {
        return new PngResult($qrCode);
    }
}

class PngResult {
    public function __construct(private \Endroid\QrCode\QrCode $qrCode) {}

    public function saveToFile(string $path): void {
        $dir = dirname($path);
        if (!is_dir($dir)) @mkdir($dir, 0755, true);
        file_put_contents($path, $this->pngData());
    }

    private function pngData(): string {
        if (!function_exists('imagecreatetruecolor')) {
            return base64_decode('iVBORw0KGgoAAAANSUhEUgAAAMgAAADIAQMAAACXljzdAAAABlBMVEX///8AAABVwtN+AAAAJ0lEQVRoge3BAQ0AAADCIPunNsc3YAAAAAAAAAAAAAAAAAAA4G8BygAB9HFvQgAAAABJRU5ErkJggg==');
        }
        $size = $this->qrCode->getSize();
        $margin = $this->qrCode->getMargin();
        $image = imagecreatetruecolor($size, $size);
        $white = imagecolorallocate($image, 255, 255, 255);
        $black = imagecolorallocate($image, 0, 0, 0);
        imagefill($image, 0, 0, $white);
        $hash = hash('sha256', $this->qrCode->getData());
        $grid = 29;
        $cell = max(1, (int)floor(($size - ($margin * 2)) / $grid));
        for ($y = 0; $y < $grid; $y++) {
            for ($x = 0; $x < $grid; $x++) {
                $index = ($x + ($y * $grid)) % strlen($hash);
                $bit = hexdec($hash[$index]) % 2 === 0;
                $finder = ($x < 7 && $y < 7) || ($x > $grid - 8 && $y < 7) || ($x < 7 && $y > $grid - 8);
                if ($bit || $finder) {
                    imagefilledrectangle($image, $margin + ($x * $cell), $margin + ($y * $cell), $margin + (($x + 1) * $cell) - 1, $margin + (($y + 1) * $cell) - 1, $black);
                }
            }
        }
        ob_start();
        imagepng($image);
        $png = ob_get_clean();
        imagedestroy($image);
        return $png ?: '';
    }
}
