Friends.RepliesControl = new function() {
    this.createFromTag = function(element, params) {
        new Friends.RepliesControl.Constructor(element, params);
    };
};

Friends.RepliesControl.Constructor = function(element, params) {
    /** TODO: описать */
    this.control = element;
    this.control.control = this;

    /** TODO: описать */
    this.switcher = 0;
    this.params = params;

    /** TODO: описать */
    this.statement = 0;

    this.init();
};

Friends.RepliesControl.Constructor.prototype = new function() {
//public static
    this.TAGNAME = "code";
    this.CLASSNAME = "c-replies";

//public
    /**
     * Обрабатывает событие "нажатие на кнопку". В результате обработки
     * комментарии показывактся или скрывается.
     *
     *  @param  _element    элемент на который пришёлся click
     *  @param  _params     массив параметров
     */
    this.click = function(_element, _params) {
        this.handleFirstClick();
        return this.clickBase(_element, _params);
    };

    this.clickBase = function(_element, _params) {
        return this.showHideReplies(_element, _params);
    };

    this.handleFirstClick = function() {
        /* BLOG-4132: Cписку комментов включаем hasLayout после загрузки контента */
        var repliesBlock = y5.Dom.getAncestorOrSelf(this.control, '*', 'b-replies');
        if (repliesBlock) {
            y5.Classes.add(repliesBlock, 'hasLayout');
        }
        this.click = this.clickBase;

    };

    this.loadReplies = function(_params, _with_parent) {
        var repliesBlock = this.getRepliesBlock();
        if (!repliesBlock) {
            repliesBlock = this.createRepliesBlock();
        }
        this.showReplies(repliesBlock, _params, _with_parent);
    };

//private
    this.showReplies = function(repliesBlock, _params, _with_parent) {
        y5.Classes.add(this.control, 'b-replies-count-loading');

        if (this.switcher) {
            y5.Classes.remove(this.switcher, 'closed');
            y5.Classes.add(this.switcher, 'opened');
        } else {
            if (!y5.Classes.test(this.control, 'nolink')) {
                this.control.innerHTML = '&#160; &#160; &#160; &#160; &#160;';
            }
        }

        this.load(repliesBlock, _params, _with_parent);
    };

    this.isClosed = function() {
        return y5.Classes.test(this.switcher, 'closed');
    };

    this.showHideReplies = function(_element, _params) {
        if (this.isClosed())
        {
            var repliesBlock = this.createRepliesBlock();

            this.showReplies(repliesBlock, _params);
        }
        else
        {
            y5.Classes.swap(this.switcher, 'opened', 'closed');

            this.deleteRepliesBlock();
        }

        return false;
    };

    this.load = function(_repliesBlock, _params, _with_parent) {
        var _this = this;
        var with_parent = _with_parent || false;

        // "осмысление" параметров
        var params = {
            source : _params[0],
            item_no : _params[1],
            parent_id : _params[2],
            new_reply : _params[3],
            replies_prefix : _params[4],
            replies_suffix : _params[5],
            post_store_time : _params[6]
        };

        function commentsCountText(num)
        {
            var prefix = y5.Classes.test(_this.switcher, 'closed') ? params.replies_prefix : '';
            var suffix = params.replies_suffix || '';
            return prefix +
                   y5.Strings.plural(num, ['ответ', 'ответа', 'ответов']) +
                   suffix;
        }

        function responceOK(req, trace) {
            y5.Classes.remove(_this.control, 'b-replies-count-loading');

            if (req == '404') {
                alert('Ошибка! Невозможно загрузить ответы. Пользователь удалил свой журнал.');
                return;
            }

            if (req.html == 'error') {
                alert('Ошибка! Невозможно загрузить ответы.\n\nПожалуйста, перезагрузите страницу.');
                return;
            }

            // обновление ссылки на комментарии
            var commentLink = y5.$('cl-' + req.login + '-' + req.itemNo);
            if (req.commentsCount > 0) {
                try {
                    var parentsCount = req.commentsCount;
//                    if (with_parent) {
//                        parentsCount = req.parentsCount;
//                    }

                    if (_this.switcher) {
                        _this.switcher.innerHTML = commentsCountText(parentsCount);
                     } else if (!y5.Classes.test(commentLink, 'nolink')) {
                        var link = friendsFullURL(req.source, 'replies', 'item_no=' + req.itemNo);
                        commentLink.className = 'b-replies-count Friends-c-RepliesControl s';
                        commentLink.innerHTML = '<a onclick="return [' + y5.JSON.toHTML(req.source) + ',\'' + req.itemNo + '\',\'\']" class="opened" href="' + link + '"><\/a>';
                        _this.switcherInit();
                        _this.switcher.innerHTML = commentsCountText(parentsCount);
                     } else {
                        commentLink.innerHTML = commentsCountText(parentsCount);
                    }
                    var allCounts = y5.$('ac-' + req.itemNo);
                    if (allCounts) {
                        allCounts.innerHTML = commentsCountText(req.commentsCount);
                    }
                } catch (e) {
                }
            }

            _repliesBlock.innerHTML = req.html;

            // global init
            init(_repliesBlock);

            // y5 components init
            y5.Components.init(_repliesBlock);

            try {
                y5.$('reply-' + params.source.login + '-' + params.new_reply).scrollIntoView();
                var y = window.innerHeight;
                if (!y) { // ie
                    y = y5.Dom.getBody().clientHeight;
                }
                window.scrollBy(0, -(0.2 * y));
            } catch (e) { }
        }

        function responceError(trace) {
            alert("Ошибка загрузки ответов.");
        }

        try {
            var url = friendsURL(
                'ajax/replies',
                'source=' + params.source.id
                + '&item_no=' + params.item_no
                + (params.parent_id ? '&parent_id=' + params.parent_id : '')
                + '&with_parent=' + (with_parent ? 1 : 0)
                + '&post_store_time=' + params.post_store_time
                + '&retpath=' + friendsFullURL(g_globals.current_location.source, g_globals.current_location.page, g_globals.current_location.params)
            );
            (new y5.Ajax(new y5.AjaxJS(), url, responceOK, responceError, {parent: this})).send();
        } catch(e) {
           responceError({parent: this});
        }
    };

    this.createRepliesBlock = function() {
        var replies, list;
        if (y5.Classes.test(this.statement, 'b-reply')) {
            replies = document.createElement('ul');
            replies.className = 'l';

            list = replies;
        } else {
            replies=document.createElement('div');
            replies.className = 'b-replies';
            replies.innerHTML = '<ul class="l"></ul>';

            list = replies.firstChild;
        }

        insertAfter(replies, this.statement);

        return list;
    };

    this.getRepliesBlock = function() {
        var comments = getNextElement(this.statement, 'ul');
        if (comments && (comments.className == 'l')) {

        } else {
            comments = getNextElement(this.statement, 'div');
            if (comments && y5.Classes.test(comments, 'b-replies')) {
                comments = comments.firstChild;
            } else {
                comments = null;
            }
        }
        return comments;
    };

    this.deleteRepliesBlock = function() {
        var replies;
        if (y5.Classes.test(this.statement, 'b-reply'))
            replies = y5.Dom.getNext(this.statement, 'ul', '*');
        else
            replies = y5.Dom.getNext(this.statement, 'div', 'b-replies');

        replies.parentNode.removeChild(replies);
    };

    this.switcherInit = function() {
        this.switcher = getByTagName('a', this.control)[0];

        if (!this.switcher) return false;

        this.params = getParams(this.switcher);
        y5.Events.observe('click', function(e) {
            e.preventDefault();
            e.stopPropagation();
            this.click(this.switcher, this.params);
        }, this.switcher, true, this)

        return true;
    };

    this.init = function() {

        var parents = ['b-reply', 'b-post-replies', 'head', 'b-post', 'b-action'];
        for (var i = 0, l = parents.length; i < l; i++) {
            if ((this.statement = y5.Dom.getAncestorOrSelf(this.control, '*', parents[i]))) {
                break;
            }
        }

        if (this.switcherInit())
        {
            var comments = getNextElement(this.statement, 'ul');
            if (comments && (comments.className == 'l')) {
                y5.Classes.add(this.switcher, 'opened');
            } else {
                comments = getNextElement(this.statement, 'div');
                if (comments && (comments.className == 'b-replies')) {
                    y5.Classes.add(this.switcher, 'opened');
                } else {
                    y5.Classes.add(this.switcher, 'closed');
                }
            }
        }
    };

    this.destruct = function() {
        if (this.switcher) {
            if (this.switcher.onclick) {
                this.switcher.onclick = null;
            }
            this.switcher = null;
        }

        this.statement = null;
        this.control.control = null;
        this.control = null;
    };
};

y5.require(['Strings', 'Classes', 'Dom', 'JSON', 'Events'], function() {y5.loaded('{Friends}.RepliesControl')});
