/* Psyclone Guides — shared client JS. Offline-first (file://). No external deps required;
   uses jQuery only if present, else vanilla. */
(function(){
  "use strict";

  // ---- Mobile nav toggle ----
  function initMenu(){
    var btn=document.querySelector('.menu-toggle'), sb=document.querySelector('.sidebar');
    if(btn&&sb){btn.addEventListener('click',function(){sb.classList.toggle('open');});}
  }

  // ---- Active nav link (by current file) ----
  function initActiveNav(){
    var here=location.pathname.split('/').pop()||'index.html';
    document.querySelectorAll('.navlist a').forEach(function(a){
      var href=(a.getAttribute('href')||'').split('#')[0];
      if(href===here){a.classList.add('active');}
    });
  }

  // ---- Right-hand in-page TOC + scroll-spy ----
  function initToc(){
    var toc=document.getElementById('pageToc'); if(!toc) return;
    var heads=document.querySelectorAll('.content h2, .content h3');
    if(!heads.length){toc.parentNode.style.display='none';return;}
    var ul=document.createElement('div');
    heads.forEach(function(h){
      if(!h.id){h.id=h.textContent.trim().toLowerCase().replace(/[^a-z0-9]+/g,'-').replace(/^-|-$/g,'');}
      var a=document.createElement('a');
      a.href='#'+h.id; a.textContent=h.textContent;
      if(h.tagName==='H3')a.className='lvl3';
      a.addEventListener('click',function(){setTimeout(function(){spy();},60);});
      ul.appendChild(a);
    });
    toc.appendChild(ul);
    var links=toc.querySelectorAll('a');
    function spy(){
      var y=window.scrollY+90,cur=null;
      heads.forEach(function(h){if(h.offsetTop<=y)cur=h.id;});
      links.forEach(function(l){l.classList.toggle('active',l.getAttribute('href')==='#'+cur);});
    }
    window.addEventListener('scroll',spy,{passive:true}); spy();
  }

  // ---- Copy buttons on code blocks ----
  function initCopy(){
    document.querySelectorAll('pre').forEach(function(pre){
      var b=document.createElement('button');b.className='copybtn';b.textContent='Copy';
      b.addEventListener('click',function(){
        var t=pre.querySelector('code')?pre.querySelector('code').innerText:pre.innerText;
        navigator.clipboard&&navigator.clipboard.writeText(t);
        b.textContent='Copied';setTimeout(function(){b.textContent='Copy';},1200);
      });
      pre.appendChild(b);
    });
  }

  // ---- Lightweight PsySpec XML highlighter (for <pre class="xml">) ----
  function initXml(){
    document.querySelectorAll('pre.xml code, pre.xml').forEach(function(el){
      if(el.dataset.hl)return; el.dataset.hl=1;
      var s=el.innerHTML;
      s=s.replace(/&lt;!--[\s\S]*?--&gt;/g,function(m){return '<span class="com">'+m+'</span>';});
      s=s.replace(/(&lt;\/?)([\w:-]+)/g,'$1<span class="tag">$2</span>');
      s=s.replace(/([\w:-]+)=(&quot;.*?&quot;)/g,'<span class="attr">$1</span>=<span class="str">$2</span>');
      el.innerHTML=s;
    });
  }

  // ---- Glossary / attribute popups. Terms: <span class="pop" data-pop="...">text</span> ----
  function initPopups(){
    var bub=document.getElementById('popbubble');
    if(!bub){bub=document.createElement('div');bub.id='popbubble';document.body.appendChild(bub);}
    function show(e){
      var t=e.currentTarget,txt=t.getAttribute('data-pop');if(!txt)return;
      bub.innerHTML=txt;bub.style.display='block';
      var r=t.getBoundingClientRect();
      var top=r.bottom+8, left=Math.min(r.left, window.innerWidth-340);
      if(top+bub.offsetHeight>window.innerHeight)top=r.top-bub.offsetHeight-8;
      bub.style.top=top+'px';bub.style.left=Math.max(8,left)+'px';
    }
    function hide(){bub.style.display='none';}
    document.querySelectorAll('.pop').forEach(function(t){
      t.addEventListener('mouseenter',show);t.addEventListener('mouseleave',hide);
      t.addEventListener('click',show);
    });
  }

  // ---- Offline search. Expects window.SEARCH_INDEX = [{t:title,c:chapter,u:url,x:text}] ----
  function initSearch(){
    var inp=document.getElementById('searchInput'), res=document.getElementById('searchResults');
    if(!inp||!res||!window.SEARCH_INDEX)return;
    function run(){
      var q=inp.value.trim().toLowerCase();res.innerHTML='';
      if(q.length<2)return;
      var terms=q.split(/\s+/),scored=[];
      window.SEARCH_INDEX.forEach(function(d){
        var hay=(d.t+' '+d.c+' '+d.x).toLowerCase(),sc=0;
        terms.forEach(function(tm){
          if(d.t.toLowerCase().indexOf(tm)>=0)sc+=5;
          var idx=hay.indexOf(tm); if(idx>=0)sc+=2;
        });
        if(sc>0)scored.push({d:d,sc:sc});
      });
      scored.sort(function(a,b){return b.sc-a.sc;});
      scored.slice(0,12).forEach(function(o){
        var li=document.createElement('li');
        li.innerHTML='<a href="'+o.d.u+'"><span class="sr-chap">'+o.d.c+'</span>'+o.d.t+'</a>';
        res.appendChild(li);
      });
      if(!scored.length){res.innerHTML='<li><a style="cursor:default">No matches</a></li>';}
    }
    inp.addEventListener('input',run);
  }

  // ---- Language code tabs (C++ / Python). Markup:
  //   <div class="codetabs"><div class="tabbar">(auto)</div><div class="panes">
  //     <div class="pane" data-lang="cpp" data-label="C++"><pre>...</pre></div>
  //     <div class="pane" data-lang="python" data-label="Python"><pre>...</pre></div>
  //   </div></div>
  // Global preference persists across blocks + pages (localStorage 'psyLang').
  function initCodeTabs(){
    var pref=null; try{pref=localStorage.getItem('psyLang');}catch(e){}
    var groups=document.querySelectorAll('.codetabs');
    function apply(lang){
      groups.forEach(function(g){
        var panes=g.querySelectorAll('.pane'), has=false;
        panes.forEach(function(p){if(p.getAttribute('data-lang')===lang)has=true;});
        panes.forEach(function(p){
          var on=p.getAttribute('data-lang')===lang || (!has && p===panes[0]);
          p.classList.toggle('active',on);
        });
        g.querySelectorAll('.tabbar button').forEach(function(b){
          b.classList.toggle('active', b.getAttribute('data-lang')===lang || (!has && b===g.querySelector('.tabbar button')));
        });
      });
    }
    groups.forEach(function(g){
      if(g.dataset.built)return; g.dataset.built=1;
      var panes=g.querySelectorAll('.pane');
      var bar=g.querySelector('.tabbar'); if(!bar){bar=document.createElement('div');bar.className='tabbar';g.insertBefore(bar,g.firstChild);}
      panes.forEach(function(p){
        var lang=p.getAttribute('data-lang')||'code';
        var label=p.getAttribute('data-label')||(lang==='cpp'?'C++':lang.charAt(0).toUpperCase()+lang.slice(1));
        var b=document.createElement('button'); b.textContent=label; b.setAttribute('data-lang',lang);
        b.addEventListener('click',function(){
          try{localStorage.setItem('psyLang',lang);}catch(e){}
          apply(lang);
        });
        bar.appendChild(b);
      });
    });
    apply(pref||'cpp');
  }

  document.addEventListener('DOMContentLoaded',function(){
    initMenu();initActiveNav();initToc();initCopy();initXml();initPopups();initSearch();initCodeTabs();
  });
})();
