{% macro css(path) %}
  {% if True %}
    <style>
      {% include path %}
    </style>
  {% else %}
    <link rel="stylesheet" href="{{ path }}">
  {% endif %}

{% endmacro %}

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>The {{ title }} pipeline</title>

        <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css" integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" crossorigin="anonymous">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
        <script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
        <script src="https://dagrejs.github.io/project/dagre-d3/latest/dagre-d3.js"></script>
        <!--<script src="dagre-d3-modified.js"></script>-->
        <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>

        {{ css("static/style.css") }}
        {{ css("static/graph.css") }}
    </head>
    <body>

        <h1>Workflow visualisation</h1>
        <svg id="main_chart"></svg>
        
        <div class="modal fade" id="diff_modal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
          <div class="modal-dialog" role="document">
            <div class="modal-content">
              <div class="modal-header">
                <h5 class="modal-title" id="diff_modal_label">Diff</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                  <span aria-hidden="true">&times;</span>
                </button>
              </div>
              <div class="modal-body">
                ...
              </div>
              <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                <!---<button type="button" class="btn btn-primary">Save changes</button>--->
              </div>
            </div>
          </div>
        </div>
        
    </body>

<script>
  /* TODO move this out, use a templating library (nunjucks? vue?), rewrite to modern JS  */
var g = new dagreD3.graphlib.Graph({compound:true})
  .setGraph({
      //rankdir: 'LR',
      ranker: 'longest-path', // longest-path also works finetop
  })
  .setDefaultEdgeLabel(function() { return {}; });

data = {{ json | safe }};
repo = '{{ repository_url }}';

for(var node of data.nodes) {
    g.setNode(node.name, node);
}

for(var edge of data.edges) {
    g.setEdge(edge.from, edge.to);
}
    
for(var cluster of data.clusters) {
    g.setNode(cluster.name, {label: cluster.name, clusterLabelPos: 'top', style: 'fill: ' + cluster.color});
    for(var member_name of cluster.members) {
        g.setParent(member_name, cluster.name); 
    }
    
}

//g.setParent('Proteomics analyses', 'Proteomics');

function show_diff(node_name) {
    var node = g.node(node_name);
    $('#diff_modal_label').html('Reproducibility report for ' + node_name);
    $('#diff_modal .modal-body').html(node.text_diff);
    $('#diff_modal').modal('toggle');
}

function format_outline(headers) {
    let out = '<ul>';
    let last_level = 2;

    for (let header of headers) {

        let chunks = header.trim().split(' ') ;
        let level = chunks[0].length;
        header = chunks.slice(1).join(' ');
        
        // ignore titles
        if(level === 1) {
            continue
        }
        if (level > last_level) {
            out += '<ul>'.repeat(level-last_level)
        }
        else if (level < last_level) {
            out += '</ul>'.repeat(last_level - level);
        }
        last_level = level;

        out += '<li>' + header
    }
    if(last_level !== 1) {
        out += '</ul>'
    }
    return out
}
    
function html_alert(text, kind) {
    return (
        '<div class="alert alert-'+ kind + '" role="alert">'
        + text 
        + '</div>'
    )
}    
g.nodes().forEach(function(v) {
    var node = g.node(v);
    node.rx = node.ry = 5;
    if(node.type == 'notebook'){
        var buttons = [];
        if (node.diff) {
            buttons.push()
        }
        images = ''
        if (node.images.length)
        {
         
            images += '<div class="notebook_images_thumbnails">'
            for(var img of node.images) {
                images += '<div class="thumbnail"><img class="thumbnail-img" src="data:image/png;base64,' + img + '"></div>'
            }
            images += '</div>'
           
        }
        state = ''
        if(node.status != 0) {
            if(node.status === null) {
                //state = html_alert('This notebook has not been executed', 'warning')
            } else {
                state = html_alert('Execution of this notebook has errored', 'danger')
            }
        }
        node.label = (
            state
            + "<div><h4>" + node.name + '</h4><i class="fab fa-github"></i> <a href="' + repo + '/blob/master/' + node.notebook + '">' + node.notebook_name + "</a></div>"
            + '<ul class="stats">'
            + '<li><i class="fas fa-hourglass-end"></i> ' + node.nice_time
            + '<li>' + '<a href="javascript:show_diff(\'' + node.name + '\')" class="fidelity-' + (node.fidelity / 10).toFixed(0) + '">' + (node.fidelity ? parseFloat(node.fidelity.toFixed(2)) : '?') + '% reproducible</a>'
            + '<li><i class="fab fa-git-alt"></i> ' + '<a href="' + repo + '/commits/master/' + node.notebook + '" title="Changes this month">' + node.changes_this_month + ' recent change' + (node.changes_this_month > 1 ? 's' : '') + '</a>'
            + '</ul>'
            + images
            + '<div class="outline">' + format_outline(node.headers) + '</div>'
            + (node.todos.length ? html_alert(node.todos.length + ' TODOs found', 'warning') : '') 
        )
        node.labelType = 'html'
    }
    if(node.type == 'io') {
        label = node.name

        labels = label.split('/')
        path = []
        for(var i = 0; i < labels.length; i++){
            label = labels[i]
            label_title = label
            if(i == 0 && label == 'data') {
                label = '<i class="fas fa-database data_path"></i>'
            }
            
            collapsed = (labels.length > 4 && i > 1 && i < labels.length - 2) ? 'collapsed' : ''

            path.push('<span class="path_element ' + collapsed + '">' + (
                (collapsed ? '<span class="replacement">...</span><span class="hidden_label">' + label + '</span>' : label) 
            ) + '</span>')
        }
        node.label = (
            '<div class="path">'
            + path.join(' / ')
            + '</div>'
        )
        node.labelType = 'html'
    }
});

var render = new dagreD3.render();

var svg = d3.select("svg"),
    svgGroup = svg.append("g");

(function() {
    render(d3.select("svg g"), g);

    d3.selectAll('g.node').each(function(name){
            var node = d3.select(this);
    });
    let svg_node = svg.node();
    let w = svg_node.getBoundingClientRect().width;
    let h = svg_node.getBoundingClientRect().height;

    // graph width and height
    let gw = g.graph().width;
    let gh = g.graph().height;
    // width and height extent
    let we = gw / 2 * 1.1;
    let he = gh / 2 * 1.1;
    let extent = [[-we, -he], [we, he]];
    let zoom = d3.zoom(extent)
        //.extent(extent)
        //.translateExtent(extent)
        //.translateExtent([[0,0], [g.graph().width, g.graph().height]])
        //.translateExtent([[0,0], [rect.width, rect.height]])
        .scaleExtent([.1, 10])
        .on("zoom", function() {
            svgGroup.attr("transform", d3.event.transform);
        });

    let initial_scale = Math.min(w / g.graph().width, h / g.graph().height);

    svg.call(zoom)
          .call(zoom.transform, d3.zoomIdentity
              .scale(initial_scale)
              .translate(
                (w - g.graph().width * initial_scale) / 2,
                (h - g.graph().height * initial_scale) / 2
                ));
})()
    
$('.thumbnail').popover({
  html: true,
  trigger: 'hover',
  content: function () {
    return '<img src="'+ this.firstChild.src + '" class="popover_img"/>';
  }
});
</script>

</html>
