(function ($) {


    var errors = {
        PARENT_COMMENT_AUTHOR_BAN: 'Пользователь ограничил возможность отвечать на его комментарии',
        POSTS_AUTHOR_BAN: 'Пользователь ограничил возможность комментировать свои статьи.',
        ADMINISTRATOR_BAN: 'К сожалению, ваш аккаунт заблокирован. Обновите страницу.',
        JOURNAL_BAN: 'Журнал ограничил возможность комментировать свои статьи.',
        COMMENT_NOT_REMOVED:'Вы не можете восстановить комментарий, так как произошла ошибка при его удалении. Он восстановится после обновления.',
        ALREADY_RESTORING: 'Уже восстанавливаем, подождите чуток :)',
        UNKNOWN_ERROR: 'Произошла непредвиденная ошибка.',
        HAVE_REPLIES: 'Вы не можете изменить содержимое комментария, так как на него уже ответили.',
        SPAM_PREVENTION: 'Вы слишком часто отправляете комментарии, попробуйте чуть позже. Спасибо!',
        EMPTY_DATA: 'Пожалуйста, введите текст или прикрепите вложение, прежде чем отправить.',
        MODERATOR_BAN_DISALLOWED: 'Вы попытались заблокировать модератора. К сожалению, данное действие недоступно.'

    };

    var connectURL = 'https://coms-bWxSZt8x.cont.ws/comments';

    var commentsSocket;

    var postData = {};

    var userData = {};

    //user's actions capabilities
    var capabilities = {
        postAuthorActions: false,
        moderatorActions: false,
        journalActions: false
    };

    var userBans = {
        postAuthorBan: false,
        journalBan: false
    };

    //globals

    var bans = {};
    var journalBans = {};


    var commentSystemContainer = '.comments-wrapper';

    var state = {
        insertingNow: false,
        insertingCommentID: 0,
        insertForm: null,
        deletingComment: null,
        newComments: [],
        editCommentID: null,
        replyToCommentID: null
    }

    var lastPostVisit;
    var isInitialized = false;


    emojify.setConfig({
        emojify_tag_type: 'div',
        only_crawl_id: null,
        ignore_emoticons: true,
        img_dir: '/messages/images/emoji',
        ignored_tags: {
            'SCRIPT': 1,
            'A': 1,
            'PRE': 1,
            'CODE': 1
        }
    });


    //COMMON ELEMENTS
    var $hasMoreRepliesButton = $('<a />')
        .attr('href', '#')
        .text('Раскрыть ветку')
        .addClass('comments-more-replies');

    var $hasMoreCommentsButton = $('<button />')
        .text('Ещё комментарии')
        .addClass('more-comments')
        .addClass('btn')
        .addClass('btn-sm');

    var $replyButton = $('<button />')
        .append('Ответить ')
        .append($('<img />')
            .attr('src', '/images/cont-preloader.svg')
            .attr('width', '12')
            .attr('height', '12')
            .css('display', 'none')
            .addClass('input_form-preloader')
        )
        .addClass('btn')
        .addClass('btn-link')
        .addClass('comment-reply-button');


    var $commentContainer = $('.comment-container');

    var premiumBorderHTML = '<div class="premium-border premium-border--comments-likes"><div class="border border-right"></div><div class="border border-left"></div></div>';
    var premiumBorderHTMLComment = '<div class="premium-border premium-border--comment premium-border--60"><div class="border border-right"></div><div class="border border-left"></div></div>';


    function convertDate(date, short) {

        var currentDate = new Date();
        var day = '',
            month = '',
            year = '',
            hours = '',
            minutes = '';

        var months = ['января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря'];

        var currentMonthAndYear = date.getMonth() == currentDate.getMonth() && date.getFullYear() == currentDate.getFullYear();

        if (date.getDate() == currentDate.getDate() && currentMonthAndYear) day = 'cегодня в ';
        else if (date.getDate() == currentDate.getDate() - 1 && currentMonthAndYear) day = 'вчера в ';
        else {
            day = date.getDate() + ' ';
            month = months[date.getMonth()] + ' ';
            if (date.getFullYear() != currentDate.getFullYear()) year = date.getFullYear() + ' г. ';
        }

        hours = date.getHours();
        minutes = ':' + (date.getMinutes() < 10 ? '0' : '') + date.getMinutes();

        if (short) {
            var response = '';
            if (month) response = day + month + year;
            else response = day + hours + minutes;
            return response;
        } else return day + month + year + hours + minutes;
    }

    function nl2br(str, isXhtml) {

        if (typeof str === 'undefined' || str === null) {
            return ''
        }

        // Adjust comment to avoid issue on locutus.io display
        var breakTag = (isXhtml || typeof isXhtml === 'undefined') ? '<br ' + '/>' : '<br>'

        return (str + '')
            .replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + breakTag + '$2')
    }

    function getNoun(number, one, several, many) {
        number = Math.abs(number);
        number %= 100;
        if (number >= 5 && number <= 20) {
            return many;
        }
        number %= 10;
        if (number == 1) {
            return one;
        }
        if (number >= 2 && number <= 4) {
            return several;
        }
        return many;
    }

    function changeCommentCount(changeBy) {

        var $commentsCount = $('#comments_count');

        var $countSpan = $commentsCount.children('span').eq(0);
        var $labelSpan = $commentsCount.children('span').eq(1);

        var newCount = $countSpan.text() * 1 + changeBy;

        $countSpan.text(newCount);
        $labelSpan.text(getNoun(newCount, 'комментарий', 'комментария', 'комментариев'));

    }
    function copyToClipboard(text) {
        var $temp = $("<input>");
        $("body").append($temp);
        $temp.val(text).select();
        document.execCommand("copy");
        $temp.remove();
    }



    function initializeSocketConnection() {

        //on connection
        function onConnect() {

            commentsSocket.on('connect_failed', function () {
                setTimeout(initializeSocketConnection, 1000);
            });

            commentsSocket.on('connect', function () {

                //get comment form
                var $commentForm = $(commentSystemContainer).children('.comment-form');

                //check status
                if ($commentForm.length && $commentForm.inputForm('getSendingStatus')) {

                    //show error
                    $commentForm.inputForm('showError', 'Произошла ошибка во время отправки. Попробуйте еще раз', false);

                }

		if (!isInitialized) {

			//remove all comments
                	$(commentSystemContainer).find('.comment-container').children().remove();
                	//show preloader
                	$(commentSystemContainer).find('.comments-preloader').show();
                	//unbind all events handlers
                	$(commentSystemContainer).unbind();

                	initCommentsEvents();
                	initViewEvents();
                	initScrollEvents();

		    	isInitialized=true;



                	var commentHash = /^\#(?:comment)(\d+)$/g;
                	var match = commentHash.exec(window.location.hash);

                	commentsSocket.emit('get comments', {
                    		postID: postData.id,
                    		searchCommentID: match ? match[1] : undefined
                	});
		}




            });


        }

        //check if we loggined
        if (userData.id > 0) {

            //get authorization token
            $.ajax({
                type: "POST",
                global: false,
                url: "/connect.php",
                data: ({
                    type: 'connect'
                }),
                dataType: 'json',
                success: function (data) {

                    commentsSocket = io.connect(connectURL, {
                        transports: ['websocket'],
                        upgrade: false,
                        query: data,
                        reconnection: false,
                        forceNew: true
                    });

                    onConnect();

                }

            });

        } else {

            commentsSocket = io.connect(connectURL, {
                transports: ['websocket'],
                upgrade: false,
                reconnection: false,
                forceNew: true
            });


            onConnect();

        }

    }

    function initCommentsEvents() {

        //on disconnect event
        commentsSocket.on('disconnect', function () {

            //start new connection
            setTimeout(initializeSocketConnection, 1000);

        });

        //on get comments
        commentsSocket.on('get comments', function (data) {

            $(commentSystemContainer).children('.comments-preloader').hide();

            //set
            changeCommentCount(data.post.commentsCount);

            //lastPostVisit = window.localStorage.getItem('post:' + postData.id + ':lastVisit') * 1;

            if (!lastPostVisit) {

                lastPostVisit = new Date();
            } else {

                lastPostVisit = new Date(lastPostVisit);
            }

            //window.localStorage.setItem('post:' + postData.id + ':lastVisit', (new Date()).getTime());

            postData = data.post;
            userBans = $.extend(userBans,data.userBans);
            capabilities = $.extend({},data.capabilities);
            bans = $.extend({},data.bans);
            journalBans = $.extend({},data.journalBans);

            //opposing that data is array
            var commentsCount = data.comments.length;
            //comments list
            var commentsContainer = $('.comment-container');

            //make comment view and inserting it
            for (var i = 0; i < commentsCount; i++) {

                if (data.comments[i].needMoreButton) {
                    commentsContainer.append($hasMoreCommentsButton.clone());
                }

                var item = makeCommentItem(data.comments[i], data.likes, new Date(data.comments[i].date) > lastPostVisit);

                //append comment
                commentsContainer.append(item);

                emojify.run(item[0]);
                item.find('[data-toggle="tooltip"]').tooltip();

                //start plugin only for attachments containers that have parents
                item.find('.comment-attachments:has(a)').justifiedGallery({refreshTime: 99999999999999});


            }

            if (data.hasMore) {

                commentsContainer.append($hasMoreCommentsButton);

            }


            var unregisteredComment = window.localStorage.getItem('send_comment_unregistered');
            var startText = '';

            if (unregisteredComment) {

                unregisteredComment = JSON.parse(unregisteredComment);

                if (unregisteredComment.postID == postData.id) {

                    startText = unregisteredComment.text;
                    window.localStorage.removeItem('send_comment_unregistered');
                }
            }

            var bannedText = '';

            if (data.userBans.postAuthorBan) {

                bannedText = 'Пользователь ограничил возможность комментировать свои статьи.';

            } else if (data.userBans.journalBan) {
                bannedText = 'Журнал ограничил возможность комментировать свои статьи'
            }

            var $commentForm = $('.comment-form');

            if ($commentForm.children().length) {

                $commentForm.show();

            } else {

                $('.comment-form').inputForm({
                    senderAvatarURL: 'https://cont.ws/uploads/users/' + userData.id + '.jpg',
                    availableStickers: stickersData.stickersGroups,
                    startText: bannedText.length > 0 ? '' : startText,
                    allowEdit: bannedText.length === 0,
                    placeholderText: bannedText.length > 0 ? bannedText : undefined,
		    showPremiumCheckbox: capabilities.premiumFollowerActions

                });

            }

            var commentHash = /^\#(?:comment)(\d+)$/g;
            var match;

            if (match = commentHash.exec(window.location.hash)) {

                var commentItem = $(commentSystemContainer).find('li[comment-id="' + match[1] + '"]').addClass('comment-search');
                commentItem.children('.media').eq(0).css('background','#e2e8ed');

                if (commentItem.length) {

                    $('html,body').animate({
                        scrollTop: commentItem.offset().top - ($(window).height() - commentItem.outerHeight(true)) / 2
                    });


                }



            }


        });

        commentsSocket.on('more replies', function (data) {

            //find parent comment
            var parentComment = $('.comments-wrapper').find('li[comment-id="' + data.parentComment + '"]');

            bans = $.extend(data.bans,bans);
            journalBans =  $.extend(data.journalBans,journalBans);

            //get container to replies
            var prev = parentComment.children('ul').children('.comments-more-replies');

            if (data.fromReply && data.toReply) {
                prev = prev.eq(0);
            } else {
                prev = $(prev[1]|| prev[0]);
            }

            var moreButton = prev;

            for (var i = 0; i < data.replies.length; i++) {

                if ($('.comments-wrapper').find('li[comment-id="' + data.replies[i].id + '"]').length) continue;

                var commentItem = makeCommentItem(data.replies[i], data.likes);

                commentItem
                    .css('opacity', 0)
                    .insertAfter(prev)
                    .slideDown('slow')
                    .animate({
                        opacity: 1
                    }, {
                        queue: false,
                        duration: 'slow'
                    });
                emojify.run(commentItem[0]);
                commentItem.find('.comment-attachments:has(a)').justifiedGallery({refreshTime: 99999999999999});

                prev = commentItem;

            }

           moreButton.remove();

            if (data.hasMore) {

                $hasMoreRepliesButton.clone().insertAfter(prev);

            }




        });

        commentsSocket.on('get more comments', function (data) {

            var container = $('.comment-container');

            //opposing that data is array
            var commentsCount = data.comments.length;
            //comments list
            var commentsContainer = $('.comment-container');

            var prev = commentsContainer.find('.more-comments');

            if (data.endComment) {
                prev = prev.eq(0);
            } else {
                prev = $(prev[1]|| prev[0]);
            }

            var button = prev;



            bans = $.extend(data.bans,bans);
            journalBans = $.extend(data.journalBans,journalBans);


            //make comment view and inserting it
            for (var i = 0; i < commentsCount; i++) {

                var item = makeCommentItem(data.comments[i], data.likes, false, new Date(data.comments[i].date) > lastPostVisit, data.bannedUsers);

                item.insertAfter(prev)



                emojify.run(item[0]);
                item.find('[data-toggle="tooltip"]').tooltip();
                item.find('.comment-attachments:has(a)').justifiedGallery({refreshTime: 99999999999999});

                prev = item;
            }

            button.remove();

            if (data.hasMore) $hasMoreCommentsButton.clone().insertAfter(prev);






        });

        commentsSocket.on('insert comment', function (data) {


            if (data.error) {

                var errorText = errors[data.error];

                if (!errorText) errorText = errors.UNKNOWN_ERROR;

                var $commentForm;

                if (data.postID) {

                    $commentForm = $('.comments-wrapper').children('.comment-form');

                } else {

                    var $commentItem = $('li[comment-id="' + data.parentID + '"]');

                    if ($commentItem.parent().hasClass('comment-replies')) {

                        $commentForm = $commentItem.parent().find('.comment-form');

                    } else {

                        $commentForm = $commentItem.find('.comment-form');
                    }

                }

                $commentForm.inputForm('showError', errorText);


            }else {

                state.insertingNow = false;
                state.insertingCommentID = data;

                if (state.inputForm.parent('.comment-replies').length) {

                    state.inputForm.remove();

                } else {

                    state.inputForm.inputForm('clearForm');
                }

            }


        });

        commentsSocket.on('restore comment', function (data) {

            if (data.error) {

                var errorText = errors[data.error];

                if (!errorText.length) errorText = errors.UNKNOWN_ERROR;

                if (data.commentID) {

                    var commentItem = $('li[comment-id="' + data.commentID + '"]');

                    $('<div />')
                        .addClass('alert')
                        .addClass('alert-danger')
                        .text(errorText)
                        .insertAfter(commentItem.children('.deleted-comment'))
                        .css('margin-top', '5px')
                        .fadeOut(3000, function () {
                            $(this).remove();
                        });

                }

            }
        });

        commentsSocket.on('remove comment', function (data) {

            //$('li[comment-id="' + data.commentID + '"]').children('.media').find('.comments-remove-button img').hide();

        });

        commentsSocket.on('check for editing', function (data) {

            var commentItem = $('li[comment-id="' + data.commentID + '"]');

            if (data.status == 'OK') {

                var commentTextElement = commentItem.find('.comment-body').clone();


                commentTextElement.children('img').each(function (index, item) {

                    $(item).replaceWith($(item).attr('alt'));

                });

                commentTextElement.children('a').each(function (index, item) {

                    var link = $(item).attr('href');

                    var userLinkRegexp = /\/\/cont\.ws\/(@[a-zA-Z0-9]+)$/ig

                    var userNaming = userLinkRegexp.exec(link);

                    if (userNaming) {

                        $(item).replaceWith(userNaming[1]);

                    } else {

                        $(item).replaceWith(link);
                    }


                });


                var commentForm = $('<div />').addClass('comment-form').prependTo(commentItem).inputForm({
                    startText: commentTextElement.html(),
                    availableStickers: stickersData.stickersGroups,
                    senderAvatarURL: 'https://cont.ws/uploads/users/' + userData.id + '.jpg',
                    showCancelButton: true
                });

                commentForm.attr('data-comment-update', commentItem.attr('comment-id'));


                //append attachments
                var $attachments = commentItem.find('.comment-attachments').eq(0).find('img');

                //for each attachment append it to form
                $attachments.each(function (index, element) {

                    commentForm.inputForm('addAttachmentByURL', $(element).attr('src'));

                });


                commentItem.children('.media').hide();


            } else if (data.error == 'HAVE_REPLIES') {

                $('<div />')
                    .addClass('alert')
                    .addClass('alert-danger')
                    .text('К сожалению, комментарий изменить уже нельзя')
                    .insertAfter(commentItem.children('.media').find('.comment-item__vote'))
                    .css('margin-top', '5px')
                    .fadeOut(3000, function () {
                        $(this).remove();
                    });

            }
        });

        commentsSocket.on('edit comment', function (data) {

            if (data.error) {

                var errorText = errors[data.error];

                if (!errorText.length) errorText = errors.UNKNOWN_ERROR;

                var comment = $('li[comment-id="' + data.commentID + '"]');
                var commentForm = comment.find('.comment-form').eq(0);

                commentForm.inputForm('showError', errorText);

            }

        });

        commentsSocket.on('new comment', function (data) {

            var commentItem = makeCommentItem(data);
            var inserted = false;

            if (data.rootComment) {

                var repliesContainer = $('li[comment-id="' + data.rootComment + '"]').find('.comment-replies');

                if (!repliesContainer.children().last().hasClass('comments-more-replies') || state.insertingCommentID == data.id) {

                    repliesContainer.append(commentItem);
                    commentItem.find('.comment-attachments:has(a)').justifiedGallery({refreshTime: 99999999999999});
                    inserted=true;

                }

            } else {

                var commentsContainer = $('.comment-container');

                if (!commentsContainer.children().last().hasClass('more-comments') || state.insertingCommentID == data.id) {

                    commentsContainer.append(commentItem);
                    commentItem.find('.comment-attachments:has(a)').justifiedGallery({refreshTime: 99999999999999});
                    inserted=true;

                }

            }


            var $commentBody = commentItem.children('.media');

            if (!$commentBody.visible(false) && inserted && state.insertingCommentID !== data.id) {

                $commentBody.addClass('comment-unread');

                $('.comment-new-items').children('strong').text($('.comment-new-items').children('strong').text() * 1 + 1);
                state.newComments.push(commentItem);

                if ($(commentSystemContainer).visible(true)) $('.comment-new-items').show();



            }


            emojify.run(commentItem[0]);

            if (state.insertingCommentID == data.id) {

                state.insertingCommentID = 0;

                if (!commentItem.visible(false)) {

                    $('html,body').animate({
                        scrollTop: commentItem.offset().top - ($(window).height() - commentItem.outerHeight(true)) / 2
                    });


                }

            }


        });

        commentsSocket.on('comment removed', function (data) {

            changeCommentCount(-1);

            var element = $('li[comment-id="' + data + '"]');


            if (element.children('.comment-replies').children().length) {

                element.children(':not(.comment-replies)').remove();

                if (data == state.deletingComment) {


                    element.prepend('<p class="deleted-comment">Комментарий удален. <a href="#" class="comment-restore-button">Восстановить</a></p>')

                } else {

                    element.prepend('<p class="deleted-comment">Комментарий удален.</p>')

                }

            } else if (data == state.deletingComment) {

                element.children(':not(.comment-replies)').remove();
                element.prepend('<p class="deleted-comment">Комментарий удален. <a href="#" class="comment-restore-button">Восстановить</a></p>')

            } else {

                var $parent = element.parent();
                element.remove();

                if ($parent.hasClass('comment-replies')) {

                    var $comment = $parent.parent('li[comment-id]');

                    if ($comment.children('.deleted-comment').length && !$parent.children().length) $comment.remove();
                }

            }

        });

        commentsSocket.on('comment edited', function (data) {

            var element = $('li[comment-id="' + data.commentID + '"]');

            element.children('.media').show();
            element.children('.comment-form').remove();
            element.find('.comment-body').eq(0).html(nl2br(data.text, false));

            var $commentAttachmentsContainer = element.find('.comment-attachments').eq(0);

            //cleanup attachments
            $commentAttachmentsContainer.children().remove();
            $commentAttachmentsContainer.justifiedGallery('destroy');

            //check if attachments present
            if (data.attachments) {

                for (var i = 0; i < data.attachments.length; i++) {

                    $commentAttachmentsContainer.append($('<a />')
                        .append($('<img />')
                            .attr('src', '/uploads/messages/' + data.attachments[i])
                            .addClass('img-responsive')
                        )
                        .attr('href', '#')
                    );

                }

                $commentAttachmentsContainer.show();
                $commentAttachmentsContainer.justifiedGallery({refreshTime: 99999999999999});
            }


            emojify.run(element[0]);


        });

        commentsSocket.on('comment liked', function (data) {

            var $comment = $(commentSystemContainer).find('li[comment-id="' + data.commentID + '"]');

			if (!$comment.length) return;

            var $commentBody = $comment.children('.media');
            var $likeButton = $commentBody.find('.comment-button-like');
            var $likesContainer = $commentBody.find('.liked-user-list');
            var $likesBodyContainer = $likesContainer.find('.liked-user-list__body');
            var $commentItemVote = $likeButton.parent();



            var commentData = $comment.data('commentData');

            //check for user
            if (data.likeAuthor.id == userData.id) {

                var currentStatus = $likeButton.data('status');

                //remove current likeStatus
                $likeButton.removeData('status');

                //check if like  is set
                if (!$likeButton.hasClass('comment-item__vote--pushed') && !currentStatus) {

                    //increase comments count
                    commentData.likes += 1;

                    var $element = $('<a />')
                        .append($('<img />')
                            .attr('src', '//cont.ws/uploads/users/' + data.likeAuthor.id + '.jpg')
                        )
                        .attr('data-like-user', data.likeAuthor.id)
                        .attr('title', data.likeAuthor.nickname)
                        .attr('data-placement', 'top')
                        .attr('data-toggle', 'tooltip');


                    $likeButton.addClass('comment-item__vote--pushed');

                    //prepend element
                    $element.prependTo($likesBodyContainer);

                    //shift body container
                    $likesBodyContainer.css('margin-left', '-45px');
                    $likesBodyContainer.animate({'margin-left': '0px'}, 200);

                    //start tooltip
                    $element.tooltip();


                    //show likes container
                    if ($commentItemVote.data('hovered')) {
                        $likesContainer.show();
                    }


                }

                //if we have changed state
                if (currentStatus === "DISLIKED") {

                    commentsSocket.emit('dislike comment', {
                        commentID: $comment.attr('comment-id')
                    });
                }


            } else {

                //increase comments count
                commentData.likes += 1;

                var $element = $('<a />')
                    .append($('<img />')
                        .attr('src', '//cont.ws/uploads/users/' + data.likeAuthor.id + '.jpg')
                    )
                    .attr('data-like-user', data.likeAuthor.id)
                    .attr('title', data.likeAuthor.nickname)
                    .attr('data-placement', 'top')
                    .attr('data-toggle', 'tooltip');


                var $firstLike = $likesBodyContainer.children().first();

                //check if we have
                if ($firstLike.attr('data-like-user') * 1 === userData.id) {

                    //insert after
                    $element.insertAfter($firstLike);


                } else if($firstLike.length) {

                    //insert before
                    $element.insertBefore($firstLike);

                } else {
                    //insert before
                    $likesBodyContainer.append($element);
                }

                $element.tooltip();

            }


            $likeButton.find('.comment-like-counter').text(commentData.likes);

            //set updated data
            $comment.data('commentData', commentData);

            //init caption
            var caption = getNoun(commentData.likes, 'Одобрил ', 'Одобрили ', 'Одобрили ');

            //caption
            caption += commentData.likes;
            caption += getNoun(commentData.likes, ' человек', ' человека', ' человек')

            //set caption
            $likesContainer.find('strong').text(caption);


        });

        commentsSocket.on('comment disliked', function (data) {

            var $comment = $('li[comment-id="' + data.commentID + '"]');
            var $commentBody = $comment.children('.media');
            var $likeButton = $commentBody.find('.comment-button-like');
            var $likesContainer = $commentBody.find('.liked-user-list');
            var $likesBodyContainer = $likesContainer.find('.liked-user-list__body');
            var $commentItemVote = $likeButton.parent();

            var commentData = $comment.data('commentData');

            if (data.likeAuthor.id == userData.id) {


                var currentStatus = $likeButton.data('status');

                //remove current likeStatus
                $likeButton.removeData('status');


                if ($likeButton.hasClass('comment-item__vote--pushed') && !currentStatus) {

                    //set commentData
                    commentData.likes -= 1;

                    //animation
                    $likesBodyContainer.animate({'margin-left': '-45px'}, 200, function () {

                        $likesBodyContainer.children('a[data-like-user="' + userData.id + '"]').remove();
                        $likesBodyContainer.css('margin-left', '0px');

                        //hide likes container
                        if (!$likesBodyContainer.children().length) {
                            $likesContainer.hide();
                        }

                    });

                }

                if (currentStatus == "LIKED") {

                    commentsSocket.emit('like comment', {
                        commentID: $comment.attr('comment-id')
                    });

                }


            } else {

                //increase comments count
                commentData.likes -= 1;

                //remove
                $likesBodyContainer.children('a[data-like-user="' + data.likeAuthor.id + '"]').remove();

            }

            $likeButton.find('.comment-like-counter').text(commentData.likes);

            //set updated data
            $comment.data('commentData', commentData);

            //init caption
            var caption = getNoun(commentData.likes, 'Одобрил ', 'Одобрили ', 'Одобрили ');

            //caption
            caption += commentData.likes;
            caption += getNoun(commentData.likes, ' человек', ' человека', ' человек')

            //set caption
            $likesContainer.find('strong').text(caption);


        });

        commentsSocket.on('comment restored', function (data) {

            changeCommentCount(1);

            var commentItem = makeCommentItem(data, data.likesData);

            var existingComment = $('li[comment-id="' + data.id + '"]');

            if (existingComment.length) {

                existingComment.children(':not(.comment-replies)').remove();
                existingComment.prepend(commentItem.children(':not(.comment-replies)'));

                emojify.run(existingComment[0]);
                existingComment.find('[data-toggle="tooltip"]').tooltip();

                //start plugin only for attachments containers that have parents
                existingComment.find('.comment-attachments:has(a)').justifiedGallery({refreshTime: 99999999999999});


            } else {

                if (data.rootCommentID) {

                    //try to find root comment item
                    var $rootCommentItem = $('li[comment-id="' + data.rootCommentID + '"]');

                    //if not found - maybe two options: 1 - placed after more comments button
                    // 2- root comment removed
                    if (!$rootCommentItem.length) {

                        var $comments = $('.comment-container').children('li[comment-id]');

                        var lastCommentID = $comments.last().attr('comment-id');

                        var $lastElement = $('.comment-container').children().last();

                        //check if we can insert,
                        if (lastCommentID > data.rootCommentID || !$lastElement.hasClass('more-comments')) {

                            //if we have comments with greater id
                            $rootCommentItem = makeCommentItem({id: data.rootCommentID, removed: true, replies: []});

                            //detect position where to insert
                            var insertBefore = $comments.filter(function (index, element) {

                                return $(element).attr('comment-id') * 1 > data.rootCommentID * 1;

                            }).eq(0);

                            //if all given values more
                            if (!insertBefore.length) {
                                $('.comment-container').append($rootCommentItem);
                            } else {
                                $rootCommentItem.insertBefore(insertBefore);
                            }

                            $rootCommentItem.children('.comment-replies').append(commentItem);



                        }

                    } else {

                        var $repliesContainer = $rootCommentItem.children('.comment-replies');
                        var $replies = $repliesContainer.children('li[comment-id]');

                        var insertPosition = $replies.filter(function (index, element) {

                            return $(element).attr('comment-id') * 1 > data.id * 1;

                        }).eq(0);

                        if (insertPosition.length && !insertPosition.prev().hasClass('comments-more-replies')) {

                            commentItem.insertBefore(insertPosition);

                        } else if (!$repliesContainer.children().last().hasClass('comments-more-replies')) {

                            $repliesContainer.append(commentItem);

                        }


                    }

                } else {

                    //find place, where to restore
                    var insertBefore = $('.comment-container').children('li[comment-id]').filter(function (index, element) {

                        return $(element).attr('comment-id') * 1 > data.id * 1;

                    }).eq(0);

                    if (insertBefore.length) {

                        commentItem.insertBefore(insertBefore);

                    } else {

                        if (!$('.comment-container').last().hasClass('more-comments')) {
                            $('.comment-container').append(commentItem);
                        }

                    }

                }


                emojify.run(commentItem[0]);
                commentItem.find('[data-toggle="tooltip"]').tooltip();

                //start plugin only for attachments containers that have parents
                commentItem.find('.comment-attachments:has(a)').justifiedGallery({refreshTime: 99999999999999}).show();


            }

        });

        commentsSocket.on('get comments likes', function (data) {

            var insertContainer = $('#comments-likes-modal').find('.aggregation-modal__users');

            for (var i = 0; i < data.likes.length; i++) {

                var $userLikeElement = $('<a />')
                    .attr('href', '//cont.ws/@' + data.likes[i].login)
                    .addClass('ava80')
                    .append($('<figure />')
                        .append($('<img />')
                            .attr('src', '/uploads/users/' + data.likes[i].id + '.jpg')
                        )
                    )
                    .append(data.likes[i].nickname);

                if(data.likes[i].premium > 5 && data.likes[i].premium < 9) $userLikeElement.find('figure').append(premiumBorderHTML);

                insertContainer.append($userLikeElement);
            }

        });

        commentsSocket.on('used emoji', function (emojies) {

            $.inputFormUtils.addLastEmojies(emojies);

        });

        commentsSocket.on('last stickers', function (stickerData) {

            $.inputFormUtils.addLastSticker(stickerData);

        });

        commentsSocket.on('check for reply', function (data) {

            //comment item
            var $commentItem = $('.comments-wrapper').find('li[comment-id = "' + data.commentID + '"]');

            //get preloader
            var $preloader = $commentItem.children('.media').find('.comment-reply-button img');

            //check if preloader active, if not true skip
            if ($preloader.is(':hidden')) return;

            //remove all forms
            $('.comment-container').find('.comment-form').remove();

            //try to get root comment
            var $rootCommentItem = $commentItem.parents('li[comment-id]');

            //get form insert container
            var $formInsertContainer = !$rootCommentItem.length ? $commentItem.children('.comment-replies') : $commentItem.parent();

            var $form;

            if (data.status === 'OK') {

                $form = $('<div />')
                    .addClass('comment-form')
                    .appendTo($formInsertContainer)
                    .inputForm({
                        startText: '@' + $commentItem.attr('comment-author-login') + ',&nbsp;',
                        availableStickers: stickersData.stickersGroups,
                        senderAvatarURL: 'https://cont.ws/uploads/users/' + userData.id + '.jpg',
                        showCancelButton: true
                    }).attr('data-reply-comment', data.commentID);

                $preloader.hide();

            } else if (data.error === 'BANNED') {

                $form = $('<div />')
                    .addClass('comment-form')
                    .appendTo($formInsertContainer)
                    .inputForm({
                        senderAvatarURL: 'https://cont.ws/uploads/users/' + userData.id + '.jpg',
                        showCancelButton: true,
                        allowEdit: false,
                        placeholderText: 'Пользователь ограничил возможность отвечать на его комментарии'
                    }).attr('data-reply-comment', data.commentID);

            }

            //scroll to form
            if (!$form.visible(false)) {

                $('html,body').animate({
                    scrollTop: $form.offset().top - ($(window).height() - $form.outerHeight(true)) / 2
                });

            }

            $preloader.hide();

        });

        commentsSocket.on('user banned', function (data) {

            bans[data.banUser] = true;
            $('li[data-user-id="' + data.banUser + '"]').children('.media').find('.comment-ban-button').text('Разблокировать пользователя');

        });

        commentsSocket.on('user unbanned', function (data) {

            bans[data.banUser] = false;
            $('li[data-user-id="' + data.banUser + '"]').children('.media').find('.comment-ban-button').text('Заблокировать пользователя');

        });

        commentsSocket.on('ban user', function (data) {

            if (data.error){

                var errorText = errors[data.error];

                if (!errorText) errorText = errors.UNKNOWN_ERROR;

                alert(errorText);
            }

        });



    }

    function initViewEvents() {
        $(commentSystemContainer).on('click', '.comment-new-items', function (evt) {

            var commentItem =  state.newComments.shift();

            $('html,body').animate({
                    scrollTop: commentItem.offset().top - ($(window).height() - commentItem.outerHeight(true)) / 2
            });

            $('.comment-new-items').children('strong').text($('.comment-new-items').children('strong').text() * 1 - 1);

            return false;

        });

        $(commentSystemContainer).on('click', '.comments-more-replies', function (evt) {

            evt.preventDefault();

            //get first level node
            var parentID = $(this).parents('li').attr('comment-id');
            //get last reply id
            var fromReply = $(this).prev().attr('comment-id');

            var toReply = $(this).next().attr('comment-id');


            commentsSocket.emit('more replies', {
                commentID: parentID,
                fromReply: fromReply,
                toReply: toReply ? toReply : undefined
            });


            return false;
        });

        $(commentSystemContainer).on('click', '.more-comments', function (evt) {

            evt.preventDefault();

            //get first level node
            var fromComment = $(this).prev().attr('comment-id');

            commentsSocket.emit('get more comments', {
                postID: postData.id,
                fromComment: fromComment,
                toComment: $(this).next().attr('comment-id')
            });

            return false;
        });


        $(commentSystemContainer).on('cont.widgets.inputform.send', '.comment-form', function (evt, text, attachments, usedEmojies) {


            evt.preventDefault();

            //check
            if (!userData.id) {

                $('#top-login').click();

                /*window.localStorage.setItem('send_comment_unregistered', JSON.stringify({
                    postID: postData.id,
                    text: text
                }));*/

                return;
            }

            state.insertingNow = true;

            //detect form position
            var $commentForm = $(this);

            state.inputForm = $commentForm;


            if ($commentForm.attr('data-comment-update')) {

                var commentID = $commentForm.attr('data-comment-update');

                commentsSocket.emit('edit comment', {
                    commentID: commentID,
                    text: text,
                    attachments: attachments.map(function (path) {
                        return path.replace('/uploads/messages/', '');
                    })
                });

            } else {

                //we are in parent comments
                if ($commentForm.parent().hasClass('comment-replies')) {

                    commentsSocket.emit('insert comment', {
                        parentCommentID: $commentForm.attr('data-reply-comment'),
                        text: text,
                        attachments: attachments
                    });

                } else {

		    var premiumThread = $commentForm.find('.premium-thread-checkbox').find(':checkbox').is(':checked');

                    commentsSocket.emit('insert comment', {
                        postID: postData.id,
                        text: text,
                        attachments: attachments,
			premiumThread: premiumThread
                    });
                }

            }

            if (usedEmojies.length) {

                commentsSocket.emit('used emoji', usedEmojies);
            }


            return false;
        });

        $(commentSystemContainer).on('cont.widgets.inputform.cancel', '.comment-form', function (evt, text, attachments, usedEmojies) {

            if ($(this).attr('data-comment-update')) {
                $(this).parent().children('.media').show();
            }

            $(this).inputForm('destroy');

        });

        $(commentSystemContainer).on('cont.widgets.inputform.send-sticker', '.comment-form', function (evt, stickerGroup, stickerID) {

            var commentForm = $(this);
            var parentCommentID = commentForm.attr('data-reply-comment') * 1;

            state.inputForm = commentForm;

            if (parentCommentID) {

                commentsSocket.emit('insert comment', {
                    parentCommentID: parentCommentID,
                    stickerType: stickerGroup,
                    stickerID: stickerID
                });

            } else {

                commentsSocket.emit('insert comment', {
                    postID: postData.id,
                    stickerType: stickerGroup,
                    stickerID: stickerID
                });

            }

        });

        $(commentSystemContainer).on('click', '.comments-edit-button', function (evt) {

            evt.preventDefault();

            var commentItem = $(this).closest('li[comment-id]');

            var commentData = commentItem.data('commentData');

            if ((new Date()) - new Date(commentData.date) > 60 * 60 * 1000 - 5 * 60 * 1000) {

                $('<div />')
                    .addClass('alert')
                    .addClass('alert-danger')
                    .text('Комментарий не может быть отредактирован так как прошло более 60 минут с момента публикации')
                    .insertAfter(commentItem.children('.media').find('.comment-item__vote'))
                    .css('margin-top', '5px')
                    .fadeOut(3000, function () {
                        $(this).remove();
                    });

                return false;

            }


            //show preloader
            $(this).children('img').show();


            //set state
            state.editCommentID = commentItem.attr('comment-id') * 1;

            //check if user can edit comment
            commentsSocket.emit('check for editing', {
                commentID: state.editCommentID
            });

            $(this).parents('.dropdown').click();

            return false;
        });

        $(commentSystemContainer).on('click', '.comments-remove-button', function (evt) {

            evt.preventDefault();

            //show preloader
            $(this).children('img').show();

            var request = {

                commentID: $(this).parents('li[comment-id]').attr('comment-id')
            };


            commentsSocket.emit('remove comment', request);

            state.deletingComment = request.commentID;

            $(this).parents('.dropdown').click();

            return false;
        });

        $(commentSystemContainer).on('click', '.comment-ban-button', function (evt) {

            var self = $(this);
            var userID = self.closest('li[comment-id').attr('data-user-id');

            if(bans[userID]) {

                commentsSocket.emit('unban user',{ banUser: userID});

            } else {
                commentsSocket.emit('ban user',{ banUser: userID});
            }



            return false;

        });

        $(commentSystemContainer).on('click', '.comment-journal-ban-button', function (evt) {

            var self = $(this);


            var status = self.data('status');

            if (status == "banned") {

                $.ajax({
                    type: "POST",
                    global: false,
                    url: "/ajax.php",
                    data: ({
                        type: "j-unban-sub",
                        journal:postData.journal,
                        sub: self.closest('li[comment-id').attr('data-user-id')
                    }),
                    dataType: "html",
                    success: function (data) {

                        self.text('Забанить в журнале')
                    }
                });

            } else {

                $.ajax({
                    type: "POST",
                    global: false,
                    url: "/jr/ajax-jr.php",
                    data: ({
                        type: "j-ban-sub",
                        journal: postData.journal,
                        sub: self.closest('li[comment-id').attr('data-user-id')
                    }),
                    success: function (data) {
                        self.text('Разбанить в журнале')
                    }
                });

            }



            return false;

        });

        $(commentSystemContainer).on('click', '.comment-abuse-report-button', function (evt) {

            var $commentItem = $(this).closest('li[comment-id]');

            $('<div />')
                .addClass('alert')
                .addClass('alert-success')
                .text('Ваша жалоба отправлена.')
                .insertAfter($commentItem.children('.media').find('.comment-item__vote'))
                .css('margin-top', '5px')
                .fadeOut(3000, function () {
                    $(this).remove();
                });

            //send data
            commentsSocket.emit('abuse report', {commentID: $commentItem.attr('comment-id') * 1});

        });

        $(commentSystemContainer).on('click', '.comment-reply-button', function (evt) {

            if (!userData.id) {

                $('#top-login').click();
                return;
            }

            //get preloader
            var $preloader = $(this).children('img');

            //do not any actions if already loading
            if ($preloader.is(':visible')) return;

            //hide all others preloader
            $(commentSystemContainer).find('.comment-reply-button img').hide();

            //get comment item
            var $commentItem = $(this).closest('li[comment-id]');

            //send query for checking
            commentsSocket.emit('check for reply', {
                commentID: $commentItem.attr('comment-id')
            });

            //show our preloader
            $preloader.show();


        });

        $(commentSystemContainer).on('click', '.comment-button-like', function (evt) {

            if (!userData.id) {

                $('#top-login').click();
                return;
            }

            var $likeButton = $(this);
            var $comment = $likeButton.closest('li[comment-id]');
            var $commentBody = $comment.children('.media');
            var $likesContainer = $commentBody.find('.liked-user-list');
            var $likesBodyContainer = $likesContainer.find('.liked-user-list__body');
            var $commentItemVote = $likeButton.parent();

            var commentData = $comment.data('commentData');

            var prevStatus = $likeButton.data('status');

            //check if liked
            if ($likeButton.hasClass('comment-item__vote--pushed')) {


                //set status
                $likeButton.data('status', 'DISLIKED');


                //set commentData
                commentData.likes -= 1;

                //animation
                $likesBodyContainer.animate({'margin-left': '-45px'}, 200, function () {

                    $likesBodyContainer.children('a[data-like-user="' + userData.id + '"]').remove();
                    $likesBodyContainer.css('margin-left', '0px');

                    //hide likes container
                    if (!$likesBodyContainer.children().length) {
                        $likesContainer.hide();
                    }

                });


                //check if status is not set
                if (!prevStatus) {

                    commentsSocket.emit('dislike comment', {
                        commentID: $comment.attr('comment-id')
                    });

                }


            } else {

                //set status
                $likeButton.data('status', 'LIKED');

                //set commentData
                commentData.likes += 1;

                //TODO: add nickname
                var $element = $('<a />')
                    .append($('<img />')
                        .attr('src', '//cont.ws/uploads/users/' + userData.id + '.jpg')
                    )
                    .attr('data-like-user', userData.id)
                    .attr('title', '')
                    .attr('data-placement', 'top')
                    .attr('data-toggle', 'tooltip');

                //prepend element
                $element.prependTo($likesBodyContainer);

                //shift body container
                $likesBodyContainer.css('margin-left', '-45px');
                $likesBodyContainer.animate({'margin-left': '0px'}, 200);

                //start tooltip
                $element.tooltip();

                //show likes container
                if ($commentItemVote.data('hovered')) {
                    $likesContainer.show();
                }

                //check if status is not set
                if (!prevStatus) {

                    commentsSocket.emit('like comment', {
                        commentID: $comment.attr('comment-id')
                    });

                }

            }

            //enable/disable class
            $likeButton.toggleClass('comment-item__vote--pushed');
            $likeButton.find('.comment-like-counter').text(commentData.likes);

            //set updated data
            $comment.data('commentData', commentData);

            //init caption
            var caption = getNoun(commentData.likes, 'Одобрил ', 'Одобрили ', 'Одобрили ');

            //caption
            caption += commentData.likes;
            caption += getNoun(commentData.likes, ' человек', ' человека', ' человек')

            //set caption
            $likesContainer.find('strong').text(caption);


        });

        $(commentSystemContainer).on('click', '.comment-restore-button', function (evt) {

            evt.preventDefault();

            var commentID = $(this).closest('li[comment-id]').attr('comment-id');

            commentsSocket.emit('restore comment', {
                commentID: commentID
            });

            return false;


        });

        $(commentSystemContainer).on('mouseenter', '.comment-search', function (evt) {

            $(this).children('.media').eq(0).css('background','');
        });

        $(commentSystemContainer).on('mouseenter', '.comment-item__vote', function (evt) {


            $(this).data('hovered', true);

            var popUp = $(this).find('.liked-user-list');

            if (!popUp.find('.liked-user-list__body').children().length) return;
            clearTimeout(popUp.data('timeoutID') * 1);
            popUp.show();

        });


        $(commentSystemContainer).on('mouseenter', '.liked-user-list', function (evt) {

            evt.stopPropagation();

            clearTimeout($(this).data('timeoutID'));
            $(this).show();

        });

        $(commentSystemContainer).on('mouseleave', '.comment-item__vote', function (evt) {


            $(this).data('hovered', false);

            var popUp = $(this).find('.liked-user-list');

            popUp.data('timeoutID', setTimeout(function () {

                popUp.hide();
            }, 250));


        });

        $(commentSystemContainer).on('mouseleave', '.liked-user-list', function (evt) {

            evt.stopPropagation();

            var self = $(this);

            self.data('timeoutID', setTimeout(function () {

                self.hide();
            }, 250));

        });

        $(commentSystemContainer).on('click', '.comment-users-likes-button', function (evt) {

            var commentItem = $(this).closest('li[comment-id]');

            var likesCount = commentItem.children('.media').find('.comment-like-counter').text();

            $('#comments-likes-modal').find('.aggregation-modal__users').children().remove();
            $('#comments-likes-modal').find('.modal-title').html(getNoun(likesCount, 'Одобрил ', 'Одобрили ', 'Одобрили ') + likesCount + getNoun(likesCount, ' человек', ' человека', ' человек'));


            commentsSocket.emit('get comments likes', {
                commentID: commentItem.attr('comment-id')
            });

        });

        $(commentSystemContainer).on('click', '.comment-attachments a', function (evt) {

            var commentData = $(this).closest('li[comment-id]').data('commentData');

            $sImgMain.attr('src', $(this).find('img').attr('src'));
            $sOriginalLink.attr('href', $(this).find('img').attr('src'));
            $sUsername.attr('href', '//cont.ws/@' + commentData.commentAuthor.login);
            $sUsername.text(commentData.commentAuthor.nickname);
            $sDate.text(convertDate(new Date(commentData.date)));
            $sAuthorImg.attr('src', '/uploads/users/' + commentData.commentAuthor.id + '.jpg');
            $sImgModal.modal('show');

            return false;

        });

        $(commentSystemContainer).on('click', '.comment-date', function (evt) {
            copyToClipboard('https://cont.ws/post/' + postData.id + '#comment' + $(this).closest('li[comment-id]').attr('comment-id'));
            iziToast.success({
                title: 'Готово!',
                message: 'Ссылка на комментарий скопирована.',
            });

        });


    }


    function makeCommentItem(commentData, likesData, isNew,banes) {

        if(typeof premiumSettings != "undefined"
            &&  "hideBannedUsersComments" in premiumSettings
            && premiumSettings.hideBannedUsersComments &&
            (commentData && 'commentAuthor' in commentData && bans[commentData.commentAuthor.id])) {

            var commentItem = $('<li />').addClass('hidden');
            return commentItem;
        }

        if (!commentData.removed) {

            var commentAllowedActions = $('<li />');


            //check for undefined
            if (capabilities.postAuthorActions && commentData.commentAuthor.id !== userData.id) {

                commentAllowedActions.append($('<a />')
                    .addClass('comment-ban-button')
                    .attr('href', '#')
                    .text(!bans[commentData.commentAuthor.id] ? 'Забанить пользователя' : 'Разбанить пользователя')
                );

            }

            if (capabilities.journalActions && commentData.commentAuthor.id !== userData.id) {

                commentAllowedActions.append($('<a />')
                    .addClass('comment-journal-ban-button')
                    .attr('href', '#')
                    .data('status',journalBans[commentData.commentAuthor.id] ? 'banned' : 'unbanned')
                    .text(!journalBans[commentData.commentAuthor.id] ? 'Забанить в журнале' : 'Разбанить в журнале')
                );

            }

            if (commentData.commentAuthor.id == userData.id && !commentData.commentType) {

                commentAllowedActions
                    .append($('<a />')
                        .append($('<img />')
                            .attr('src', '/images/cont-preloader.svg')
                            .attr('width', '12')
                            .attr('height', '12')
                            .css('display', 'none')
                            .addClass('input_form-preloader')
                        )
                        .append('Редактировать')
                        .addClass('comments-edit-button')
                        .attr('href', '#')
                    );

            }

            if (commentData.commentAuthor.id == userData.id || capabilities.postAuthorActions || capabilities.moderatorActions || capabilities.journalActions) {

                commentAllowedActions.append($('<a />')
                    .append($('<img />')
                        .attr('src', '/images/cont-preloader.svg')
                        .attr('width', '12')
                        .attr('height', '12')
                        .css('display', 'none')
                        .addClass('input_form-preloader')
                    )
                    .append('Удалить')
                    .addClass('comments-remove-button')
                    .attr('href', '#')
                )

            }

            if (userData.id && userData.id != commentData.commentAuthor.id) {

                commentAllowedActions.append($('<a />')
                    .addClass('comment-abuse-report-button', '#')
                    .text('Пожаловаться')
                )

            }


            var attachments = $();

            if (commentData.attachments) {

                for (var i = 0; i < commentData.attachments.length; i++) {

                    attachments = attachments.add($('<a />')
                        .append($('<img />')
                            .attr('src', '/uploads/messages/' + commentData.attachments[i])
                            .addClass('img-responsive')
                        )
                        .attr('href', '#')
                    );

                }

            }

	    var canReply = !userBans.postAuthorBan && !userBans.journalBan;
        var $replyButtonReplace = $();

	    if (commentData.private) {
		    canReply = canReply && capabilities.premiumFollowerActions;
            $replyButtonReplace = $('<div class="tooltip-popup-white"><button class="btn btn-link" data-toggle="tooltip" data-trigger="click" data-placement="bottom" title="" data-original-title="Премиум-ветка означает, что отвечать на эти комментарии может либо автор, либо другие премиум-подписчики автора">Ответить</button></div>');
	    }

            var likesUsers = $();

            if (likesData && likesData[commentData.id]) {

                for (var i = 0; i < likesData[commentData.id].length; i++) {
                    likesUsers = likesUsers.add($('<a />')
                        .append($('<img />')
                            .attr('src', '//cont.ws/uploads/users/' + likesData[commentData.id][i].id + '.jpg')
                        )
                        .attr('data-like-user', likesData[commentData.id][i].id)
                        .attr('title', likesData[commentData.id][i].nickname)
                        .attr('data-placement', 'top')
                        .attr('data-toggle', 'tooltip')
                        .attr('data-container', 'body')
                    )
                }
            }

            var commentItem = $('<li />')
                .append($('<div />')
                    .append($('<div />')
                        .append($('<a />')
                            .append($('<figure />')
                                .append($('<img />')
                                    .attr('src', '/uploads/users/' + commentData.commentAuthor.id + '.jpg')
                                )
                            )
                            .attr('href', '//' + commentData.commentAuthor.login + '.cont.ws')
                        )
                        .addClass('media-top')
                        .addClass('media-left')
                    )
                    .append($('<div />')
                        .append($('<ul/>')
                            .append($('<li />')
                                .append($('<a />')
                                    .append($('<strong />')
                                        .text(commentData.commentAuthor.nickname)
                                    )
                                    .attr('href', '//cont.ws/@' + commentData.commentAuthor.login)
                                )
                                .append(
                                    commentData.toUser ? $('<small />')
                                        .text(' → ' + commentData.toUser)

                                        : $()
                                )
                            )
                            .append($('<li class="comment-date"/>')
                                .append($('<small />')
                                    .text(convertDate(new Date(commentData.date)))
                                )
                            )
                            .append(commentData.replies && commentData.private ? $('<li class="premium-thread-badge tooltip-popup-white"> <span data-toggle="tooltip" data-placement="bottom" title="" data-original-title="Премиум-ветка означает, что отвечать на эти комментарии может либо автор, либо другие премиум-подписчики автора">Премиум ветка</span></li>') : $())
                            .append(isNew ? $('<li />').append($('<span/>').addClass('label').text('новый!')) : $())
                            .append(commentAllowedActions.children().length > 0 ? $('<li />')
                                .append($('<div />')
                                    .append($('<a />')
                                        .append($('<small />')
                                            .append($('<i />')
                                                .attr('aria-hidden', true)
                                                .addClass('fa')
                                                .addClass('fa-ellipsis-h')
                                            )
                                        )
                                        .attr('href', '#')
                                        .attr('data-toggle', 'dropdown')
                                        .attr('aria-expanded', true)
                                        .addClass('dropdown-toggle')
                                        .addClass('btn')
                                        .addClass('btn-link')
                                        .addClass('hide_dots')
                                    )
                                    .addClass('dropdown')
                                    .append($('<ul />')
                                        .append(commentAllowedActions)
                                        .addClass('dropdown-menu')
                                        .addClass('dropdown-menu-right')
                                    )
                                )
                                .addClass('comment-options').addClass('pull-right') : $()
                            )
                            .addClass('list-inline')
                        )
                        .append($('<div />')
                            .html(nl2br(commentData.comment, false))
                            .addClass('comment-body')
                        )
                        .append($('<div />')
                            .append(attachments)
                            .addClass('comment-attachments')
                        )
                        .append(canReply ? $replyButton.clone() : $replyButtonReplace)
                        .append($('<div />')
                            .append($('<button />')
                                .addClass('btn')
                                .addClass('btn-link')
                                .addClass('comment-button-like')
                                .addClass(likesData && likesData[commentData.id] && likesData[commentData.id][0] && likesData[commentData.id][0].id == userData.id ? 'comment-item__vote--pushed' : '')
                                .append($('<small />')
                                    .append($('<i />')
                                        .addClass('glyphicon')
                                        .addClass('glyphicon-arrow-up')
                                        .attr('aria-hidden', true)
                                    )
                                )
                                .append($('<span />')
                                    .text(commentData.likes ? commentData.likes : '')
                                    .addClass('comment-like-counter')
                                )
                            )
                            .append($('<div />')
                                .append($('<p />')
                                    .append($('<a />')
                                        .addClass('comment-users-likes-button')
                                        .attr('href', '#')
                                        .attr('data-toggle', 'modal')
                                        .attr('data-target', '#comments-likes-modal')
                                        .append($('<strong />')
                                            .text(getNoun(commentData.likes, 'Одобрил ', 'Одобрили ', 'Одобрили ') + commentData.likes + getNoun(commentData.likes, ' человек', ' человека', ' человек'))
                                        )
                                    )
                                )
                                .append($('<div />')
                                    .append(likesUsers)
                                    .addClass('liked-user-list__body')
                                )
                                .addClass('liked-user-list')
                                .hide()
                            )
                            .append($('<div />')
                                .addClass('liked-user-list__arrow')
                            )
                            .addClass('pull-right')
                            .addClass('comment-item__vote')
                        )
                        .addClass('media-body')
                        .addClass('media-top')
                        .addClass('comment-item')
                    )
                    .addClass('media')
                )

            if(commentData.commentAuthor.premiumType > 5) commentItem.find('figure').prepend(premiumBorderHTMLComment);

            commentItem.attr('comment-author-login', commentData.commentAuthor.login);
            commentItem.attr('data-user-id', commentData.commentAuthor.id);


        } else {

            var commentItem = $('<li />')
                .append($('<p />')
                    .text('Комментарий удален')
                    .addClass('deleted-comment')
                );

        }

        if (!commentData.attachments || !commentData.attachments.length) {
            commentItem.find('.comment-attachments').hide();
        }

        commentItem.attr('comment-id', commentData.id);

        commentItem.data('commentData', commentData);


        var replies = $('<ul />').addClass('comment-replies');

        if (commentData.replies) {

            var repliesCount = !commentData.replies ? 0 : commentData.replies.length;

            //insert replies
            for (var i = 0; i < repliesCount; i++) {
		commentData.replies[i].private = commentData.private;
                replies.append(makeCommentItem(commentData.replies[i], likesData, new Date(commentData.replies[i].date) > lastPostVisit, bans));
            }

            //append more button
            if (commentData.hasMore) {


                replies.append($hasMoreRepliesButton.clone());
            }

            return commentItem.append(replies);


        }

        if(commentData.needMoreButton) {
            commentItem = $hasMoreRepliesButton.clone().add(commentItem);
        }


        return commentItem;


    }

    function initScrollEvents() {

        $(window).scroll(function () {

            var $unreadComments = $('.comment-unread');

            for (var i = 0; i < $unreadComments.length; i++) {

                if ($unreadComments.eq(i).visible(false)) {

                    $unreadComments.eq(i).removeClass('comment-unread')
                }

            }

            if ($(commentSystemContainer).visible(true) && state.newComments.length) {
                $('.comment-new-items').show();
            } else {
                $('.comment-new-items').hide();
            }

        });
    }

    $.fn.CommentsStart = function (postID, userID) {

        userData.id = userID;
        postData.id = postID;

        initializeSocketConnection();

    };

    $.fn.getSocket = function () {
        return commentsSocket;
    }

}(jQuery));
