function showTags() {
    var tagsOuter = $(".taglist_container"),
        tagsInner = $(".taglist_container table"),
        acInput = $("#form_tag input[type=search]"),
        acdata = [],
        labels = {
            content: "Séquence",
            tag: "Mot-clé"
        },
        replacerx;
    
    acInput.autocomplete({
        source: function( request, response ) {
            var charsub = [ '[aáàâä]', '[cç]', '[eéèêë]', '[iíìîï]', '[oóòôö]' ],
                terms = request.term.split(/[\s,]/),
                escterms = terms.map(function(term) {
                    var t = term.replace(/([\\\*\+\?\|\{\[\}\]\(\)\^\$\.\#\/])/gm, '\\$1');
                    _(charsub).each(function(chars) {
                        var tmprx = new RegExp(chars,"gim");
                        t = t.replace(tmprx, chars);
                    });
                    return t;
                }).filter(_.identity);
                var searchrxs = _(escterms).map(function(term) {
                    return new RegExp("(^|\\s)" + term, "i")
                });
            replacerx = new RegExp("(^|\\s)(" + escterms.join("|") + ")", "gi");
            var filtered = acdata
                    .filter(function(d) {
                        return _(searchrxs).reduce(function(memo, rx) {
                            return memo && rx.test(d.label);
                        }, true);
                    })
                    .sort(function(a, b) {
                        if (a.type === b.type) {
                            return (a.label > b.label ? 1 : (a.label < b.label ? -1 : 0));
                        } else {
                            return (a.type === "content" ? -1 : 1);
                        }
                    });
            response(filtered);
        },
        select: function(event, ui) {
            document.location.href = ui.item.href;
        }
    }).data("autocomplete")._renderItem = function(ul, item) {
        return $( "<li>" )
            .data( "item.autocomplete", item )
            .append( "<a href='" + item.href + "'>" + labels[item.type] + " : " + item.label.replace(replacerx, '$1<b>$2</b>') + "</a>" )
            .appendTo( ul );
    };
    acInput.on("keyup input paste", function() {
        acInput.val(acInput.val().toUpperCase());
    });
    
    $("#form_tag").submit(function() {
        return false;
    });
        
    tagsInner.draggable();
    
    var dragtimeout;
    
    $(".arrow_left").data({xdelta: 6, ydelta: 0});
    $(".arrow_right").data({xdelta: -6, ydelta: 0});
    $(".arrow_top").data({xdelta: 0, ydelta: 6});
    $(".arrow_bottom").data({xdelta: 0, ydelta: -6});
    
    $(".arrow")
        .on("touchstart mousedown", function(evt) {
            var deltas = $(this).data(),
                move = function() {
                    tagsInner.css({
                        "left": deltas.xdelta + parseInt(tagsInner.css("left")),
                        "top": deltas.ydelta + parseInt(tagsInner.css("top"))
                    });
                }
            window.clearInterval(dragtimeout);
            dragtimeout = window.setInterval(move, 20);
            move();
            return false;
        })
        .on(
            "touchend mouseout mouseup",
            function() {
                window.clearInterval(dragtimeout);
            }
        );
    
    function resizeTags() {
        tagsInner.css({
            "margin-left": - Math.floor(tagsInner.width()/2) + "px",
            "margin-top": - Math.floor(tagsInner.height()/2) + "px",
            "left": Math.floor(tagsOuter.width()/2) + "px",
            "top": Math.floor(tagsOuter.height()/2) + "px"
        });
    }
    $(window).on("resize",resizeTags);
    
    $.ajax({
        url: endpoints.contents_api,
        data: {
            limit: 0,
            format: "json"
        },
        success: function(data) {
            _(data.objects).each(function(content) {
                acdata.push({
                    label: content.title,
                    type: "content",
                    href: endpoints.content_page.replace("__CONTENT_ID__", content.iri_id)
                });
            });
        }
    })
    
    $.ajax({
        url: endpoints.tag_api,
        dataType: "json",
        data: {
            contents: "all",
            format: "json",
            limit: 0,
            steps: 100
        },
        success: function(data) {
            var grouped = {};
            _(data.objects).each(function(t) {
                var upt = t.name.toUpperCase(),
                    w = t.weight + (grouped[upt] || 0);
                grouped[upt] = w;
            });
            _(grouped).each(function(v, k) {
                acdata.push({
                    label: k,
                    type: "tag",
                    href: endpoints.tag_page.replace("__TAG__", k)
                });
            });
            var ordered = _(grouped)
                .chain()
                .map(function(v, k) {
                    return {
                        label: k,
                        weight: v
                    }
                })
                .sortBy(function(t) {
                    return -t.weight;
                })
                .value();
            var l = ordered.length,
                max = ordered[0].weight,
                min = Math.min(max - 1, ordered[l - 1].weight),
                colorscale = 160 / (max - min),
                ncols = Math.floor(.65*Math.sqrt(l)),
                nlines = Math.ceil(l/ncols);
            var cells = _(nlines * ncols)
                .chain()
                .range()
                .map(function(i) {
                    var x = i % ncols,
                        y = Math.floor(i / ncols),
                        dx = x - ((ncols - 1) / 2),
                        dy = y - ((nlines - 1) / 2),
                        d = Math.sqrt(dx*dx + dy*dy);
                    return {
                        n: i,
                        x: x,
                        y: y,
                        d: d
                    }
                })
                .sortBy(function(c) {
                    return c.d;
                })
                .value();
            _(ordered).each(function(v, k) {
                cells[k].tag = v;
            });
            cells = _(cells).sortBy(function(c) { return c.n });
            var _html = "";
            _(cells).each(function(c) {
                if (c.x === 0) {
                    _html += "<tr>";
                }
                _html += "<td>";
                if (c.tag) {
                    var color = Math.floor( 95 + (c.tag.weight - min) * colorscale );
                    _html += '<a href="'
                        + endpoints.tag_page.replace("__TAG__",encodeURIComponent(c.tag.label))
                        + '" style="color: rgb('
                        + [color,color,color].join(",")
                        + ')">'
                        + c.tag.label
                        + '</a>';
                }
                _html += "</td>";
                if (c.x === (ncols - 1)) {
                    _html += "</tr>";
                }
            });
            tagsInner.html(_html);
            resizeTags();
        }
    });
    
    $("#btnInfo, .lightBoxClose").click(function() {
        $(".lightBoxWrap").toggle();
        return false;
    });
    
}
