/*******************************************************************************
                           НАСТРОЙКИ КОММЕНТАРИЕВ
*******************************************************************************/

	var comments_settings = new Array();

	//Путь к юзерпику, если пользователь не загрузил свой
	comments_settings["url_userpic"] = "/images/avatars/avatar_no_img_filmz.gif";

	//Ширина комментариев
	comments_settings["width"] = 965;

	//Отступ ответа от родительского сообщения
	comments_settings["parent_indent"] = 30;

	//PHP-скрипт, обрабатывающий AJAX-запросы
	comments_settings["ajax_handler_path"] = "/comments/user/ajax.php";

	//PHP-скрипт для управления комментариями не через AJAX
	comments_settings["none_ajax_handler_path"] = "/comments/user/form.php";

	// Список администраторов:
	comments_settings["admins"] = new Array();
	comments_settings["admins"][0] = 3;
	comments_settings["admins"][1] = 38;
	comments_settings["admins"][2] = 44;
	comments_settings["admins"][3] = 47;

	// Метки пользователей:
	comments_settings["labels"]                  = new Array();
	comments_settings["labels"]["base"]          = "";
	comments_settings["labels"]["admin"]         = "администратор";
	comments_settings["labels"]["moderator"]     = "модератор";
	comments_settings["labels"]["banned"]        = "забанен";
	comments_settings["labels"]["premoderation"] = "в премодерации";








/*******************************************************************************
                            ЗНАЧЕНИЯ ПО УМОЛЧАНИЮ
*******************************************************************************/

	//Открытая в данный момент форма ответа на комментарий
	//Может принимать следующие значения:
	//    -1: ни одна форма ответа не открыта
	//     0: открыта форма добавления нового комментария
	//     X: открыта форма ответа на комментарий X
	var current_reply_form_id = -1;





/*******************************************************************************
                 ДОПОЛНЕНИЕ К СТАНДАРТНЫМ ФУНКЦИЯМ JAVASCRIPT
*******************************************************************************/

//------------------------------------------------------------------------------
// trim
//------------------------------------------------------------------------------
//    Удаление из начала и конца строки лишних символов:
//    пробелов, переводов строк и т.п.
//------------------------------------------------------------------------------

function trim(s)
{
    //Удаляем лишние символы в начале строки
    result = s.replace(/^\s+/, '');
    //Удаляем лишние символы в конце строки
    result = result.replace(/\s+$/, '');

	return result;
}



//------------------------------------------------------------------------------
// insertAfter
//------------------------------------------------------------------------------
//    Почему-то отсутствующий в JavaScript аналог функции insertBefore,
//    только добавляющий новый узел в DOM-дерева после указанного, а не перед.
//
//    ПАРАМЕТРЫ:
//        parent - куда вставляем
//        node - что вставляем
//        referenceNode - после чего вставляем
//------------------------------------------------------------------------------
function insertAfter(parent, node, referenceNode)
{
	parent.insertBefore(node, referenceNode.nextSibling);
}



//------------------------------------------------------------------------------
// createDOMNode
//------------------------------------------------------------------------------
//    Создание нового узла в DOM-дереве
//    Возвращает созданный элемент
//
//    ПАРАМЕТРЫ:
//        tag - имя создаваемого элемента
//        className - class нового элемента
//        id - id нового элемента
//------------------------------------------------------------------------------
function createDOMNode(tag, className, id)
{	var newDOMNode = document.createElement(tag);
	if ( className )
	{
		newDOMNode.className = className;
	}
	if ( id )
	{
		newDOMNode.id = id;
	}

	return newDOMNode;
}



//------------------------------------------------------------------------------
// array_unique
//------------------------------------------------------------------------------
//    Аналог функции array_unique в PHP
//------------------------------------------------------------------------------
function array_unique( array )
{

    var p, i, j;
    for(i = array.length; i;){
        for(p = --i; p > 0;){
            if(array[i] === array[--p]){
                for(j = p; --p && array[i] === array[p];);
                i -= array.splice(p + 1, j - p).length;
            }
        }
    }

    return true;
}



//------------------------------------------------------------------------------
// in_array
//------------------------------------------------------------------------------
//    Аналог функции in_array в PHP
//------------------------------------------------------------------------------
function in_array(needle, haystack, strict)
{
    var found = false, key, strict = !!strict;
    for (key in haystack)
    {
        if ((strict && haystack[key] === needle) || (!strict && haystack[key] == needle))
        {
            found = true;
            break;
        }
    }
    return found;
}



//------------------------------------------------------------------------------
// dateFormat
//------------------------------------------------------------------------------
//    Форматирует дату и время для представления в комментариях
//    Возвращает строку типа: "31 декабря 2008 | 19:00"
//
//    ПАРАМЕТРЫ:
//        timestamp - метка времени UNIX (в секундах)
//------------------------------------------------------------------------------
function dateFormat(timestamp)
{

	if ( timestamp == 0 )
	{
		return "";
	}

	//Создаём новый объект Date
	//Метку времени умножаем на 1000, потому что JS в отличие
	//от PHP умеет оперировать только миллисекундами
	var d = new Date(timestamp * 1000);

	var result = "";

	result += d.getDate()  + " ";

	var monthes = new Array();
	monthes[0] = "января";
	monthes[1] = "февраля";
	monthes[2] = "марта";
	monthes[3] = "апреля";
	monthes[4] = "мая";
	monthes[5] = "июня";
	monthes[6] = "июля";
	monthes[7] = "августа";
	monthes[8] = "сентября";
	monthes[9] = "октября";
	monthes[10] = "ноября";
	monthes[11] = "декабря";

	result += monthes[ d.getMonth() ] + " ";

	result += d.getFullYear() + " | ";
	result += d.getHours() + ":";

	if ( d.getMinutes() < 10 )
	{
		result += "0" + d.getMinutes();
	}
	else
	{		result += d.getMinutes();
	}

	return result;
}



//------------------------------------------------------------------------------
// getSelectedText
//------------------------------------------------------------------------------
//    Получение выделенного на странице текста
//------------------------------------------------------------------------------
function getSelectedText()
{	if ( window.getSelection )
	{		return window.getSelection().toString();
	}
	else if ( document.getSelection )
	{		return document.getSelection();
	}
	else if ( document.selection )
	{		return document.selection.createRange().text;
	}
}





/*******************************************************************************
                             РАБОТА С BB-КОДАМИ
*******************************************************************************/

//------------------------------------------------------------------------------
// replaceBBCode
//------------------------------------------------------------------------------
//    Возвращает строку, в которое BB-коды заменены
//    соответствующими HTML-тегами
//
//    Заменяет следующиее BB-коды:
//        [b] => <b>
//        [i] => <i>
//        [u] => <u>
//        [url] => <a href=>
//        [url=] => <a href=>
//		  [quote] => <span class=comments_bbcode_quote>
//		  [spoiler] => <span class=comments_bbcode_spoiler>
//------------------------------------------------------------------------------
function replaceBBCode(s)
{
    result = s;

    //[b]...[/b]
    //Описание регулярного выражения:
    //код "[b]" потом любое количество пробелов илюбых символов,
    //потом закрывающий код "[/b]"
    result = result.replace(/\[b\](.*?)\[\/b\]/gi, "<b>$1</b>");

    //[i]...[/i]
    result = result.replace(/\[i\](.*?)\[\/i\]/gi, "<i>$1</i>");

    //[u]...[/u]
    result = result.replace(/\[u\](.*?)\[\/u\]/gi, "<u>$1</u>");

    //[strike]...[/strike]
    result = result.replace(/\[strike\](.*?)\[\/strike\]/gi, "<strike>$1</strike>");

    //[url]...[/url]
    result = result.replace(/\[url\](.*?)\[\/url\]/gi, "<a href=$1>$1</a>");

    //[url=...]...[/url]
    result = result.replace(/\[url=([^\]]*)\](.*?)\[\/url\]/gi, "<a href=$1>$2</a>");

    //[quote]...[/quote]
    result = result.replace(/\[quote\](.*?)\[\/quote\]/gi, "<div class=comments_bbcode_quote>$1</div>");

    //[spoiler]...[/spoiler]
    result = result.replace(/\[spoiler\](.*?)\[\/spoiler\]/gi, "<div class=comments_bbcode_spoiler><font color='#ff0000'>Спойлер!</font> $1</div>");

	return result;
}



//------------------------------------------------------------------------------
// insertBBCode
//------------------------------------------------------------------------------
//    Вставляет в форму ответа BB-коды
//------------------------------------------------------------------------------
function insertBBCode(current_textarea_id, bbcode_open, bbcode_close, insert_text)
{
	var t = document.getElementById("comment_reply_form_textarea_" + current_textarea_id);

	var open = bbcode_open;
	var close = bbcode_close;

	if (t.focus) t.focus();
	fTrans = function(t) { return trim(t); };

	var range = null;
	var text = null;

	// Find selection.
	if (document.getSelection) {
		// the Navigator 4.0x code
		text = document.getSelection();
	} else if (document.selection && document.selection.createRange) {
		// the Internet Explorer 4.0x code
		range = document.selection.createRange();
		text = range.text;
	} else {
		// the alternative code
		return false;
	}

	var notEmpty = text != null && text != '';

	// Surround.
	if (range) {
		var notEmpty = text != null && text != '';
		if ( insert_text != "" )
		{
			var newText = open + insert_text + (close? close : '');
		}
		else
		{			var newText = open + fTrans(text) + (close? close : '');
		}
		range.text = newText;
		range.collapse();
		if (text != '') {
			// Correction for stupid IE: \r for moveStart is 0 character.
			var delta = 0;
			for (var i=0; i<newText.length; i++) if (newText.charAt(i)=='\r') delta++;
			range.moveStart("character", -close.length-text.length-open.length+delta);
			range.moveEnd("character", -0);
		} else {
			range.moveEnd("character", -close.length);
		}
		range.select();
	} else if (t.setSelectionRange) {
		var start = t.selectionStart;
		var end = t.selectionEnd;
		var sel1 = t.value.substr(0, start);
		var sel2 = t.value.substr(end);
		var sel = fTrans(t.value.substr(start, end-start));
		if ( insert_text != "" )
		{
			t.value = sel1 + open + insert_text + close + sel2;
		}
		else
		{
			t.value = sel1 + open + sel + close + sel2;
		}
		if (sel != '') {
			t.setSelectionRange(start, start+open.length+sel.length+close.length);
			notEmpty = true;
		} else {
			t.setSelectionRange(start+open.length, start+open.length);
			notEmpty = false;
		}
	} else {

		if ( insert_text != "" )
		{		 	t.value += open + insert_text + close;
		}
		else
		{
			t.value += open+close;
		}
		notEmpty = false;
	}
	return notEmpty;
}



//------------------------------------------------------------------------------
// insertQuoteText
//------------------------------------------------------------------------------
//    Вставляет в форму ответа выделенный текст, обрамлённый
//    соответствующими BB-кодами
//------------------------------------------------------------------------------
function insertQuoteText(current_textarea_id)
{
	//Если на странице ничего не выделено, просто вставляем теги
	if ( getSelectedText() == "" )
	{
		insertBBCode(current_textarea_id, "[quote]", "[/quote]", "");
	}
	else
	{
    	insertBBCode(current_textarea_id, "[quote]", "[/quote]", trim( getSelectedText() ));
	}
}





/*******************************************************************************
                          ВЫВОД ИНФОРМАЦИИ В БРАУЗЕР
*******************************************************************************/

//------------------------------------------------------------------------------
// showMessage
//------------------------------------------------------------------------------
//    Вывод сообщения
//
//    ПАРАМЕТРЫ:
//        code - код сообщения:
//                   error - сообщение об ошибке
//                   info - информационное сообщение
//        text - текст сообщения
//------------------------------------------------------------------------------
function showMessage(code, text)
{	//Удаляем со страницы все сообщения
	document.getElementById("comments_message").innerHTML = "";

	//Добавляем DIV c заголовком сообщения
	var newMessageHeader = createDOMNode("div", "message_header", "message_header");

	if ( code == "error" )
	{
    	newMessageHeader.innerHTML = "Ошибка";
	}
	else if ( code == "info" )
	{		newMessageHeader.innerHTML = "Сообщение";
	}
    document.getElementById("comments_message").appendChild(newMessageHeader);

 	//Добавляем DIV c текстом сообщения
	var newMessageText = createDOMNode("div", "message_text", "message_text");
   	newMessageText.innerHTML = text;
    document.getElementById("comments_message").appendChild(newMessageText);

}



//------------------------------------------------------------------------------
// showTreeComments
//------------------------------------------------------------------------------
//    Вывод дерева комментариев или добавление узлов в выведенное дерево
//    Дерево передаётся в виде массива tree
//------------------------------------------------------------------------------
function showTreeComments(tree)
{
	//Проходим по всем элементам дерева комментариев
    for (node in tree)
	{
		//Вытаскиваем сведения о комментарии в отдельные переменные
		var id         = tree[node]["id"];
        var user_id    = tree[node]["user_id"];
        var parent_id  = tree[node]["parent_id"];
        var level      = tree[node]["level"];
        var path       = tree[node]["path"];
        var date       = tree[node]["date"];
        var username   = tree[node]["username"];
        var userpic    = tree[node]["userpic"];
        var user_label = tree[node]["user_label"];
        var text       = tree[node]["text"];

		//Если нужно отобразить не всё дерево, а его ветвь
		if ( comments_service["comment_id"] != 0 )
		{
			//Получаем путь верхнего узла нужной ветви
			var path_array = getArrayFromCommentPath(  getCommentPathById(comments_service["comment_id"])  );

			//Если у требуемой ветви нулевой уровень, то ничего делать не надо
			if ( path_array.length != 1 )
			{
				//Вычисляем уровни, относительно ветви, а не всего дерева
				level = level - ( path_array.length - 1 );

				//Отщепляем от пути лишние ветви, которые не будут отображены
				path_array.pop();
				path_minus = path_array.join(":") + ":";
				path = path.substring(path_minus.length);
			}
		}

		// Проверяем поле ID, потому что иногда попадаются служебные
		// данные внутренней организации JavaScript в разных браузерах
		if ( id )
		{
		    //Выводим комментарий на страницу
            addComment(id, user_id, parent_id, level, path, date, username, userpic, user_label, text);
        }
	}
}



//------------------------------------------------------------------------------
// addComment
//------------------------------------------------------------------------------
//    Вывод конкретного комментария на страницу (создание нового DOM-узла)
//
//    ПАРАМЕТРЫ:
//               id - ID комментария
//          user_id - ID пользователя, который написал комментарий
//        parent_id - ID родительского комментария
//                    (или ноль, если родителя нет)
//            level - уровень вложенности комментария (от нуля и выше)
//             path - полный путь к комментарию в базе
//                    (называется Materialized Path)
//             date - дата добавления комментария в UNIX-формате
//         username - имя пользователя, оставившего комментарий
//          userpic - расширение файла с юзерпиком автора комментария
//                    (если пустая строка, то юзерпика нет)
//             text - текст комментария
//------------------------------------------------------------------------------
function addComment(id, user_id, parent_id, level, path, date, username, userpic, user_label, text)
{
    if ( user_label != "admin" && user_label != "moderator" )
    {    	admin_comment = false;
    }
    else
    {    	admin_comment = true;
    }

	var path_array = getArrayFromCommentPath(path);

	//Создаём общий DIV для комментария
	if ( admin_comment )
	{
        var newComment = createDOMNode("div", "comment_admin", "comment_" + id);
 	}
	else
	{	    var newComment = createDOMNode("div", "comment", "comment_" + id);
	}

	//Устанавливаем ширину комментария в зависимости от его уровня и
	//заданных параметров (общая ширина поля для комментариев и
	//величина отступа ответа от родительского комментария)    if ( level >= 10 )
    {    	var comment_width = comments_settings["width"] - ( comments_settings["parent_indent"] * 10 );
    }
    else
    {    	var comment_width = comments_settings["width"] - ( comments_settings["parent_indent"] * level );
    }
    newComment.style.width = comment_width + "px";

	//Определяем положение новосозданного комментария на странице:
	//Если родителя нет, то просто выводим его в конец DIV'а с комментариями
	if ( path_array.length == 1 )
	{
		document.getElementById("comments").appendChild(newComment);
	}
	//Если родитель есть, то комментарий нужно поставить после самого нижнего
	//комментария, в ветке этого родителя
	else
	{
	    p_id = getLastNodeID_DOM( getParentFromPath(path) );
		insertAfter(document.getElementById("comments"), newComment, document.getElementById("comment_" + p_id));
	}

    //ЮЗЕРПИК:
    //Создаём DIV c юзерпиком:
	var newCommentUserpic = createDOMNode("div", "comment_userpic", "comment_userpic_" + id);

	//Если у юзерпика есть расширение, то генерируем код картинки,
	//иначе ставим общий юзерпик (задаётся в настройках)
	if ( userpic != "" )
	{
		newCommentUserpic.innerHTML = "<img class=comment_userpic_img src=http://media.filmz.ru/users/userpics/" + user_id + "." + userpic + ">";
	}
	else
	{
		newCommentUserpic.innerHTML = "<img class=comment_userpic_img src=" + comments_settings["url_userpic"] + ">";
	}

	//Размещаем юзерпик на странице в DIV'е комментария
	document.getElementById("comment_" + id).appendChild(newCommentUserpic);


	//ИНФОРМАЦИОННОЕ ПОЛЕ
    //Создаём DIV с информационным полем cо сведениями о комментарии
    var newCommentInfo = createDOMNode("div", "comment_info", "comment_info_" + id);
	document.getElementById("comment_" + id).appendChild(newCommentInfo);

	//Добавляем в информационное поле SPAN c именем пользователя
	if ( admin_comment )
	{        var newCommentInfoUsername = createDOMNode("span", "comment_info_username_admin", "comment_info_username_" + id);	}
	else
	{        var newCommentInfoUsername = createDOMNode("span", "comment_info_username", "comment_info_username_" + id);
	}
    newCommentInfoUsername.innerHTML = "<a href=/moviegoers/" + user_id + "/>" + username + "</a>";
    newCommentInfoUsername.innerHTML = newCommentInfoUsername.innerHTML + "<sup>" + comments_settings["labels"][user_label] + "</sup>";

    document.getElementById("comment_info_" + id).appendChild(newCommentInfoUsername);

	//Добавляем перенос строки после имени пользователя
	//var newCommentInfoUsernameBR = createDOMNode("br");
    //document.getElementById("comment_info_" + id).appendChild(newCommentInfoUsernameBR);

	//Добавляем в информационное поле SPAN c датой добавления комментария
	var newCommentInfoDate = createDOMNode("span", "comment_info_date", "comment_info_date_" + id);
    newCommentInfoDate.innerHTML = dateFormat(date);
    document.getElementById("comment_info_" + id).appendChild(newCommentInfoDate);


    //ТЕКСТ КОММЕНТАРИЯ
    //Создаём DIV c текстом комментария
	var newCommentText = createDOMNode("div", "comment_text", "comment_text_" + id);
    //Не забываем обработать текст на BB-коды
    newCommentText.innerHTML = replaceBBCode(text);
	document.getElementById("comment_" + id).appendChild(newCommentText);


	//ССЫЛКИ, ОБСЛУЖИВАЮЩИЕ КОММЕНТАРИЙ
	var newCommentLinks = createDOMNode("div", "comment_links", "comment_links_" + id);
	var arrLinks = new Array();
	arrLinks.push("<a href=# OnClick='showCommentReplyForm(" + id + "); return false;'>Ответить</a>");
	arrLinks.push("<a href=# OnClick='postCommentsThread(" + id + "); return false;'>Ветвь комментариев</a>");

	//Если отображаем только одну ветвь, а не всё дерево,
	//то у верхнего комментария ставим ссылку "Уровень выше"
	if ( comments_service["comment_id"] != 0 && level == 0 )
	{		//Если у текущего комментария нет родителя, то
		//ссылка "Уровень выше" ведёт на все комментарии
		if  ( parent_id == 0 )
		{			arrLinks.push("<a href=# OnClick='postCommentsThread(0); return false;'>Все комментарии</a>");
		}
		else
		{			arrLinks.push("<a href=# OnClick='postCommentsThread(" + parent_id + "); return false;'>Уровень выше</a>");
		}
	}
	arrLinks.push("<a href=?comment_id=" + id + "#comments>Ссылка</a>");
	arrLinks.push("<a href=/moviegoers/profile/messages/write/?user_id=" + user_id + ">Отправить личное сообщение</a>");

	//Если пользователь является администратором,
	//то выводим дополнительные ссылки
	comments_settings["labels"]["admin"]         = "администратор";
	comments_settings["labels"]["moderator"]     = "модератор";

	if ( in_array(comments_service["user_login"], comments_settings["admins"]) )
	{        arrLinks.push("<a href=http://www.filmz.ru/admin/comments/?comment_id=" + id + ">Редактировать</a>");
	}

    newCommentLinks.innerHTML = arrLinks.join(" | ");
	document.getElementById("comment_" + id).appendChild(newCommentLinks);

	//Добавляем добавленный комментарий в массив,
	//дублирующий DOM-дерево комментариев
	comments_dom[ comments_dom.length ] = path;
}



//------------------------------------------------------------------------------
// hideAllReplyForms
//------------------------------------------------------------------------------
//    Скрывает со страницы все формы добавления комментария,
//    присваивая их DIV'у стиль "display: none"
//------------------------------------------------------------------------------
function hideAllReplyForms()
{
	//Получаем все DIV'ы, относящиеся к комментариям и проходим по ним
	var comments = document.getElementById("comments").getElementsByTagName("div");

	for ( var i = 0; i < comments.length; i++ )
	{
		//Если встреченный DIV содержит форму для ответа, то скрываем его
		if ( comments[i].className == "comment_reply" )
		{
			comments[i].style.display = "none";
		}
	}

	//Также скрываем форму добавления нового комментария
	//(если она, конечно, существует)
	if ( document.getElementById("comment_reply_0") != undefined )
	{
		document.getElementById("comment_reply_0").style.display = "none";
	}
}



//------------------------------------------------------------------------------
// showCommentsPages
//------------------------------------------------------------------------------
//    Создаёт или обновляет указатель страниц
//------------------------------------------------------------------------------
function showCommentsPages(count)
{
	//Если выводится не дерево, а отдельная ветвь
	if ( comments_service["comment_id"] != 0 )
	{
		comments_pages_text = "<center><a href=? OnClick='postCommentsPage(" + comments_service["current_page"] + "); return false;'>Перейти к комментариям</a></center>";
		document.getElementById("comments_pages_1").innerHTML = comments_pages_text; //Верхний указатель
		document.getElementById("comments_pages_2").innerHTML = comments_pages_text; //Нижний указатель
		return;
	}

	//Если комментариев вообще нет, скрываем указатель страниц
	if ( count == 0 )
	{
		document.getElementById("comments_pages_1").style.display = "none"; //Верхний указатель
		document.getElementById("comments_pages_2").style.display = "none"; //Нижний указатель
		return;
	}

	//НАСТРОЙКИ:
	var frame = 3; //число обрамления (количество страниц в каждом блоке
	               //разделенных разделителем и текущей страницей):

	var current = Number( comments_service["current_page"] );

	var first = new Array();
	var before = new Array();
	var after = new Array();
	var last = new Array();
	var pages = new Array();

	//Создание четырёх блоков:
	//1 (first):  от первой страницы
	//2 (before): до текущей
	//3 (after):  после текущей
	//4 (last):   перед последней
	for ( var i = 1; i <= frame; i++ )
	{
    	first[first.length] = i;
    	before[before.length] = current - ( ( frame - i ) + 1 );
    	after[after.length] = current + i;
    	last[last.length] = count - ( frame - i );
	}

	//СОЗДАНИЕ ПЭЙДЖИНАТОРА

	//Сначала пишем первый блок
	for ( i = 1; i <= frame; i++ )
	{
		pages[pages.length] = first[i-1];
	}

	//Смотрим нужен ли разделитель между первым и вторым блоком и ставим его
	if ( ( before[0] - first[frame-1] ) > 1 )
	{
		pages[pages.length] = "bar_before";
	}

	//Заполняем второй блок:
	for ( i = 1; i <= frame; i++ )
	{
		pages[pages.length] = before[i-1];
	}

	//Дошли до текущей страницы, отмечаем её:
	pages[pages.length] = current;

	//Заполняем третий блок:
	for ( i = 1; i <= frame; i++ )
	{
		pages[pages.length] = after[i-1];
	}

	//смотрим нужен ли разделитель перед четвёртым блоком
	if ( ( last[0] - after[frame-1] ) > 1 )
	{
		pages[pages.length] = "bar_after";
	}

	//заполняем последний, четвёртый, блок
	for ( i = 1; i <= frame; i++ )
	{
		pages[pages.length] = last[i-1];
	}

	//убираем повторяющиеся значения
	array_unique(pages);

	var pages_final = new Array();

	//убираем из ряда отрицательные значения, ноль и те,
	//которые больше общего количества страниц, а также
	//приводим к причёсанному виду c отмеченной текущей
	//страницей
	for (key in pages)
	{
		switch ( pages[key] )
		{
			case 'bar_before':
		    	pages_final[pages_final.length] = 'bar';
		    	break;
			case 'bar_after':
		    	pages_final[pages_final.length] = 'bar';
		    	break;
			case 'current':
		    	pages_final[pages_final.length] = 'current';
		    	break;
			default:
				if ( ( pages[key] > 0 ) && ( pages[key] <= count ) )
				{
					if ( pages[key] != current )
					{
						pages_final[pages_final.length] = pages[key];
					}
					else
					{
						pages_final[pages_final.length] = 'current';
					}
				}
		}
	}

	var result = '';

	result += "<table border=0 cellspacing=1 cellpadding=2 width=100%>";
	result += "<tr><td width=180>";

	if ( current != 1 )
	{
		result += "<a href=#commentlist OnClick='postCommentsPage(" + ( current - 1 ) + "); //return false;'>Предыдущая страница</a>";
	}

	result += "</td><td width=7></td>";
	result += "<td align=center><b>";

	for ( var i = 0; i < pages_final.length; i++ )
	{
		//Если страница первая или последняя
		if ( i == 0 || i == pages_final.length )
		{			//Если страница текущая, то её не надо делать ссылкой
			if ( pages_final[i] == 'current' )
			{
				result += "<span class=comments_pages_extreme><span class=comments_pages_current>" + current + "</span></span>";
			}
			else
			{
				result += "<span class=comments_pages_extreme><a href=#commentlist OnClick='postCommentsPage(" + pages_final[i] + "); //return false;'>" + pages_final[i] + "</a></span>";
			}
		}
		else if ( pages_final[i] == 'bar' )
		{
			result += "<b>...</b>&nbsp";
		}
	    else
	    {
			if ( pages_final[i] == 'current' )
			{
		    	result += "<span class=comments_pages_page><span class=comments_pages_current>" + current + "</span></span>";
			}
			else
			{
		    	result += "<span class=comments_pages_page><a href=#commentlist OnClick='postCommentsPage(" + pages_final[i] + "); //return false;'>" + pages_final[i] + "</a></span>";
			}
		}

		//Ставим пробелы после каждого номера, за исключением последнего
		if ( i != pages_final.length )
		{
			result += "&nbsp;";
		}

	}

	result += "</b></td>";
	result += "<td width=7></td><td align=right width=180>";

	if ( current != count )
	{
		result += "<a href=#commentlist OnClick='postCommentsPage(" + ( Number(comments_service["current_page"]) + 1 ) + "); //return false;'>Следующая страница</a>";
	}
	result += "</td></tr>";
	result += "</table>";

	document.getElementById("comments_pages_1").innerHTML = result; //Верхний указатель
	document.getElementById("comments_pages_2").innerHTML = result; //Нижний указатель
}



//------------------------------------------------------------------------------
// showCommentsHeadline
//------------------------------------------------------------------------------
//    Вывод заголовка комментариев
//------------------------------------------------------------------------------
function showCommentsHeadline(count)
{
	a = count.toString();

	//Получаем два последних символа
	a = a.substring(a.length - 2);

	if ( a == "11" || a == "12" || a == "13" || a == "14" )
	{		document.getElementById("comments_headline").innerHTML = count + " комментариев";
		return;
	}

	//Получаем последний символ
	a = a.substring(  a.length - 1  );

	if ( a == "1" )
	{		document.getElementById("comments_headline").innerHTML = count + " комментарий";
		return;
	}
	else if ( a == "2" || a == "3" || a == "4" )
	{		document.getElementById("comments_headline").innerHTML = count + " комментария";
		return;
	}
	else if ( a == "5" || a == "6" || a == "7" || a == "8" || a == "9" || a == "0"  )
	{
		document.getElementById("comments_headline").innerHTML = count + " комментариев";
		return;
	}
	else
	{		document.getElementById("comments_headline").innerHTML = "Комментарии (" + count + ")";
		return;
	}


}





/*******************************************************************************
                              РЕАКЦИЯ НА СОБЫТИЯ
*******************************************************************************/

//------------------------------------------------------------------------------
// processCommentsAfterDocumentLoad
//------------------------------------------------------------------------------
//    Самые первые действия с комментариями,
//    совершаемые после загрузки страницы в браузере
//------------------------------------------------------------------------------
function processCommentsAfterDocumentLoad()
{

	showCommentsPages(  comments_service["count_pages"]  );
	showCommentsHeadline(  comments_count  );

	//Если у записи нет комментариев, то открываем форму добавления нового
	if ( comments_service["count_pages"] == 0 )
	{
		showCommentReplyForm(0);
	}
	//Если у записи есть комментарии, то выводим их в браузер
	else
	{
		//Выводим дерево комментариев в браузер
		showTreeComments(comments);
	}
}



//------------------------------------------------------------------------------
// processCommentsAfterDocumentLoad
//------------------------------------------------------------------------------
//    Отображение формы добавления комментария, после того как пользователь
//    кликнул по ссылке "Ответить" или "Новый комментарий"
//    Принимает ID комментария, на который отвечают
//------------------------------------------------------------------------------
function showCommentReplyForm(id)
{

    //Проверяем существует ли уже форма ответа для данного комментария
	//Если не существует, то создаём её
	if ( ! document.getElementById("comment_reply_" + id) )
    {
        //Создание DIV'а формы ответа на комментарий
		var newCommentReply = document.createElement("div");
		newCommentReply.className = "comment_reply";
	    newCommentReply.id = "comment_reply_" + id;
	    newCommentReply.style.display = "none";
		if ( id == 0 )
		{
			document.getElementById("comments_new").appendChild(newCommentReply);
		}
		else
		{
			document.getElementById("comment_" + id).appendChild(newCommentReply);
		}

		//Создание формы для ответа
		var newCommentReplyForm = document.createElement("form");
		newCommentReplyForm.className = "comment_reply_form";
	    newCommentReplyForm.id = "comment_reply_form_" + id;
	    newCommentReplyForm.name = "comment_reply_form_" + id;
	    newCommentReplyForm.method = "POST";
	    document.getElementById("comment_reply_" + id).appendChild(newCommentReplyForm);

	    //Если пользователь не залогинен, то вместе с полем комментария выводим
	    //форму авторизации
	    if ( comments_service["user_login"] == 0 )
	    {
			newCommentReplyForm.action = comments_settings["none_ajax_handler_path"] + "?action=add";
			newCommentReplyForm.innerHTML = document.getElementById("comment_reply_form_authorization_prototype").innerHTML;
	    }

		//Создание DIV'а c кнопками BB-кодов:
		var newCommentReplyFormBBCode = document.createElement("span");
		newCommentReplyFormBBCode.className = "comment_reply_form_bbcode";
	    newCommentReplyFormBBCode.id = "comment_reply_form_bbcode_" + id;
	    newCommentReplyFormBBCode.innerHTML = document.getElementById("comment_reply_form_bbcode_prototype").innerHTML;
	    document.getElementById("comment_reply_form_" + id).appendChild(newCommentReplyFormBBCode);

	    //Создание текстового поля для ответа:
		var newCommentReplyFormTextarea = document.createElement("textarea");
		newCommentReplyFormTextarea.className = "comment_reply_form_textarea";
	    newCommentReplyFormTextarea.id = "comment_reply_form_textarea_" + id;
	    newCommentReplyFormTextarea.rows = 10;
	    newCommentReplyFormTextarea.style.width = "100%";
	    newCommentReplyFormTextarea.name = "text";
	    document.getElementById("comment_reply_form_" + id).appendChild(newCommentReplyFormTextarea);

	    //Создание скрытого поля с ID родительского каммента:
		var newCommentReplyFormInputParent = document.createElement("input");
	    newCommentReplyFormInputParent.id = "comment_reply_form_input_parent_" + id;
	    newCommentReplyFormInputParent.name = "parent_id";
	    newCommentReplyFormInputParent.type = "hidden";
	    newCommentReplyFormInputParent.value = id;
	    document.getElementById("comment_reply_form_" + id).appendChild(newCommentReplyFormInputParent);

	    //Создание скрытого поля с именем категории:
		var newCommentReplyFormInputCategory = document.createElement("input");
	    newCommentReplyFormInputCategory.id = "comment_reply_form_input_category_" + id;
	    newCommentReplyFormInputCategory.name = "category";
	    newCommentReplyFormInputCategory.type = "hidden";
	    newCommentReplyFormInputCategory.value = comments_service["category"];
	    document.getElementById("comment_reply_form_" + id).appendChild(newCommentReplyFormInputCategory);

	    //Создание скрытого поля с номером статьи:
		var newCommentReplyFormInputArticle = document.createElement("input");
	    newCommentReplyFormInputArticle.id = "comment_reply_form_input_article_" + id;
	    newCommentReplyFormInputArticle.name = "article_id";
	    newCommentReplyFormInputArticle.type = "hidden";
	    newCommentReplyFormInputArticle.value = comments_service["article_id"];
	    document.getElementById("comment_reply_form_" + id).appendChild(newCommentReplyFormInputArticle);

	    //Создание кнопки Отправить:
		var newCommentReplyFormInputSubmit = document.createElement("input");
		newCommentReplyFormInputSubmit.className = "comment_reply_form_input_submit";
	    newCommentReplyFormInputSubmit.id = "comment_reply_form_input_submit_" + id;
	    newCommentReplyFormInputSubmit.type = "submit";
	    newCommentReplyFormInputSubmit.value = "Отправить";
	   	if ( comments_service["user_login"] != 0 )
	    {
	    	newCommentReplyFormInputSubmit.onclick = function() { postCommentReply(); return false; }
		}
	    document.getElementById("comment_reply_form_" + id).appendChild(newCommentReplyFormInputSubmit);

	    //Создание скрытого элемента с анимированным GIF'ом:
		var newCommentReplyFormSpanLoading = createDOMNode("span", "comment_reply_form_span_loading", "comment_reply_form_span_loading_" + id);
	    newCommentReplyFormSpanLoading.innerHTML = "&nbsp;<img src=/images/ajax_commentpost_loading.gif>";
		newCommentReplyFormSpanLoading.style.display = "none";
	    document.getElementById("comment_reply_form_" + id).appendChild(newCommentReplyFormSpanLoading);
	}

	//Если DIV с формой скрыт (по умолчанию),
	//то показываем его, иначе скрываем
	if ( document.getElementById("comment_reply_" + id).style.display == "none" )
	{
		hideAllReplyForms();
		document.getElementById("comment_reply_" + id).style.display = "";
		current_reply_form_id = id;
	}
	else
	{
		document.getElementById("comment_reply_" + id).style.display = "none";
		current_reply_form_id = -1;
	}
}





/*******************************************************************************
                        ВЗАИМОДЕЙСТВИЕ С СЕРВЕРОМ
*******************************************************************************/

//------------------------------------------------------------------------------
// postCommentReply
//------------------------------------------------------------------------------
//    Отправка на сервер нового комментарий
//------------------------------------------------------------------------------
function postCommentReply()
{

    document.getElementById("comment_reply_form_" + current_reply_form_id).disabled = true;
    document.getElementById("comment_reply_form_span_loading_" + current_reply_form_id).style.display = "inline";

    //Отправляем комментарий на указанный URL из открытой, в данный момент,
    //формы ответа, данные которой предвартиельно переведены в строку.
    //Ответ сервера передаём функции responseCommentReply
    ajaxPOSTRequest
    (
        comments_settings["ajax_handler_path"] + "?action=add",
        formToString(document.forms["comment_reply_form_" + current_reply_form_id]),
        responseCommentReply
    );
}



//------------------------------------------------------------------------------
// responseCommentReply
//------------------------------------------------------------------------------
//    Функция, принимающая ответ от сервера после отправки
//    комментария функцией postCommentReply
//    От сервера приходит массив с новым комментарием comment и
//    служебный массив comments_service
//------------------------------------------------------------------------------
function responseCommentReply(result)
{
	eval( result );

	//Если не возникло никаких ошибок и комментарий был успешно добавлен
	if ( comments_service["error"] == "error_none" )
    {
    	//Скрываем все формы добавления комментария
    	hideAllReplyForms();

    	//Если количество комментариев увеличилось больше, чем на один или
    	//комментарий был добавлен на одну страницу, а пользователь
    	//находится на другой, значит обновляем всё
    	if
    	(
    		( ( Number(comments_count) + 1 ) < comments_service["count_comments"] ) ||
    		( comments_current_page != comments_service["current_page"] )
    	)
    	{
    		//Заново открываем страницу с добавленным комментарием
    		postCommentsPage(comments_service["current_page"]);
    	}
    	else
	    {
	       	showCommentsPages(comments_service["count_pages"]);
	       	showTreeComments(comment);
    	}

		//Обновляем количество комментариев:
		comments_count = comments_service["count_comments"];
		showCommentsHeadline(  comments_count  );

		showMessage("info", "Ваш комментарий успешно добавлен");

	}
    else
    {
		showMessage("error", "Возникла какая-то ошибка при отправке ответа: " + comments_service["error"]);
    }

    document.getElementById("comment_reply_form_" + current_reply_form_id).disabled = false;
    document.getElementById("comment_reply_form_span_loading_" + current_reply_form_id).style.display = "none";
}



//------------------------------------------------------------------------------
// postCommentsPage
//------------------------------------------------------------------------------
//    Отправка номера страницы на сервер для получения её дерева комментариев
//------------------------------------------------------------------------------
function postCommentsPage(page)
{

	//Генерируем строку запроса
	var querystring = "action=tree&category=" + comments_service["category"] + "&article_id=" + comments_service["article_id"] + "&page=" + page;

	//Делаем запрос на сервер, а ответ передаём функции responseCommentsPage
	ajaxGETRequest
	(
	    comments_settings["ajax_handler_path"],
	    querystring,
	    responseCommentsPage
	);
}



//------------------------------------------------------------------------------
// responseCommentsPage
//------------------------------------------------------------------------------
//    Функция, принимающая ответ от сервера после отправки
//    номера страницы функцией postCommentsPage
//    От сервера приходит новый массив комментариев для заданной страницы и
//    служебный массив comments_service
//------------------------------------------------------------------------------
function responseCommentsPage(result)
{
	//Выполняем ответ сервера
	eval(result);

	comments_count = comments_service["count_comments"];

	comments_dom = new Array();

	//Удаляем со страницы все комментарии
	document.getElementById("comments").innerHTML = "";

	//Обновляем номер текущей страницы
	comments_current_page = comments_service["current_page"];

	//Обновляем указатель страниц
	showCommentsPages(comments_service["count_pages"]);

	//Обновляем заголовок комментариев с их количеством
	showCommentsHeadline(  comments_count  );

	//Показываем новое дерево
	showTreeComments(comments);
}




//------------------------------------------------------------------------------
// postCommentsThread
//------------------------------------------------------------------------------
//    Отправка на сервер сведений о ветви, которую нужно вывести
//------------------------------------------------------------------------------
function postCommentsThread(comment_id)
{

	//Генерируем строку запроса
	var querystring = "action=thread&category=" + comments_service["category"] + "&article_id=" + comments_service["article_id"] + "&page=" + comments_service["current_page"] + "&comment_id=" + comment_id;

	//Делаем запрос на сервер, а ответ передаём функции responseCommentsThread
	ajaxGETRequest
	(
	    comments_settings["ajax_handler_path"],
	    querystring,
	    responseCommentsThread
	);
}



//------------------------------------------------------------------------------
// responseCommentsThread
//------------------------------------------------------------------------------
//    Функция, принимающая ответ от сервера после отправки
//    сведений о ветви функцией postCommentsThread
//    От сервера приходит новый массив комментариев с заданной веткой и
//    служебный массив comments_service
//------------------------------------------------------------------------------
function responseCommentsThread(result)
{

	//Выполняем ответ сервера
	eval(result);

	comments_count = comments_service["count_comments"];

	comments_dom = new Array();

	//Удаляем со страницы все комментарии
	document.getElementById("comments").innerHTML = "";

	//Обновляем номер текущей страницы
	comments_current_page = comments_service["current_page"];

	//Обновляем указатель страниц
	showCommentsPages(comments_service["count_pages"]);

	//Обновляем заголовок комментариев с их количеством
	showCommentsHeadline(  comments_count  );

	//Показываем новое дерево
	showTreeComments(comments);
}





/*******************************************************************************
                              РАБОТА С ДЕРЕВОМ
*******************************************************************************/

//------------------------------------------------------------------------------
// getParentFromPath
//------------------------------------------------------------------------------
//    Получение пути родительского элемента из пути заданного
//------------------------------------------------------------------------------

function getParentFromPath(s)
{
	//Извлекаем из пути подстроку без последнего элемента
	return s.substring(0, s.lastIndexOf(":"));
}



//------------------------------------------------------------------------------
// getCommentPathById
//------------------------------------------------------------------------------
//    Получение пути комментария по его id из массива comments
//------------------------------------------------------------------------------

function getCommentPathById(id)
{
	for ( key in comments )
	{		if ( comments[key]["id"] == id )
		{			return comments[key]["path"];
		}
	}
	return false;
}



//------------------------------------------------------------------------------
// getArrayFromCommentPath
//------------------------------------------------------------------------------
//    Получение массива из пути
//------------------------------------------------------------------------------

function getArrayFromCommentPath(path)
{
	return path.split(":");
}



//------------------------------------------------------------------------------
// getLastNodeID_DOM
//------------------------------------------------------------------------------
//    Найти в заданной ветке самый нижний выведенный комментарий
//    Поиск производится путём сравнения путей между собой и выбор
//    пути с самым последним комментарием
//------------------------------------------------------------------------------

function getLastNodeID_DOM(parent_path)
{
	//Массив, в котором будет хранится максимальная ветка
	var max = new Array();

	//Для начала сделаем его из пути ролителя
	max = getArrayFromCommentPath(parent_path);

	max_length = max.length;

	var current = new Array();
	var i = 0;

	//Идём по всем записям в массиве выведенных комментариев
	//for ( key in comments_dom )
	for ( var key = 0; key < comments_dom.length; key++ )
	{
		//Рассматриваем только комментарии, относящиеся
		//к данному родительскому элементу
		if ( comments_dom[key].indexOf(parent_path + ":") == 0 )
		{
            current = getArrayFromCommentPath(comments_dom[key]);

            //Делаем так, чтобы количество элементов в массиве max было равно
            //количеству элементов в массиве текущей ветки
            if ( max.length < current.length )
            {
				for ( i = max.length; i < current.length; i++ )
				{
				    max[i] = 0;
				}
            }

            //Сравниваем пути по каждому элементу и тот,
            //что старше пишем в массив max
            //Например: 1,2,3,8 выше, чем 1,2,6
            for ( i = max_length; i < current.length; i++ )
			{
				if ( current[i] > max[i] )
				{
					max = current;
					break;
				}

				if ( current[i] < max[i] )
				{
				 	break;
				}
			}
		}
	}

	//Удаляем все нули из массива max
	while ( max[max.length - 1] == 0 )
	{
		max.pop();
	}

	//Возвращаем ID самого нижнего выделенного элемента
	return max.join(":").substring( max.join(":").lastIndexOf(":") + 1 );
}
