#!/usr/bin/env python3
"""Generate a portable offline index; no model, network or PNG collection."""
from pathlib import Path
import argparse
import json

ROOT = Path(__file__).resolve().parents[1]

TEMPLATE = r'''<!doctype html>
<html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>OpenGlyph glyph index</title><style>
@font-face{font-family:Ebag;src:url('../fonts/OpenGlyphEbag.otf') format('opentype')}
body{max-width:1100px;margin:auto;padding:24px;font:16px/1.65 system-ui;color:#20382c;background:#f7f6f1}
input{padding:12px;width:90%;font:inherit}#grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(155px,1fr));gap:12px}
article{background:white;border:1px solid #ddd;padding:12px;text-align:center}.glyph{display:block;font:80px Ebag}
button{padding:7px;cursor:pointer}code{overflow-wrap:anywhere}.pager{margin:20px 0}a{color:#265f43}
</style><h1>OpenGlyph: 22,583 source forms</h1>
<p>v0.2.1 CTAN candidate. Font-backed forms from GlyphWiki, not an OCR result.
Source IDs and component hits are not scholarly identifications. Check each form against your document.</p>
<input id="query" aria-label="Search source ID or component" placeholder="s030-067, u81e3, or a common character as a component hint">
<p id="status"></p><p>LaTeX: <code id="command">\ebag{s030-067}</code> <span id="copy-status"></span></p>
<main id="grid"></main><div class="pager"><button id="prev">Previous</button> <span id="page"></span> <button id="next">Next</button></div>
<p>Keep this file under doc/ and the font at ../fonts/OpenGlyphEbag.otf. After TEXMF installation, use your local OTF path.
Licenses: <a href="../THIRD-PARTY-NOTICES.md">third-party notices</a>. Each source link below is an optional external link.</p>
<script>
const all=__GLYPH_DATA__,query=document.getElementById('query'),grid=document.getElementById('grid');
let page=0,filtered=all;const size=60;
function filter(){let q=query.value.trim().toLowerCase().replace(/^ebag[:_]/,'');
if(Array.from(q).length===1&&q.codePointAt(0)>127)q='u'+q.codePointAt(0).toString(16);
filtered=all.filter(r=>r[0].includes(q)||r[2].includes(q));page=0;render();}
function render(){grid.replaceChildren();const start=page*size;
for(const r of filtered.slice(start,start+size)){const card=document.createElement('article'),glyph=document.createElement('span'),id=document.createElement('div'),button=document.createElement('button'),link=document.createElement('a');
glyph.className='glyph';glyph.textContent=String.fromCodePoint(r[1]);id.textContent=r[0];button.textContent='Copy LaTeX';
button.onclick=async()=>{const text='\\ebag{'+r[0]+'}';document.getElementById('command').textContent=text;
try{await navigator.clipboard.writeText(text);document.getElementById('copy-status').textContent='Copied';}
catch{document.getElementById('copy-status').textContent='Select the command above and copy it manually.';}};
link.textContent='GlyphWiki source';link.href='https://glyphwiki.org/wiki/ebag_'+r[0];link.target='_blank';link.rel='noopener noreferrer';
card.append(glyph,id,button,document.createElement('br'),link);grid.append(card);}
document.getElementById('status').textContent=filtered.length+' matches / '+all.length+' forms';
document.getElementById('page').textContent=(filtered.length?page+1:0)+' / '+Math.ceil(filtered.length/size);
document.getElementById('prev').disabled=page===0;document.getElementById('next').disabled=start+size>=filtered.length;}
query.oninput=filter;document.getElementById('prev').onclick=()=>{if(page>0){page--;render();}};
document.getElementById('next').onclick=()=>{if((page+1)*size<filtered.length){page++;render();}};filter();
</script></html>
'''


def main():
    p = argparse.ArgumentParser(description=__doc__)
    p.add_argument('-o', '--output', type=Path, default=ROOT.parent/'doc/openglyph-index.html')
    args = p.parse_args()
    manifest = json.loads((ROOT/'data/ebag-manifest.json').read_text())
    rows = [[r['id'], r['codepoint'], ' '.join(r['components'])] for r in manifest['glyphs']]
    args.output.parent.mkdir(parents=True, exist_ok=True)
    args.output.write_text(TEMPLATE.replace('__GLYPH_DATA__', json.dumps(rows, ensure_ascii=True, separators=(',', ':'))), encoding='utf-8')
    print(json.dumps({'entries': len(rows), 'file': str(args.output)}))


if __name__ == '__main__':
    main()
