/*
 * Represents a topic, containing the id, associated nested subtopics among other fields
 */
function TopicObj(dimId, parentDimId, rootTopicDimId, nestedItems, checkedVal) {
	var id = dimId;
	var parentId = parentDimId;
	var rootTopicId = rootTopicDimId;
	var nestedSubtopics = nestedItems;
	var checked = checkedVal;
	this.getId = getId;
	this.getParentId = getParentId;
	this.getRootTopicId = getRootTopicId;
	this.getNestedSubtopics = getNestedSubtopics;
	this.isChecked = isChecked;
	this.isRootTopic = isRootTopic;
	
	
	function getId() {
		return id;
	}
	
	function getParentId() {
		return parentId;
	}
	
	function getRootTopicId() {
		return rootTopicId;
	}
	
	function getNestedSubtopics() {
		return nestedSubtopics;
	}
	
	function isChecked() {
		return checked;
	}
	
	function isRootTopic() {
		return (rootTopicId == id);
	}
}


// Variable to help in determining which nested subtopics a topic/subtopic contains, etc.
var topicObjs = new Array();

// Variable to help determine whether the 'Any Topics' checkbox needs to be selected/deselected
var selectedTopicsCount = 0;

/*
 * initializes the selectedTopicCount var
 *
 */
function initializeSelectedTopicsCount(initVal) {

	if (Number(initVal) != NaN) {
		selectedTopicsCount = initVal;
	}
}


/*
 * Creates an a TopicObj objects for a particular topic id, as well as
 * all subtopics and nested subtopics for that topic.
 * These objects are used in various Custom Search Form methods 
 * to determining which subtopics belong to a given topic or subtopic
 *
 */
function lazilyInitializeTopicForId(topicId, index) {

	if (topicObjs[index] == undefined) {
		//initialize the root topic's subtopics
		var subtopicObjs = initializeSubtopics(topicId, topicId);//document.getElementsByName(topicId);
		
		var topicCheckbox = document.getElementById('dim_' + topicId);
		
		//add the topic to the array
		var topicObj = new TopicObj(topicId, null, topicId, subtopicObjs, topicCheckbox.checked);
		topicObjs[index] = topicObj;
	}
}


/*
 * Creates an array of Javascript TopicObj objects. 
 * These objects are used in various Custom Search Form methods 
 * to determining which subtopics belong to a given topic or subtopic
 *
 */
function initializeRootTopicArray() {

	//loop through the all subtopics (ids are hidden in the popover)
	var topicIds = document.getElementsByName('topicId');
	topicObjs = new Array(topicIds.length);
	
	/*for (var i=0; i < topicIds.length; i++) {
	
		var topicId = topicIds[i].value;
		
		//initialize the root topic's subtopics
		var subtopicObjs = initializeSubtopics(topicId, topicId);//document.getElementsByName(topicId);
		
		var topicCheckbox = document.getElementById('dim_' + topicId);
		
		//add the topic to the array
		var topicObj = new TopicObj(topicId, null, topicId, subtopicObjs, topicCheckbox.checked);
		topicObjs[i] = topicObj;
	}*/
	
	//loop and display all subtopics
	/*for (var i=0; i<topicObjs.length; i++) {
	
		document.writeln('<br/>topic ' + topicObjs[i].getId());
		
		var subtopicObjs = topicObjs[i].getNestedSubtopics();
		if (subtopicObjs ==  undefined) {
			subtopicObjs = new Array();
		} else if (subtopicObjs.length == undefined) {
			//check for only one  subtopic
			subtopicObjs = new Array(subtopicObjs);
		}
		
		for (var j=0; j<subtopicObjs.length; j++) {
		
			document.writeln('<br/>-subtopic ' + subtopicObjs[j].getId());
			
			var nestedSubtopicObjs = subtopicObjs[j].getNestedSubtopics();
			if (nestedSubtopicObjs ==  undefined) {
				nestedSubtopicObjs = new Array();
			} else if (nestedSubtopicObjs.length == undefined) {
				//check for only one  subtopic
				nestedSubtopicObjs = new Array(nestedSubtopicObjs);
			}
			
			for (var k=0; k<nestedSubtopicObjs.length; k++) {
			
				document.writeln('<br/>--nestedSubtopic ' + nestedSubtopicObjs[k].getId());
				
				
				var nestedSubtopicObjs2 = nestedSubtopicObjs[k].getNestedSubtopics();
				if (nestedSubtopicObjs2 ==  undefined) {
					nestedSubtopicObjs2 = new Array();
				} else if (nestedSubtopicObjs2.length == undefined) {
					//check for only one  subtopic
					nestedSubtopicObjs2 = new Array(nestedSubtopicObjs2);
				}
				
				for (var l=0; l<nestedSubtopicObjs2.length; l++) {
					document.writeln('<br/>--nestedSubtopic2 ' + nestedSubtopicObjs2[l].getId());
				}	
			}
		}
	}*/
}

/*
 * Creates an array of Javascript subtopic TopicObj objects. 
 * These objects are used in various Custom Search Form methods 
 * to determining which subtopics belong to a given topic or subtopic
 *
 */
function initializeSubtopics(topicId, rootTopicId) {

	//loop through the selected topic's subtopics
	var subtopics = document.getElementsByName(topicId);
	
	//process topic's subtopics
	if (subtopics ==  undefined) {
		subtopics = new Array();
	} else if (subtopics.length == undefined) {
		//check for only one  subtopic
		subtopics = new Array(subtopics);
	}
	
	var subtopicsLength = subtopics.length;
	var subtopicObjs = new Array(subtopicsLength);
	for (var i=0; i < subtopicsLength; i++) {
		
		var subtopicId = subtopics[i].value;
		var subtopicCheckbox = document.getElementById('dim_' + subtopicId);
		
		//process subtopic's nested subtopics
		var nestedSubtopicObjs = initializeSubtopics(subtopicId, rootTopicId);
		
		var subtopicObj = new TopicObj(subtopicId, topicId, rootTopicId, nestedSubtopicObjs, subtopicCheckbox.checked);
		
		//add the subtopic to the array
		subtopicObjs[i] = subtopicObj;
	}
	
	return subtopicObjs;
}

/*
 * Helper method to find a topic object for the given id
 */
function findTopicForId(dimId, topics) {

	var matchingTopic = null;
	
	//if array of topics passed in, start at the top
	if (topics == null) {
		return matchingTopic;
	}
	
	//search through the topics
	var topicsLength = topics.length;
	for (var i=0; i < topicsLength; i++) {
		
		var topic = topics[i];
		if (topic != undefined) {
			if (topic.getId() == dimId) {
				return topic;
			}
			
			matchingTopic = findTopicForId(dimId, topic.getNestedSubtopics());
			if (matchingTopic != null) {
				return matchingTopic;
			}
		}
	}
	
	return matchingTopic;
}

/*
 * Ensures that when a topic is selected, all nested subtopics on the form
 * are deselected and hidden.
 *
 * If the topic is deselected, not a root topic, then it is hidden, 
 * and all parent topics for it are chekced to see if they should be 
 * hidden as well.
 * 
 * Finally, determines if the 'Any' topic checkbox should be selected.
 * 
 */
function processFormTopicSelection(dimId) {

	var dimCheckbox = document.getElementById('dim_' + dimId);
	
	var topic = findTopicForId(dimId, topicObjs);
	
	//if the subtopic was checked, de-select any subtopics/nested subtopics
	if (dimCheckbox.checked) {
	
		selectedTopicsCount++;
		uncheckFormSubtopics(topic.getNestedSubtopics());
		
		//deselect the 'any' checkbox
		var anyTopicCheckbox = document.getElementById('topic_subject_any');
		anyTopicCheckbox.checked = false;
		
	} else {
	
		selectedTopicsCount--;
	
		//if it was unchecked, and it was not a root topic, then hide this checkbox\
		if (!topic.isRootTopic()) {
			uncheckFormTopic(dimId);
			
			hideFormTopic(dimId);
			
			//check the parent, if the parent is not a root topic, and it is unchecked,
			//then hide that too
			hideFormParentTopics(topic);
		}
		
	
		//if no other topic/subtopic is selected, then check 'any'
		if (selectedTopicsCount == 0) {
			var anyTopicCheckbox = document.getElementById('topic_subject_any');
			anyTopicCheckbox.checked = true;
		}
	}
}


/*
 * Deselect all given subtopic checkboxes in the form.
 * Also, when a subtopic is unchecked in the form, it is also hidden.
 */
function uncheckFormSubtopics(subtopics) {

	if (subtopics == null) {
		return;
	}
	
	var subtopicsLength = subtopics.length;
	for (var i=0; i < subtopicsLength; i++ ) {
		
		uncheckFormTopic(subtopics[i].getId());
		hideFormTopic(subtopics[i].getId());
		
		//uncheck all subtopics
		uncheckFormSubtopics(subtopics[i].getNestedSubtopics());
	}
			
}


/*
 * Ensures that a nested subtopic is unchecked
 * 
 */
function uncheckFormTopic(dimId) {

	var topicCheckbox = document.getElementById('dim_' + dimId);
	if (topicCheckbox.checked) {
		topicCheckbox.checked = false;
		selectedTopicsCount--;
	}
}

/*
 * Ensures that a nested subtopic is hidden
 * 
 */
function hideFormTopic(dimId) {
		
	var topicCheckboxDiv = document.getElementById('div_' + dimId);
	topicCheckboxDiv.style.display = "none";
}

/*
 * Hides the parent topic if none of the parent topic's subtopics are selected.
 * The method works recursively, hiding all parent topics up until
 the root topic
 * 
 */
function hideFormParentTopics(topic) {

	if (!topic.isRootTopic()) {
		
		var parent = findTopicForId(topic.getParentId(), topicObjs);
		//if none of the parent topic's subtopic are selected, then 
		//hide the parent topic
		if (!isOneTopicSelected(parent.getNestedSubtopics()) && !parent.isRootTopic()) {
			
			hideFormTopic(parent.getId());
			
			//attempt to hide the parent topics for this topic
			hideFormParentTopics(parent);
		}
	}
}


/*
 * Ensures that, in the popover,  when a subtopic is selected, all nested subtopics are deselected
 * 
 */
function processPopoverTopicSelection(dimId, parentId, rootTopicDimId) {

	var dimCheckbox = document.getElementById('pop_dim_' + dimId);
	
	//if the subtopic was checked, de-select any parent subtopics/nested subtopics
	if (dimCheckbox.checked) {
	
		//uncheckPopoverSubtopic(subtopic.getId());
		uncheckPopoverParentTopics(parentId);
		
		var subtopic = findTopicForId(dimId, topicObjs);
		uncheckPopoverSubtopics(subtopic.getNestedSubtopics());
	}
}

/*
 * Deselect all given popover subtopic checkboxes in the popover.
 */
function uncheckPopoverSubtopics(subtopics) {

	if (subtopics == null) {
		return;
	}
	var subtopicsLength = subtopics.length;
	for (var i=0; i < subtopicsLength; i++ ) {
		
		uncheckPopoverSubtopic(subtopics[i].getId());
		
		//uncheck all subtopics
		uncheckPopoverSubtopics(subtopics[i].getNestedSubtopics());
	}
			
}


/*
 * Ensures that a popover nested subtopic is unchecked
 * TODO may no longer need
 */
function uncheckPopoverSubtopic(dimId) {

	var subtopicCheckbox = document.getElementById('pop_dim_' + dimId);
	subtopicCheckbox.checked = false;
}

/*
 * Ensures that a popover nested subtopic is unchecked
 * 
 */
function uncheckPopoverParentTopics(dimId) {

	var parentCheckbox = document.getElementById('pop_dim_' + dimId);
	if (parentCheckbox != null) {
		parentCheckbox.checked = false;
		
		//using the popover checkbox name to obtain the parent id,
		//which is faster than first obtaining a topic obj with findTopicForId(dimId)
		//and then getting the parent id with topic.getParentId()
		uncheckPopoverParentTopics(parentCheckbox.name);
	}
}


/*
 * Display the subtopic selection popover.
 * This method also sets the topic tets in the popover, and wensures that all
 * related subtopics are displayed
 *
 */
function overlaySubtopicSelectPop(curobj, subobjstr, opt_position, topicName, topicId) {
	
	if (document.getElementById){

		var subobj=document.getElementById(subobjstr);
		
		//if the selection popover is currently displaying for another topic, then hide it
		if (subobj.style.display == "block") {
			hideSubtopicSelections();
		}
		
		//set the current topic id
		var currentTopicId = document.getElementById('currentTopicId');
		currentTopicId.value = topicId;
		
		var searchSubtopicPopoverInstructions = document.getElementById('searchSubtopicInstructions');
		searchSubtopicPopoverInstructions.innerHTML = topicName;
		
		//initialize the popover's checkboxes
		initializeSubtopicPopoverCheckboxes(topicId);
		 
		//display the subtopics
		var subtopicsDiv = document.getElementById(topicId + '_subtopics');
		subtopicsDiv.style.display = "block";
		
		//set the subtopic popover select link
		var searchSubtopicLink = document.getElementById('searchSubtopicLink');
		searchSubtopicLink.href = "javascript: processSubtopicSelections('" + topicId + "', true);";
		
		var searchSubtopicCloseLink = document.getElementById('searchSubtopicCloseLink');
		searchSubtopicCloseLink.href = "javascript: hideSubtopicSelections('" + topicId + "');";

		overlay(curobj, subobjstr, opt_position);

		document.getElementById('popover_iframe').style.display="none";

		return true;
	} else {
		return true;
	}
}



/*
 * initialize the popover checkbox statuses to match the form's subtopic checkbox statuses 
 */
function initializeSubtopicPopoverCheckboxes(topicId){
	
	//loop through the selected topic's subtopics
	var subtopics = document.getElementsByName(topicId);
	
	//process topic's subtopics
	if (subtopics ==  undefined) {
		subtopics = new Array();
	} else if (subtopics.length == undefined) {
		//check for only one  subtopic
		subtopics = new Array(subtopics);
	}
	
	var subtopicsLength = subtopics.length;
	for (var i=0; i < subtopicsLength; i++) {
		
		var subtopicId = subtopics[i].value;
		var correspondingCheckbox = document.getElementById('dim_' + subtopicId);
		subtopics[i].checked = correspondingCheckbox.checked;
		
		//diplay the nested subtopics for this current sub topic
		initializeSubtopicPopoverCheckboxes(subtopicId);
	}
}



/*
 * This method is called after the user submits his subtopic popover selections.
 * This method id responsible for correctly checking the associated subtopic checkboxes
 * on the form, and hiding the popover.
 * 
 * TODO try to make this recursive
 */
function processSubtopicSelections(topicId, isRoot){
	
	//loop through and set all the selected topic subtopic checkboxes to match the popover
	var subtopics = document.getElementsByName(topicId);

	var showParentTopic = false;
	
	//process topic's subtopics
	if (subtopics ==  undefined) {
		subtopics = new Array();
	} else if (subtopics.length == undefined) {
		//check for only one  subtopic
		subtopics = new Array(subtopics);
	}
	
	var subtopicsLength = subtopics.length;
	for (var i=0; i < subtopicsLength; i++) {
		
		var subtopicId = subtopics[i].value;
		var correspondingCheckbox = document.getElementById('dim_' + subtopicId);
		if ((!correspondingCheckbox.checked) && (subtopics[i].checked)) {
			selectedTopicsCount++;
		} else if ((correspondingCheckbox.checked) && (!subtopics[i].checked)) {
			selectedTopicsCount--;
		}
		correspondingCheckbox.checked = subtopics[i].checked;
		
		//display the checkbox, if it is checked
		if (correspondingCheckbox.checked) {
			document.getElementById('div_' + subtopicId).style.display = "block";
			showParentTopic = true;
		} else {
			document.getElementById('div_' + subtopicId).style.display = "none";
		}
		
		
		//process nested subtopics
		var nestedTopicChecked = processSubtopicSelections(subtopicId, false);
		if (nestedTopicChecked) {
			showParentTopic = true;
		}
		
		//if at least one nestedSubtopic was selected, display the parent subtopic
		if (showParentTopic && !isRoot) {
			document.getElementById('div_' + topicId).style.display = "block";
		}
	}
	
	//if at least one subtopic was selected, need to uncheck the main topic/subtopic
	if (isRoot && showParentTopic) {
	
		uncheckFormTopic(topicId);
		
		//deselect the 'any' checkbox
		var anyTopicCheckbox = document.getElementById('topic_subject_any');
		anyTopicCheckbox.checked = false;
	
	} else {
		//if no other topic/subtopic is selected, then check 'any'
		if (selectedTopicsCount == 0) {
			var anyTopicCheckbox = document.getElementById('topic_subject_any');
			anyTopicCheckbox.checked = true;
		}
		/*if (!isOneTopicSelected(topicObjs)) {
			var anyTopicCheckbox = document.getElementById('topic_subject_any');
			anyTopicCheckbox.checked = true;
		}*/
	}
	
	hideSubtopicSelections();
	
	if (!isRoot) {
		return showParentTopic;
	}
}

/*
 * Determines if at least one topic, subtoic, or nested subtopic is selected.
 * Helps to determine if the 'Any' checkbox shuld be selected
 */
function isOneTopicSelected(topics) {


	if (topics == null) {
		return false;
	}
	
	var topicsLength = topics.length;
	for (var i=0; i < topicsLength; i++) {
		
		var topic = topics[i];
		var topicCheckbox = document.getElementById('dim_' + topic.getId());
		if (topicCheckbox.checked) {
			return true;
		}
		
		if (isOneTopicSelected(topic.getNestedSubtopics())) {
			return true;
		}
	}
	
	//no topic is selected...
	return false;

}

/*
 * Hides all popover subtopic selections for the current selected topic
 */
function hideSubtopicSelections() {

	//hide the subtopics
	var currentTopicId = document.getElementById('currentTopicId');
	var subtopicsDiv = document.getElementById(currentTopicId.value + '_subtopics');
	subtopicsDiv.style.display = "none";
	
	//hide the popover
	overlayclose('searchsubtopic_popover');
}

/*
 * Called when an 'Any Topic' checkbox is checked.  Responsible for ensuring that all
 * topics and subtopics are deselected
 */
function processAnyTopicsCheckbox() {

	var anyTopicCheckbox = document.getElementById('topic_subject_any');
	if (anyTopicCheckbox.checked) {
	
		//deselect all topics
		var topicObjsLength = topicObjs.length;
		for (var i=0; i < topicObjsLength; i++) {
			
			if (topicObjs[i] != undefined) {
				uncheckFormTopic(topicObjs[i].getId());
				uncheckFormSubtopics(topicObjs[i].getNestedSubtopics());
			}
		}
	} else {
	
		//the user cannot uncheck the anyTopicCheckbox.  They must select a topic to uncheck it
		anyTopicCheckbox.checked = true;
	
	}
}

/*
 * Called when an 'Any' checkbox is checked.  Responsible for ensuring that all
 * corresponding checkboxes are deselected
 */
function processAnyCheckbox(anyCheckbox, correspondingElementName, correspondingCheckboxCount) {
	
	if (anyCheckbox.checked) {
	
		//deselect all corresponding elements
		for (var i=0; i < correspondingCheckboxCount; i++) {
			var correspondingCheckbox = document.getElementById(correspondingElementName + '[' + i + '].checked');
			correspondingCheckbox.checked = false;
		}
	} else {
		//the user cannot uncheck the 'any' Checkbox.  They must select an item 
		anyCheckbox.checked = true;
	}
}

/*
 * Called when a checkbox is checked.  Responsible for ensuring that the 'Any' checkbox is deselected if need be
 */
function processCheckbox(thisCheckbox, anyCheckboxId, checkBoxName, checkboxCount) {

	//if a (non 'Any') checkbox is selected, deselect the 'Any' checkbox
	if (thisCheckbox.checked) {
	
		//deselect the 'Any' checkbox
		var anyCheckBox = document.getElementById(anyCheckboxId);
		anyCheckBox.checked = false;
		
	} else {
		//need to check if any other elements are checked.
		var isAnotherChecked = false;
		for (var i=0; i < checkboxCount; i++) {
			var checkBox = document.getElementById(checkBoxName + '[' + i + '].checked');
			if (checkBox.checked) {
				isAnotherChecked = true;
				break;
			}
		}
		
		if (!isAnotherChecked) {
			//select the 'Any' checkbox
			var anyCheckBox = document.getElementById(anyCheckboxId);
			anyCheckBox.checked = true;
		}
	}
}

/*
 * Called when the user selects 'Any Reading Level'. 
 * Responsible for hiding reading level options.
 */
function processAnyReadingLevelCheckbox(anyCheckbox) {
	
	if (anyCheckbox.checked) {
		
		//reset the reading from level to the first option
		var readingLevelFromSelect = document.getElementById('reading_level_from_options');
		readingLevelFromSelect.options[0].selected = true;
		document.getElementById('reading_level_from').value = "";
		
		//reset the reading to level to the first option
		var readingLevelToSelect = document.getElementById('reading_level_to_options');
		readingLevelToSelect.options[0].selected = true;
		document.getElementById('reading_level_to').value = "";
			
	} else {
		//the user cannot uncheck the 'any' Checkbox.  They must select an item 
		anyCheckbox.checked = true;
	}
	
}

/*
 * Sets the reading level 'From' hidden input field
 */
function setReadingLevelFrom(readingLevelFromSelect) {
	var readingLevelFrom = document.getElementById('reading_level_from');
	readingLevelFrom.value = readingLevelFromSelect.options[readingLevelFromSelect.selectedIndex].value;
	document.getElementById('is_reading_level_selected').value = "true";
	
	//check if the reading from and reading to values are any.  if so, reselect the 'Any'.
	//otherwise deselect the 'Any' checkbox
	var readingLevelTo = document.getElementById('reading_level_to');
	var anyCheckBox = document.getElementById('reading_level_any');
	if ((readingLevelFrom.value == '') && (readingLevelTo.value == '')) {
		anyCheckBox.checked = true;
	} else {
		anyCheckBox.checked = false;
	}
}

/*
 * Sets the reading level 'To' hidden input field
 */
function setReadingLevelTo(readingLevelToSelect) {
	var readingLevelTo = document.getElementById('reading_level_to');
	readingLevelTo.value = readingLevelToSelect.options[readingLevelToSelect.selectedIndex].value;
	document.getElementById('is_reading_level_selected').value = "true";
	
	//check if the reading from and reading to values are any.  if so, reselect the 'Any'.
	//otherwise deselect the 'Any' checkbox
	var readingLevelFrom = document.getElementById('reading_level_from');
	var anyCheckBox = document.getElementById('reading_level_any');
	if ((readingLevelFrom.value == '') && (readingLevelTo.value == '')) {
		anyCheckBox.checked = true;
	} else {
		anyCheckBox.checked = false;
	}
}