// Автор - Осовский Л.
// Скрипт отмечает элементы дерева. Позволяет отметить все элементы ветки, отметив саму только ветку. То же самое со снятием отметки. Есть управляющий элемент - вершина дерева, который отмечает ВСЕ элементы дерева.
// Если в элементах-потомках есть как отмеченные, так и неотмеченные элементы, то настоящий элемент отмечает, как неопределенный.
// Соглашение имен:
// имя формы - fieldList;
// имя вершины дерева - toggleAll;
// имена checkbox'ов элементов дерева состоят из 8-и букв (inccheck) и числа, обозначающего уровень вложенности, начиная с 1. Т.е. inccheck1 - элемент самого первого уровня (не вложенный);
// id checkbox'ов состоят из 2-х букв и числа, однозначно идентифицирующего его.
// Число описывается в виде "id родительского элемента"+"трехзначное число, идентифицирующее элемент на своем уровне".
// Например, 1234012 означает, что это элемент третьего уровня с номером 012, относящийся к элементу 2-го уровня с номером 234, котороый относится к элементу 1-го уровня с номером 1.
// Ограничение: элементов одного уровня, относящихся к одному родительскому элементу, не может быть больше 999-и.


    function initCheck() // Функция, инициирует состояние дерева в зависимости от набора отмеченных элементов. Вызывается onclick="initCheck()" из тега body.
    {
	var fl = document.fieldList;
	var len = fl.elements.length;
	for (var i = 0; i < len; i++) {
	    var e = fl.elements[i];
	    var e_len = e.id.length;
	    var param = e.id.substring(2, e_len);
	    var N = Math.round(param.length/3) + 1;
	    for (var j = 0; j < len; j++) {
	        var g = fl.elements[j];
	        var g_len = g.id.length;
	        var g_param = g.id.substring(0, e_len);
	        if (g_param == e.id && g_len >= e_len) {
		    var M = Math.round((g_len-2)/3) + 1;
	        }
	    }
	    if (e.name.substring(0, 8) == 'inccheck' && e.checked) {
//		Highlight(e);
		CheckUp(e, N);
		CheckDown(e, N, M);
		document.fieldList.toggleAll.checked = false;
		document.fieldList.toggleAll.indeterminate = AllChecked();
		if (!document.fieldList.toggleAll.indeterminate)
		{
		    document.fieldList.toggleAll.checked = true;
		}
	    }
	}
    }

    function ToggleTree(e) // Функция, вызываемая при изменении состояния элемента дерева. Определяет уровень вложенности N и суммарное количество уровней M, вызывает другие функции. Вызывается из checkbox'а по onclick="ToggleTree(this)".
    {
	var fl = document.fieldList;
	var e_len = e.id.length;
	var param = e.id.substring(2, e_len);
	var N = Math.round(param.length/3) + 1;
	var len = fl.elements.length;
	for (var i = 0; i < len; i++) {
	    var g = fl.elements[i];
	    var g_len = g.id.length;
	    var g_param = g.id.substring(0, e_len);
	    if (g_param == e.id && g_len >= e_len) {
		var M = Math.round((g_len-2)/3) + 1;
	    }
	}
	if (e.checked) {
//	    Highlight(e);
	    CheckUp(e, N);
	    CheckDown(e, N, M);
		document.fieldList.toggleAll.checked = false;
	    document.fieldList.toggleAll.indeterminate = AllChecked();
	    if (!document.fieldList.toggleAll.indeterminate)
	    {
		document.fieldList.toggleAll.checked = true;
	    }
	}
	else {
//	    Unhighlight(e);
	    ClearUp(e, N);
	    ClearDown(e, N, M);
	    document.fieldList.toggleAll.indeterminate = AllUnChecked();
	    document.fieldList.toggleAll.checked = false;
	}
    }

    function CheckUp(e, N) // Отмечает элементы дерева, являющиеся предками для отмеченного элемента, в случае, если все остальные листья этой ветки уже отмечены.
    {
	e.indeterminate = false;
	e.checked = true;
	for (N; N > 1; N--) {
	    var fl = document.fieldList;
	    var len = fl.elements.length;
	    finalExit:
	    for (var i = 0; i < len; i++) { // этот цикл проверяет, все ли элементы уровня N отмечены
		var g = fl.elements[i];
		var g_index = g.name.substring(8, g.name.length);
		var red = (N + 1 - g_index) * 3;
		var param_len = g.id.length - red;
		var g_param = g.id.substring(0, param_len);
		var e_param = e.id.substring(0, param_len);
		if (g_index == N && g_param == e_param) {
		    if (!g.checked || g.indeterminate) {
			var z = 0;
			break finalExit;
		    }
		    else {
			var z = 1;
		    }
		}
	    }
	    for (var i = 0; i < len; i++) { // этот цикл отмечает элемент, у которого все потомки отмечены
		var g = fl.elements[i];
		var g_index = g.name.substring(8, g.name.length);
		var eg = e.id.substring(0, g.id.length);
		if (g_index == (N - 1) && g.id == eg) {
		    if (z == 1) {
			g.indeterminate = false;
			g.checked = true;
		    }
		    else {
			g.checked = false;
			g.indeterminate = true;
		    }
		}
	    }
	}
    }

    function CheckDown(e, N, M) // Отмечает все элементы дерева, являющиеся потомками для отмеченного элемента.
    {
	for (N; N < M; N++) {
	    var fl = document.fieldList;
	    var len = fl.elements.length;
	    for (var i = 0; i < len; i++) {
		var g = fl.elements[i];
		var id_param = g.id.substring(0, e.id.length);
		if (e.id == id_param) {
		    g.indeterminate = false;
		    g.checked = true;
		}
	    }
	}
    }

    function ClearUp(e, N) // Снимает отметки со всех элементов дерева, являющихся предками для элемента, с которого снята отметка.
    {
	e.indeterminate = false;
	e.checked = false;
	for (N; N > 1; N--) {
	    var fl = document.fieldList;
	    var len = fl.elements.length;
	    finalExit:
	    for (var i = 0; i < len; i++) { // этот цикл проверяет, все ли элементы уровня N отмечены
		var g = fl.elements[i];
		var g_index = g.name.substring(8, g.name.length);
		var red = (N + 1 - g_index) * 3;
		var param_len = g.id.length - red;
		var g_param = g.id.substring(0, param_len);
		var e_param = e.id.substring(0, param_len);
		if (g_index == N && g_param == e_param) {
		    if (g.checked || g.indeterminate) {
			var z = 0;
			break finalExit;
		    }
		    else {
			var z = 1;
		    }
		}
	    }
	    for (var i = 0; i < len; i++) { // этот цикл отмечает элемент, у которого все потомки отмечены
		var g = fl.elements[i];
		var g_index = g.name.substring(8, g.name.length);
		var eg = e.id.substring(0, g.id.length);
		if (g_index == (N - 1) && g.id == eg) {
		    if (z == 1) {
			g.indeterminate = false;
			g.checked = false;
		    }
		    else {
			g.checked = false;
			g.indeterminate = true;
		    }
		}
	    }
	}
    }

    function ClearDown(e, N, M) // Снимает отметки со всех элементов дерева, являющихся потомками для элемента, с которого снята отметка.
    {
	for (N; N < M; N++) {
	    var fl = document.fieldList;
	    var len = fl.elements.length;
	    for (var i = 0; i < len; i++) {
		var g = fl.elements[i];
		var id_param = g.id.substring(0, e.id.length);
		if (e.id == id_param) {
		    g.indeterminate = false;
		    g.checked = false;
		}
	    }
	}
    }

    function ToggleTreeAll(e) // Функция, вызываемая onclick="ToggleTreeAll(this)" из вершины дерева. Вызывает функции установки и снятия пометок со всех элементов дерева.
    {
	if (e.checked) {
	    CheckAll();
	}
	else {
	    ClearAll();
	}
    }

    function CheckAll() // Помечает все элементы дерева.
    {
	var fl = document.fieldList;
	var len = fl.elements.length;
	for (var i = 0; i < len; i++) {
	    var g = fl.elements[i];
	    var g_param = g.name.substring(0, 8);
	    if (g_param == 'inccheck') {
		g.indeterminate = false;
		g.checked = true;
	    }
	}
    }

    function ClearAll() // Снимает пометки со всех элементов дерева.
    {
	var fl = document.fieldList;
	var len = fl.elements.length;
	for (var i = 0; i < len; i++) {
	    var g = fl.elements[i];
	    var g_param = g.name.substring(0, 8);
	    if (g_param == 'inccheck') {
		g.indeterminate = false;
		g.checked = false;
	    }
	}
    }

    function AllChecked() // Функция, проверяющая, все ли элементы дерева отмечены, и передающая на выход команду установки отметки на вершине дерева.
    {
	var fl = document.fieldList;
	len = fl.elements.length;
	for (var i = 0 ; i < len ; i++) {
	    if (fl.elements[i].name == "inccheck1") {
		if (!fl.elements[i].checked || fl.elements[i].indeterminate) {
		    return true;
		}
	    }
	}
	return false;
    }

    function AllUnChecked() // Функция, проверяющая, все ли элементы дерева не отмеченные, ипередающая на выход команду снятия отметки с вершины дерева.
    {
	var fl = document.fieldList;
	len = fl.elements.length;
	for (var i = 0 ; i < len ; i++) {
	    if (fl.elements[i].name == "inccheck1") {
		if (fl.elements[i].checked || fl.elements[i].indeterminate) {
		    return true;
		}
	    }
	}
	return false;
    }

/*	Это функции смены стиля у отмеченных элементов. Отключены.
    function Highlight(e)
    {
	var r = null;
	if (e.parentNode && e.parentNode.parentNode) {
	    r = e.parentNode.parentNode;
	}
	else if (e.parentElement && e.parentElement.parentElement) {
	    r = e.parentElement.parentElement;
	}
	if (r) {
	    if (r.className == "msgnew") {
		r.className = "msgnews";
	    }
	    else if (r.className == "msgold") {
		r.className = "msgolds";
	    }
	}
    }

    function Unhighlight(e)
    {
	var r = null;
	if (e.parentNode && e.parentNode.parentNode) {
	    r = e.parentNode.parentNode;
	}
	else if (e.parentElement && e.parentElement.parentElement) {
	    r = e.parentElement.parentElement;
	}
	if (r) {
	    if (r.className == "msgnews") {
		r.className = "msgnew";
	    }
	    else if (r.className == "msgolds") {
		r.className = "msgold";
	    }
	}
    }
*/