registerNS("GroupTree");



// Returns the position of a given value in an array, -1 if the value
// is not in the array
GroupTree.positionOf = function(arr, val){
	for(a = 0; a < arr.length; a++){
		if(arr[a] == val) return a;
	}
	return -1;
}



// Function to create the hierarchy of groups
GroupTree.createGroupHierarchy = function(containerID){
	
	var cont = document.getElementById(containerID);
	var output = "";
	
	for(var i = 0; i < groupids.length; i++){
		if(GroupTree.positionOf(ignoregroups, groupids[i]) == -1){ // If we're not supposed to ignore this group
			var padding = grouplevels[i] * leveloffset;
			output += "<label style='padding-left:" + padding + "px'>";
			output += "<input type='checkbox' name='" + checkboxname + "[]' value='" + groupids[i] + "' id='" + checkboxname + groupids[i] + "' onChange='GroupTree.cbChanged(this)'";
	   	output += " />" +  groupnames[i] + "</label><br />";
  	}
	}
	
	cont.innerHTML = output;
	
	// Check the boxes in startgroups
	for(var s = 0; s < startgroups.length; s++){
		if(GroupTree.positionOf(ignoregroups, startgroups[s]) == -1){ // If we're not supposed to ignore this group
  		if(document.getElementById(checkboxname + startgroups[s])){
	  		document.getElementById(checkboxname + startgroups[s]).checked = true;
				if(keepStart) document.getElementById(checkboxname + startgroups[s]).disabled = true;
	  		GroupTree.isChecked(startgroups[s], true);
  		}
		}
	}
	
	GroupTree.onChangeHook();
	
}


// Given the name of a table, creates one row for each group and puts a corresponding
// text box in it
GroupTree.createRoleBoxes = function(containerID){
	
	var table = document.getElementById(containerID);
	
	var rowIndex = 0;
	
	for(var i = 0; i < groupids.length; i++){
		if(GroupTree.positionOf(ignoregroups, groupids[i]) == -1){ // If we're not supposed to ignore this group
			
			var newRow = Misc.insertRow(table, rowIndex);
			newRow.id = "rolerow" + groupids[i];
			newRow.style.display = 'none'; // Show nothing to start with
			var titleCell = newRow.insertCell(0);
			titleCell.innerHTML = groupnames[i];
			titleCell.style.textAlign = "right";
			var roleCell = newRow.insertCell(1);
			
			var roletext;
			if(grouproles[groupids[i]]){
				roletext = grouproles[groupids[i]];
			} else {
				roletext = '';
			}
			
			roleCell.innerHTML = '<input type="text" name="roleChoices[' + groupids[i] + 
													 ']" value="' + roletext + '" size="40" id="role' + groupids[i] + 
													 '" style="margin-left:10px;">';
			rowIndex++;
		}
	}
	
}


// Called after isChecked and isUnchecked
// Provides a hook to a function which may be externally defined, called onGroupChange()
GroupTree.onChangeHook = function(){
	// Hook to a function which can be defined elsewhere
	if(GroupTree.onGroupChange)
		GroupTree.onGroupChange();
	
}


// Called when a checkbox is checked
// Disables all the checkboxes above this one in the hierarchy
GroupTree.isChecked = function(groupid, isStart){
	
	// Get the group's position in the array
	pos = GroupTree.positionOf(groupids, groupid);
	currentLevel = grouplevels[pos];
	
	
	// We go backwards through the array, and every time the level goes
	// down we disable that checkbox
	for(p = pos-1; p >= 0; p--){
		if(grouplevels[p] < currentLevel){
			if(GroupTree.positionOf(ignoregroups, groupids[p]) == -1){ // If we're not supposed to ignore this group
				document.getElementById(checkboxname + groupids[p]).checked = true;
				if((!keepStart || keepStart && !isStart) && !document.getElementById(checkboxname + groupids[p]).disabled){
					GroupTree.showRoleBox(groupids[p]);					
				}
				if(keepStart){
					document.getElementById(checkboxname + groupids[p]).disabled = true;
				}
			}
			currentLevel = grouplevels[p];
		}
	}
	
	GroupTree.showRoleBox(groupid);
	GroupTree.onChangeHook();
	
}


// Called when a checkbox is checked
// Shows the appropriate role box
GroupTree.showRoleBox = function(groupid){
	
	// If we can't change the group we can't change the role either
	if(GroupTree.positionOf(startgroups, groupid) != -1 && keepStart) return;
	
	// Display the roles table just in case it was hidden before
	var mainrow = document.getElementById('rolesrow');
	mainrow.style.display = 'table-row';
	
	var row = document.getElementById('rolerow' + groupid);
	row.style.display = 'table-row';
	
	
}





// Called when a checkbox is unchecked
// Enables all the checkboxes above this one in the hierarchy, unless
// They are in the startgroups array
GroupTree.isUnchecked = function(groupid){
	
	// Get the group's position in the array
	pos = GroupTree.positionOf(groupids, groupid);
	currentLevel = grouplevels[pos];
	
	GroupTree.hideRoleBox(groupid);

	if(keepStart){
		// We go backwards through the array, and every time the level goes
		// down we enable that checkbox
		
		// However, if there is another box checked on the same level as this one,
		// we don't bother
		if(GroupTree.othersCheckedOnSameLevel(groupid)){
			GroupTree.onChangeHook(); 
			return;
		}
		
		for(var p = pos-1; p >= 0; p--){
			if(grouplevels[p] < currentLevel){
				// Once we reach an element in startgroups we can return because
				// everything above that in the hierarchy should always be disabled
				if(GroupTree.positionOf(startgroups, groupids[p]) != -1){
					GroupTree.onChangeHook();
					return;
				}
				
				if(GroupTree.positionOf(ignoregroups, groupids[p]) == -1){ // If we're not supposed to ignore this group
					document.getElementById(checkboxname + groupids[p]).checked = false;
					GroupTree.hideRoleBox(groupids[p]);
					document.getElementById(checkboxname + groupids[p]).disabled = false;
				}
				
				// Stop the unchecking if there are other things checked on the same level
				if(GroupTree.othersCheckedOnSameLevel(groupids[p])) return;

				
				currentLevel = grouplevels[p];

			}
		}
	}
	
	// Reset the current level
	currentLevel = grouplevels[pos];
	
	// We go forwards through the array, and uncheck
	// any checkboxes below the current one in the hierarchy
	for(var p = pos+1; p < groupids.length; p++){
		if(grouplevels[p] > currentLevel){
			
			// If we're not supposed to ignore this group
			if(GroupTree.positionOf(ignoregroups, groupids[p]) == -1){ 
				document.getElementById(checkboxname + groupids[p]).checked = false;
				GroupTree.hideRoleBox(groupids[p]);
				document.getElementById(checkboxname + groupids[p]).disabled = false;
			}
			currentLevel = grouplevels[p];
		} else {
			GroupTree.onChangeHook();
			return
		}
	}
	
	GroupTree.onChangeHook();
	
}



// Called when a checkbox is unchecked
// Hides the appropriate role box
GroupTree.hideRoleBox = function(groupid){
	
	var row = document.getElementById('rolerow' + groupid);
	row.style.display = 'none';
	
	// Hide the entire row if nothing id displayed
	var somethingShowing = false;
	var rolestable = document.getElementById('rolestable');
	
	for(var r = 0; r < rolestable.rows.length; r++){
		//alert("checking row " + r + " - style is " + rolestable.rows[r].style.display + ", id = " + rolestable.rows[r].id);
		if(rolestable.rows[r].style.display != 'none'){
			somethingShowing = true;
		}
	}
	
	if(!somethingShowing){
		var mainrow = document.getElementById('rolesrow');
		mainrow.style.display = 'none';
	}
	
}



// Returns true if there is another checkbox on the same level that is checked
GroupTree.othersCheckedOnSameLevel = function(groupid){
	
	for(g = 0; g < groupids.length; g++){
		if(groupids[g] == groupid)
			var curLevel = grouplevels[g];
	}
	
	for(g = 0; g < groupids.length; g++){
		if(grouplevels[g] == curLevel && groupids[g] != groupid && document.getElementById(checkboxname + groupids[g]).checked)
			return true;
	}
	
	return false;
}




// Called when a user checks/unchecks a checkbox
GroupTree.cbChanged = function(checkbox){
	groupcode = checkbox.value;
	if(checkbox.checked){
		GroupTree.isChecked(groupcode, false);
	} else {
		GroupTree.isUnchecked(groupcode);
	}
}


