/**
 * Класс для работы с навигационной колонкой и навигации по странице
 * @requires js/jquery.ext.js
 * @requires js/utils.js
 * @requires js/location.js
 */
Navigation = function() {

    /** Таймаут запуска обработчика скрола */
    var scrollTimout = 100;
    /** Продолжительность прокрутки навигатора */
    var barScrollDuration = 200;

    var scrollBody, scrollTop, navBar, $navBar, bodyIsScrolling;

    /** Массив навигационных ссылок по странице */
    var navigationLinks = new Array();

    var activeNavLink;
    var arrowLine;

    /** Массив якорей в контенте, привязаных к ссылкам */
    var contentAnchors = new Array();
    var adjustAnchorFlag = true;

    /**
     * Определяет навигационную колонку
     * @param {String} id ID навигационнной колонки
     */
    function defineNavigationBar(id) {
       navBar = document.getElementById(id);
       $navBar = $(navBar);
       scrollBody = Browser.getScrollBody();
       scrollTop = scrollBody.scrollTop;
    }

    /**
     * Настраивает прокрутку колонки
     */
    function setupScroll() {
        var offsetTop = $navBar.offset().top;
        var footerHeight = $('#footer').outerHeight();
        function barScroll() {
            var b = scrollBody.scrollHeight - footerHeight - $navBar.outerHeight();
            var pTop = (scrollTop > offsetTop)
                ? ((scrollTop > b)
                    ? b
                    : scrollTop)
                : offsetTop;
            pTop -= offsetTop;
            $navBar.stop().animate(
                {
                    top: pTop
                },
                barScrollDuration,
                'swing', function() {
                    adjustCurrentPageAnchor();
                }
            );
        }
        $(window).scroll(function() {
            var _scrollTop = scrollBody.scrollTop;
            window.setTimeout(function() {
                if (_scrollTop == scrollTop) {
                    barScroll();
                }
            }, scrollTimout);
            scrollTop = _scrollTop;
        });
        barScroll();
    }

    /**
     * Настраивает поведение селекторов (табов, списков)
     */
    function setupSelectors() {
        $navBar.find('dl.tabs').tabList();
    }

    /**
     * Настраивает ссылки в навигаторе
     */
    function setupNavigationLinks() {
        $navBar.find('ul.link-list a[rel=nav]').each(function() {
            var link = this;
            var hash = link.href.split('#')[1];
            if (hash) {
                link._decodedHash = decodeURIComponent(hash);
                link._item = link.parentNode;
                navigationLinks.push(link);
                $(link).click(function() {
                    releaseLink(this, true);
                    return false;
                });
            }
        });
        arrowLine = document.getElementById('arrow-line');
        if (arrowLine) {
            arrowLine._$ = $(arrowLine)
        } else {
            var arrowLinePath = document.getElementById('arrow-line-path');
            if (arrowLinePath) {
                var $ar = $(arrowLinePath)
                var $activeItem = $('#link-list-path li.active');
                if ($activeItem.length)
                    $ar.show().css('height', $activeItem.offset().top - $ar.offset().top);
            }
        }
    }

    /**
     * Ищет навигационную ссылку по хэшу
     * @param {String} hash хэш
     */
    function getLinkByHash(hash) {
        for (var i = 0; i  < navigationLinks.length; i++)
            if (navigationLinks[i]._decodedHash == hash)
                return navigationLinks[i];
        return null;
    }

    /**
     * Выполняет обработку нажатия ссылки навигационной ссылки
     * @param {Object} link DOM-объект ссылки
     * @param {Boolean} scrollBodyFlag прокручивать ли контент?
     */
    function releaseLink(link, scrollBodyFlag) {
        if (link != activeNavLink) {
            if (activeNavLink)
                $(activeNavLink._item).removeClass('active');
            if (!link.anchorObject)
                FLocation.set(link.href);
            activeNavLink = link;
            FLocation.setHash(link.anchorObject.name, true);
            var $item = $(activeNavLink._item).addClass('active');
            if (arrowLine)
                arrowLine._$.show().css('height', $item.offset().top - arrowLine._$.offset().top);
            if (activeNavLink.id.match(/path(\d+)\-(\d+)/)) {
                var pathId = RegExp.$1 + ',' + RegExp.$2;
                Cookies.set('_path_id', pathId, '+1d', '/');
            }
            if (scrollBodyFlag) {
                bodyIsScrolling = true;
                $(scrollBody).stop().animate(
                    {
                        scrollTop: link.anchorObject.top
                    },
                    500,
                    'swing', function() {
                        bodyIsScrolling = false;
                    }
                );
            }
        }
    }

    /**
     * Обработка ссылки по текущенму хэшу URL
     */
    function releaseLinkByCurrentHash() {
        var link = getLinkByHash(FLocation.getHash());
        if (link)
            releaseLink(link, true);
    }

    /**
     * Настройка якорей на странице
     */
    function setupContentAnchors() {
        var $anchors = $('a[name]', document.getElementById('center')).each(function() {
            var anchor = this;
            var $anchor = $(anchor);
            var hash = anchor.getAttribute('name');
            var navLink = getLinkByHash(hash);
            if (navLink) {
                var anchorObject = navLink.anchorObject = {
                    navLink : navLink,
                    top     : $anchor.offset().top,
                    name    : hash,
                    object  : anchor
                };
                contentAnchors.push(anchorObject);
                anchor.removeAttribute('name');
            }
        });
        if (contentAnchors.length > 0) {
            releaseLinkByCurrentHash();
            FLocation.attachListener(function() {
                releaseLinkByCurrentHash()
            });
            $(window).bind('scroll', adjustCurrentPageAnchorHandler);
        }
    }


    /**
     * Определяет текущий якорь по прокрутке страницы
     */
    function adjustCurrentPageAnchor() {
        var activeIndex = -1;
        if (scrollTop == (scrollBody.scrollHeight - scrollBody.clientHeight)) {
            activeIndex = contentAnchors.length - 1;
        } else {
            var _delta = 0;
            for (var i = 0; i < contentAnchors.length; i ++) {
                var delta = contentAnchors[i].top - scrollTop;
                if ((delta > 0) ||(i == contentAnchors.length - 1)) {
                    activeIndex = ((-_delta < delta) && (i > 0))
                        ? (i - 1)
                        : i;
                    break;
                } else {
                    _delta = delta;
                }
            }
        }
        if (activeIndex > -1)
            releaseLink(navigationLinks[activeIndex], false);
    }

    function adjustCurrentPageAnchorHandler() {
        if (bodyIsScrolling)
            return;
        var _scrollTop = scrollBody.scrollTop;
        window.setTimeout(function() {
            if (_scrollTop == scrollTop) {
                adjustCurrentPageAnchor();
            }
        }, scrollTimout);
        scrollTop = _scrollTop;
    }

    return {
        /**
         * Настраивает навигацию по странице
         */
        setup: function(navBarID) {
            defineNavigationBar(navBarID);
            if (navBar) {
                setupSelectors();
                setupNavigationLinks();
                setupScroll();
            }
            setupContentAnchors();
        }
    }
}();

