$(function() {
    
    /* DBPEDIA OVERLAY */
    
    var lang = $("html").attr("lang"),
        sparqlTpl = _.template(
            'select distinct * where { '
            + 'OPTIONAL { <<%= uri %>> rdfs:label ?l FILTER( langMatches( lang(?l), "<%- lang %>" ) ) }. '
            + 'OPTIONAL { <<%= uri %>> dbpedia-owl:thumbnail ?t }. '
            + 'OPTIONAL { <<%= uri %>> dbpedia-owl:abstract ?a FILTER( langMatches( lang(?a), "<%- lang %>" ) ) }. '
            + 'OPTIONAL { <<%= uri %>> dbpedia-owl:wikiPageRedirects ?r }. '
            + 'OPTIONAL { ?r rdfs:label ?lr FILTER( langMatches( lang(?lr), "<%- lang %>" ) ) }. '
            + 'OPTIONAL { ?r dbpedia-owl:thumbnail ?tr }. '
            + 'OPTIONAL { ?r dbpedia-owl:abstract ?ar FILTER( langMatches( lang(?ar), "<%- lang %>" ) ) }. '
            + '}'
        ),
        $overlay = $(".dbpedia-overlay"),
        hovering = null,
        $refdiv = null,
        $win = $(window),
        dbpediaCache = {},
        $overlayImg = $overlay.find("img"),
        $h2 = $overlay.find("h2"),
        $abstract = $overlay.find(".dbpedia-abstract"),
        $source = $overlay.find(".dbpedia-source a");
    
    function moveDbpediaPopin() {
        if (hovering && $refdiv) {
            var refoff = $refdiv.offset(),
                refw = $refdiv.outerWidth(),
                refh = $refdiv.outerHeight(),
                refx = refoff.left,
                refy = refoff.top,
                ovw = $overlay.outerWidth(),
                ovh = $overlay.outerHeight(),
                showAbove = (refy + refh + ovh) > ($win.height() + $win.scrollTop());
            $overlay.css({
                top: showAbove ? (refy - ovh) : (refy + refh),
                left: Math.max(5, Math.min($win.width() - ovw - 5, refx + (refw / 2) - (ovw / 2)))
            });
        }
    }
    
    function showUriData(dbpediaUri) {
        $overlay.hide();
        $overlayImg.attr("src","");
        var uriData = dbpediaCache[dbpediaUri];
        if (!uriData) {
            return false;
        }
        if (hovering) {
            $overlay.show().attr("data-dbpedia-uri", dbpediaUri);
            if (uriData.t || uriData.tr) {
                $overlayImg.attr("src",uriData.t || uriData.tr).show();
            } else {
                $overlayImg.hide();
            }
            var label = uriData.l || uriData.lr || "",
                wkUrl = "http://" + lang + ".wikipedia.org/";
            if (label) {
                wkUrl += "wiki/" + encodeURI(label.replace(/ /g,'_'));
            } 
            $h2.text(uriData.l || uriData.lr || "");
            $abstract.text((uriData.a || uriData.ar || "").replace(/^(.{240,260})\s.+$/,'$1…').substr(0,261));
            $source.attr("href", wkUrl);
            moveDbpediaPopin();
        }
        return true;
    }
    
    function getUriData(dbpediaUri) {
        if (typeof dbpediaCache[dbpediaUri] !== "undefined") {
            return;
        }
        var sparqlEndpoint = dbpediaUri.replace(/\/resource\/.*$/,'/sparql'),
            query = sparqlTpl({uri: decodeURI(dbpediaUri), lang: lang});
        dbpediaCache[dbpediaUri] = false;
        $.getJSON(sparqlEndpoint, {
            query: query,
            format: "application/sparql-results+json"
        }, function(data) {
            if (!data.results || !data.results.bindings || !data.results.bindings.length) {
                return;
            }
            var res = data.results.bindings[0], cacheData = {};
            for (var k in res) {
                if (res.hasOwnProperty(k)) {
                    cacheData[k] = res[k].value;
                }
            }
            dbpediaCache[dbpediaUri] = cacheData;
            if (hovering === dbpediaUri) {
                showUriData(dbpediaUri);
            }
        });
    }
    
    function onDbpediaLeave() {
        hovering = null;
        setTimeout(function() {
            if (!hovering) {
                $overlay.hide();
                deferredRemovePopin();
            }
        }, 0);
    }
    
    window.bindDbpediaBox = function(selector, defaultUri) {
        $(selector).on({
            mouseenter: function(e) {
                $refdiv = $(this);
                var dbpediaUri = $refdiv.attr("data-dbpedia-uri") || defaultUri;
                if (!dbpediaUri) {
                    return;
                }
                hovering = dbpediaUri;
                showUriData(dbpediaUri) || getUriData(dbpediaUri);
            },
            mouseleave: onDbpediaLeave
        });
    }
        
    $overlay.hover(function() {
        var $this = $(this),
            dbpediaUri = $this.attr("data-dbpedia-uri");
        if (dbpediaUri) {
            hovering = dbpediaUri;
        }
    }, onDbpediaLeave);
    
    /* END DBPEDIA OVERLAY MANAGEMENT */
   
    /* NOTICE LIST MANAGEMENT */
   
    var gridsize = 160,
        $popin = null;
    
    function removePopin() {
        if ($popin) {
            $popin.remove();
            $popin = null;
        }
    }
    
    function movePopin() {
        if ($popin) {
            var $tblist = $(".notice-list"),
                $img = $popin.find(".notice-image"),
                $refli = $tblist.find("li[data-notice-id=" + $popin.attr("data-notice-id") + "]"),
                $refimg = $refli.find(".notice-image"),
                $md = $popin.find(".notice-metadata"),
                refo = $refimg.offset(),
                refw = $refimg.width(),
                winw = $win.width(),
                x = refo.left + refw / 2;
            $popin.css({
                top: refo.top - 11,
                width: refw + 260
            });
            if (x < winw / 2) {
                $img.css({
                    float: "left"
                });
                $md.css({
                    "margin-left": refw + 10,
                    "margin-right": 0
                });
                $popin.css({
                    right: "none",
                    left: refo.left - 11
                });
            } else {
                $img.css({
                    float: "right"
                });
                $md.css({
                    "margin-left": 0,
                    "margin-right": refw + 10
                });
                $popin.css({
                    left: "none",
                    right: winw - refo.left - refw - 11
                });
            }
        }
    }
    
    var hoverPopin = false;
    
    function deferredRemovePopin() {
        window.setTimeout(function() {
            if (!hoverPopin) {
                removePopin();
            }
        }, 0);
    }
            
    function adaptGrid() {
        var $tblist = $(".notice-list");
        if ($tblist.length) {
            $tblist.css({
                padding: "0 " + Math.floor($tblist.parent().width() % gridsize / 2) + "px"
            });
        }
    }
    
    function checkSizes() {
        var notloaded = false;
        $(".notice-image").each(function() {
            if (this.__isloaded) {
                return;
            }
            var ih = this.height;
            if (ih < 30) {
                notloaded = true;
                return;
            }
            var iw = this.width,
                scale = gridsize / Math.min(iw, ih),
                nw = scale * iw,
                nh = scale * ih;
            $(this).css({
                width: nw + "px",
                height: nh + "px",
                "margin-top": (gridsize - nh) / 2 + "px",
                "margin-left": (gridsize - nw) / 2 + "px"
            });
            this.__isloaded = true;
        });
        if (notloaded) {
            setTimeout(checkSizes, 500);
        }
    }
    
    window.bindResultsMouseover = function() {
        $(".notice-item").mouseover(function() {
            var $this = $(this);
            window.setTimeout(function() {
                removePopin();
                if (!$this.find(".notice-image")[0].width) {
                    return;
                }
                $popin = $('<div class="notice-popin"></div>').append($this.find(".notice-contents").clone());
                $popin.attr("data-notice-id",$this.attr("data-notice-id"));
                $popin.find(".notice-image").css("margin", 0);
                $("body").append($popin);
                movePopin();
                bindDbpediaBox($popin.find(".notice-term a"));
                $popin.mouseover(function() {
                    hoverPopin = true;
                }).mouseleave(function() {
                    hoverPopin = false;
                    if ($overlay.is(":hidden")) {
                        deferredRemovePopin();
                    }
                });
            }, 0);
        });
        
        removePopin();
        adaptGrid();
        checkSizes();
    }
    
    $win.resize(function() {
        adaptGrid();
        movePopin();
        moveDbpediaPopin();
    }).scroll(moveDbpediaPopin);
        
    $(".language-label").click(function() {
       $(this).siblings(".language-button").click(); 
    });
/*
    $(".language-current").click(function() {
        $(".language-list").toggle();
    });
*/    
    $overlayImg.load(moveDbpediaPopin);
    
});
