
<?php
/**
 * crank.php
 *
 * Works BOTH from CLI and via browser.
 *
 * REQUIREMENTS ON HOST:
 *  - PHP 8+
 *  - poppler-utils (pdftoppm, pdftotext)
 *
 * USAGE:
 *  CLI:
 *    php crank.php "software.pdf"
 *
 *  Browser:
 *    crank.php?pdf=software.pdf
 */

/* ----------------------------------------------------------
 * Resolve PDF path (CLI or Web)
 * ---------------------------------------------------------- */
if (PHP_SAPI === 'cli') {
    if (!isset($argv[1])) {
        echo "Usage: php crank.php \"software.pdf\"\n";
        exit(1);
    }
    $pdf = $argv[1];
} else {
    if (!isset($_GET['pdf'])) {
        echo "Missing ?pdf= parameter";
        exit;
    }
    $pdf = $_GET['pdf'];
}

if (!file_exists($pdf)) {
    echo "PDF not found: " . htmlspecialchars($pdf);
    exit;
}

/* ----------------------------------------------------------
 * Paths
 * ---------------------------------------------------------- */
$root     = __DIR__;
$assets   = $root . '/assets';
$pagesDir = $assets . '/pages';

@mkdir($pagesDir, 0777, true);

/* ----------------------------------------------------------
 * 1. Extract pages as images
 * ---------------------------------------------------------- */
$cmd = 'pdftoppm -png -r 200 ' . escapeshellarg($pdf) . ' ' . escapeshellarg($pagesDir . '/page');
exec($cmd, $o, $ret);
if ($ret !== 0) {
    echo "pdftoppm failed";
    exit;
}

/* ----------------------------------------------------------
 * 2. Rename images page001.png
 * ---------------------------------------------------------- */
$imgs = glob($pagesDir . '/page-*.png');
sort($imgs, SORT_NATURAL);
$n = 1;
foreach ($imgs as $img) {
    $dst = sprintf('%s/page%03d.png', $pagesDir, $n++);
    @rename($img, $dst);
}

/* ----------------------------------------------------------
 * 3. Extract text
 * ---------------------------------------------------------- */
@mkdir($assets, 0777, true);
$textFile = $assets . '/full.txt';
$cmd = 'pdftotext ' . escapeshellarg($pdf) . ' ' . escapeshellarg($textFile);
exec($cmd, $o, $ret);
if ($ret !== 0) {
    echo "pdftotext failed";
    exit;
}

/* ----------------------------------------------------------
 * 4. Split text into pages
 * ---------------------------------------------------------- */
$text      = file_get_contents($textFile);
$textPages = preg_split("/\f/", $text);

/* ----------------------------------------------------------
 * 5. Build search.json
 * ---------------------------------------------------------- */
$images = glob($pagesDir . '/page*.png');
sort($images, SORT_NATURAL);

$search = ["pages" => []];
for ($i = 0; $i < count($images); $i++) {
    $search["pages"][] = [
        "page" => $i + 1,
        "img"  => "assets/pages/" . basename($images[$i]),
        "text" => trim($textPages[$i] ?? "")
    ];
}

file_put_contents(
    $assets . '/search.json',
    json_encode($search, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
);

/* ----------------------------------------------------------
 * 6. Write index.html (NO heredoc – zero parse issues)
 * ---------------------------------------------------------- */
$indexHtml =
'<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>SKIDATA Software User Guide</title>
<style>
body{margin:0;font-family:system-ui;background:#0b1020;color:#e2e8f0}
header{display:flex;gap:12px;align-items:center;padding:12px;border-bottom:1px solid #1f2a44}
header h1{margin:0;font-size:16px}
header button{background:#142042;color:#e2e8f0;border:1px solid #1f2a44;border-radius:8px;padding:6px 10px;cursor:pointer}
.layout{display:grid;grid-template-columns:300px 1fr;height:calc(100vh - 52px)}
aside{border-right:1px solid #1f2a44;padding:12px;overflow:auto}
main{padding:12px;overflow:auto}
input{width:100%;padding:8px;border-radius:8px;border:1px solid #1f2a44;background:#070b16;color:#e2e8f0}
ul{list-style:none;padding:0;margin:12px 0}
li{margin-bottom:6px}
a{cursor:pointer;color:#e2e8f0;text-decoration:none}
a:hover{color:#fbbf24}
img{max-width:100%;background:#000}
.page-text{white-space:pre-wrap;border-top:1px dashed #334155;padding-top:12px;margin-top:12px;display:none}
.page-text.show{display:block}
</style>
</head>
<body>

<header>
<h1>SKIDATA Software User Guide</h1>
<button id="toggleText">Show text</button>
</header>

<div class="layout">
<aside>
<input id="q" placeholder="Search…">
<ul id="results"></ul>
</aside>
<main>
<img id="pageImg">
<div id="pageText" class="page-text"></div>
</main>
</div>

<script>
(async function(){
  const data = await fetch(\"assets/search.json\").then(r=>r.json());
  let current=0, show=false;
  const img=document.getElementById(\"pageImg\");
  const txt=document.getElementById(\"pageText\");
  const q=document.getElementById(\"q\");
  const res=document.getElementById(\"results\");

  function render(i){
    current=i;
    img.src=data.pages[i].img;
    txt.textContent=data.pages[i].text||\"\";
    txt.classList.toggle(\"show\",show);
  }

  q.oninput=()=>{
    res.innerHTML=\"\";
    const t=q.value.toLowerCase();
    if(!t) return;
    data.pages.forEach((p,i)=>{
      if(p.text.toLowerCase().includes(t)){
        const li=document.createElement(\"li\");
        const a=document.createElement(\"a\");
        a.textContent=\"Page \"+p.page;
        a.onclick=()=>render(i);
        li.appendChild(a);
        res.appendChild(li);
      }
    });
  };

  document.getElementById(\"toggleText\").onclick=()=>{
    show=!show;
    render(current);
  };

  render(0);
})();
</script>

</body>
</html>';

file_put_contents($root . '/index.html', $indexHtml);

/* ----------------------------------------------------------
 * Done
 * ---------------------------------------------------------- */
echo "OK – Interactive site generated\n";



// -------------------------------------------------
// 7. Zip everything
// -------------------------------------------------
$zipFile = $root . '/skidata-validation-manual.zip';
$zip = new ZipArchive();

if ($zip->open($zipFile, ZipArchive::CREATE | ZipArchive::OVERWRITE)) {
    $files = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($root, FilesystemIterator::SKIP_DOTS)
    );

    foreach ($files as $file) {
        if ($file->getFilename() === basename(__FILE__)) continue;
        if ($file->getFilename() === basename($zipFile)) continue;

        $zip->addFile(
            $file->getRealPath(),
            substr($file->getRealPath(), strlen($root) + 1)
        );
    }

    $zip->close();
}