const CGI = api.cgi
const F = CGI.getFossilInstance()
const out = api.io.output

var version = CGI.getVar('version') || R.routeAfterApp.0 || 'trunk'
const includeBaselineFiles = +CGI.getVar('baseline-files', 0)
const includeBaselineObj = +CGI.getVar('baseline', 0)
const linkRoot = CGI.cgiRoot + 'manifest/'
//CGI.request.ENV.PATH_INFO.substr(1/*trim leading slash*/)
const vLinkRoot = linkRoot
//+ '?version=' + (version ? CGI.urlencode(version) : 'trunk')

+version && (version = +version)

const uuidStr = proc(u){
    return u.substr(0,12)
}

const showDeltaTips = proc(){

  /* This is ugly, but it works. We use $-call syntax mixed with heredocs
     and {squiggly strings} to fake a single line of arguments for $-call
     purposes.
  */

  $out <<<EOF
<blockquote>
This is a delta manifest. Tips regarding delta manifests:

<ul>

EOF ((!deck.B || includeBaselineFiles) ? '' : <<<XXX
    <li>We are only showing this
    checkin's files. Use baseline-files=1 to get all files.</li>
XXX) <<<EOF

  <li>Use the 'baseline=0|1' parameter to disable/enable loading of the
    baseline manifest object. Only delta manifests have baselines and
    they are not loaded by default.
    <br/>Try it out:
    <a href='EOF vLinkRoot <<<EOF&baseline=0'>off</a>
    or <a href='EOF vLinkRoot <<<EOF&baseline=1'>on</a>
  </li>

  <li>Use the 'baseline-files=0|1' parameter to disable/enable loading
    of the (inherited) baseline file list. If 0 (the default), only
    files included directly in this checkin (not from baseline
    manifests) are listed in the "F-card". This only affects delta
    manifests.
    <br/>Try it out:
    <a href='EOF vLinkRoot <<<EOF&baseline-files=0'>off</a>
    or <a href='EOF vLinkRoot <<<EOF&baseline-files=1'>on</a>
  </li>

</ul>
</blockquote>
EOF
} /* showDeltaTips() */



const showDeck = proc(deck){
    out({<div><span class='strong'>Manifests: </span>})
    out("[<a href='", linkRoot, 'trunk',
        "'>Trunk</a>] ")

    (deck.P && deck.P.0) && 
        out("[<a href='", linkRoot, deck.P.0,
            "'>Parent</a>] ")

    (deck.B && deck.B.uuid) && 
        out("[<a href='", linkRoot, deck.B.uuid,
            "'>Baseline</a>] ")
    out({</div>})
    
    var children = array[]
    F.db.each(object {
        sql: {SELECT uuid, cid, isprim
             FROM plink JOIN blob ON cid=rid
            WHERE pid=%1$d
            ORDER BY isprim DESC, mtime DESC}.applyFormat(deck.rid),
        callback: proc(){
            //print(this)
            children.push(this.0)
        }
    })
    
    
    if(children.length()){
        $out {<div><span class='strong'>Children: </span>}
        $children.eachIndex proc(v,i){
            i && out(', ')
            out("[<a class='uuid' href='", linkRoot, v,
                "'>", uuidStr(v), "</a>]")

        }.importSymbols('out','linkRoot')
        out({</div>})
    }

    

    $out {<div>}
    const versionLabel = version ?
          (Fossil.isUuid(version) ? "%1$.12s".applyFormat(version) : version)
          : version;

    const reportByUserLink =
        CGI.html.createAnchor( CGI.cgiRoot + 'timeline?user=' + CGI.urlencode(deck.U), 
                                deck.U)

    out(CGI.html.createAnchor(
          CGI.cgiRoot.concat('download/uuid/',deck.uuid,
                            '?name=manfiest-',uuidStr(deck.uuid), '.txt'),
          'Manifest'),
        ' of [',
       Fossil.client.linkToProject('', F.getProjectName()),
       '] repository version [', {<span class='uuid'>},
       Fossil.client.linkToProject('/info/'+version, versionLabel),
       {</span>},
       '] checked in at ',
       Fossil.time.julianToHuman(deck.D),
       ' by ', reportByUserLink)
    deck.C && scope {
        const comment = F.selectVal({SELECT coalesce(ecomment, comment) FROM event WHERE objid=?},
                                    deck.rid, deck.C)
        out({, who commented:},
                  {<blockquote class='timeline-checkin-comment'>},
                  CGI.htmlEscape(comment),
                  {</blockquote>})
    }
    $out {</div>}

    const DeckDiff = api.import('DeckDiff')
    DeckDiff.showDeckFileChangeList(F, deck, true)

    if(0){
        deck.B && showDeltaTips()
        $out {<textarea rows="30" cols="80" readonly>}
        CGI.printJSON(deck)
        $out {</textarea>}
    }
}.importSymbols('F', 'uuidStr')/*showDeck()*/


const ob = api.ob
ob.push() /* start output buffering */
var err = catch{
    const deck = F.loadManifest(version, includeBaselineFiles, includeBaselineObj)
    Fossil.sorter(deck, true)
    showDeck(deck)
}/*catch*/

if(err){
    err = CGI.scrubException(err)
    ob.clear() /* discard buffered output */
    out("Error rendering manifest: <pre>",CGI.htmlEscape(CGI.toJSONString(err)),"</pre>\n")
}else{
    $out <<<EOF
    <script>try {(function(){
        /* for sbs diffs, keep their side-scrolling components synchronized... */
        var SCROLL_LEN = 25;
        function initSbsDiff(diff){
          var txtCols = diff.querySelectorAll('.fsl-diff-text-col');
          var txtPres = diff.querySelectorAll('.fsl-diff-text-col pre');
          var width = Math.max(txtPres[0].scrollWidth, txtPres[1].scrollWidth);
          for(var i=0; i<2; i++){
            txtPres[i].style.width = width + 'px';
            txtCols[i].onscroll = function(e){
              txtCols[0].scrollLeft = txtCols[1].scrollLeft = this.scrollLeft;
            };
          }
          diff.tabIndex = 0;
          diff.onkeydown = function(e){
            e = e || event;
            var len = {37: -SCROLL_LEN, 39: SCROLL_LEN}[e.keyCode];
            if( !len ) return;
            txtCols[0].scrollLeft += len;
            return false;
          };
        }

        var diffs = document.querySelectorAll('.fsl-sbsdiff-cols');
        for(var i=0; i<diffs.length; i++){
          initSbsDiff(diffs[i]);
        }
    }())} catch(e){/*ignore*/}</script>
    EOF

}
ob.flush()
ob.pop()
