// Doghole content. Require jQuery.
// Just make sure your post has right tree structure, otherwise some title may not be shown.
// 2020/05/04
$(function(){
    if (window.Doghole == undefined) {
        window.Doghole = {};
    }
    
    var titleTags = ['h1', 'h2', 'h3']
    ,titleList = $('<ul></ul>')
    ,postDom = $('.post-content')
    ,postDomChildren = postDom.children()
    ,beginLevel = 0
    ,scrollOffset = 1;
    
    // Fit mobile devices. Touchstart can save about 200ms per operation.
    var clickName = ('ontouchstart' in window) ? 'touchstart' : 'click';
    
    // This part is for menu creation.
    $.each(titleTags, function(level, tag) {
        var founds = postDom.find(tag);
        if (!founds.length) {
            beginLevel += 1;
            return true;
        }
        $.each(founds, function(i, found){
            var index = postDomChildren.index($(found)), index = index == -1 ? Math.random() : index
            , menu = 'menu-' + index
            , li = $('<li></li>')
                .attr('level', level)
                .attr('index', index).append(
                    $('<a></a>')
                        .attr({href:'#' + menu, title: $(found).html()})
                        .html($(found).html())
                        .css('text-indent', 2.5 * (level - beginLevel) + 'em')
                        .on(clickName, function(){
                            var _menu = $('[name="' + menu + '"]')
                            , targetTop = _menu.prev().css('display') == 'none' ? _menu.offset().top : _menu.prev().offset().top;
                            if (targetTop + scrollOffset != $(window).scrollTop()) {
                                $('.widget-contents li').find('.active').removeClass('active');
                                $(this).addClass('active');
                                $('html,body').finish().animate({scrollTop: targetTop + scrollOffset});
                            }
                            return false;
                        }));
            $(found).after('<a name="' + menu + '"></a>');
            if (level == beginLevel) {
                titleList.append(li);
            } else {
                // Recursive it
                var recursion = function(prevLevel) {
                    var prevLevelLi = titleList.find('li[level="' + prevLevel + '"]')
                    , appended = false
                    , next;
                    $.each(prevLevelLi, function(j, prevLi){
                        prevLi = $(prevLi);
                        if (prevLi.attr('index') < index && (!prevLi.next().length || prevLi.next().attr('index') > index)) {
                            if (prevLi.children('ul').length) {
                                prevLi.children('ul').append(li);
                            } else {
                                prevLi.append($('<ul></ul>').css('display', 'none').append(li));
                            }
                            appended = true;
                            return false;
                        } 
                        else if (!next || prevLi.attr('index') < next.attr('index')){
                            next = prevLi;
                        }
                    });
                    if (!appended) {
                        // Wrong tree structure
                        if (prevLevel - 1 < beginLevel) {
                            next.before(
                                $('<li></li>')
                                    .attr('level', prevLevel)
                                    .attr('index', index - 1)
                                    .css('display', 'block')
                                    .append($('<ul></ul>').append(li)));
                        } else {
                            recursion(prevLevel - 1);
                        }
                    }
                }
                recursion(level - 1);
            }
        });
    });
    // Add to sidebar
    if (titleList.find('li').length) {
        $('.sidebar-container section:first').before(
            $('<section></section>')
                .append($('<div class="sidebar-header"><span class="widget-title">Contents</span></div>'))
                .append(titleList.addClass('widget-list widget-list2 widget-contents')));
        var showAndActive = function(menua) {
            var others = $('.widget-contents li');
            others.find('.active').removeClass('active');
            
            if (menua && menua.length) {
                var closestParentUl = menua.parents('ul:first');
                while (!closestParentUl.hasClass('widget-contents')) {
                    closestParentUl.slideDown();
                    closestParentUl = closestParentUl.parents('ul:first');
                }
                menua.addClass('active').closest('li').children('ul').slideDown();
            }
            
            $.each(others, function(i, li) {
                li = $(li);
                if (!li.find('.active').length)
                    li.find('ul').slideUp();
            })
        }
        
        // This timer makes sure refreshMenu() is triggered once.
        var _refreshMenuTimer;
        // Refresh menu style after scrolling or resizing.
        // Include sub-menu's slideDown and slideUp.
        window.Doghole.refreshMenu = function() {
            if ($('html,body').is(':animated')) {
                if (_refreshMenuTimer != null) return;
                _refreshMenuTimer = setInterval(function(){
                    if (!$('html,body').is(':animated')) {
                        clearInterval(_refreshMenuTimer);
                        _refreshMenuTimer = null;
                        window.Doghole.refreshMenu();
                        return;
                    }
                }, 50);
                return;
            }
            var scrollTop = $(window).scrollTop()
            , windowHeight = $(window).height();
            if (scrollTop + windowHeight - $('html').height() == 0) {
                showAndActive($('[href^="#menu-"]:last'));
            }
            else if ($('[name^="menu-"]:first').length &&
                     ($('[name^="menu-"]:first').offset().top > windowHeight + scrollTop || scrollTop == 0)) {
                showAndActive();
            }
            else {
                var menus = $('a[name^="menu-"]'), max = null;
                $.each(menus, function(i, menu){
                    menu = $(menu);
                    var targetTop = menu.prev().css('display') == 'none' ? menu.offset().top : menu.prev().offset().top;
                    if (targetTop - scrollOffset <= scrollTop) {
                        max = menu;
                    }
                });
                if (max != null)
                    showAndActive($('[href="#' + $(max).attr('name') + '"'));
            }
        };
        $(window).on('scroll resize', function() {
            try{
                window.Doghole.refreshMenu();
            }
            catch(_){
                setTimeout(function(){
                    $(window).trigger('resize');
                }, 100);
            }
        });
        window.Doghole.refreshMenu();
    }
});