/*
	Category selection classes for selecting taxonomy categories from a tree
	generated by the SearchPortletUtils functions.
	Author: Sindri Traustason, Copyright 2005 VYRE Ltd.
*/

/**
 * Category set is a array implementation of a set.
 * CategorySet.array never contains more than one instance of anything
 */
function CategorySet(){
	this.array = new Array(0);
}
CategorySet.prototype.contains = function(categoryId){
	for( var i=0; i < this.array.length; i++ ){
		if(this.array[i]==categoryId){
			return true;
		}
	}
	return false;
}
CategorySet.prototype.add = function(categoryId){
	if(!this.contains(categoryId)){
		this.array.push(categoryId);
	}
}
CategorySet.prototype.remove = function(categoryId){
	var replacement = {};
	for( var i=0; i < this.array.length; i++ ){
		if(this.array[i] == categoryId){
			this.array.splice(i, 1);
		}
	}
}
CategorySet.prototype.join = function(seperator){
	return this.array.join(seperator);
}

/**
 * CategorySelector manages selected categoies in a tree and
 * makes sure their ids are in a comma seperated string in the field
 * with id fieldId.
 */
function CategorySelector(namespace, tree, fieldId, tracerDivId){
	this.categoryIds = new CategorySet();
	this.namespace = namespace;
	this.tree = tree;
	this.fieldId = fieldId;
	this.tracerDivId = tracerDivId;
}

CategorySelector.prototype.init = function(array){
	this.categoryIds.array = (array.length == 1 && array[0] == "")?new Array():array;
	this.updateTracer();
	if(this.categoryIds.array.length > 0){
		this._colorTree(this.tree);
	}
}

CategorySelector.prototype._colorTree = function(xtreeNode){
	var categoryId = this._getId(xtreeNode);
	if(this.categoryIds.contains(categoryId)){
		this.color(categoryId);
		this._expandAncestors(xtreeNode);
	}
	for(var i = 0; i < xtreeNode.childNodes.length; i++){
		this._colorTree(xtreeNode.childNodes[i]);
	}
}

CategorySelector.prototype.addOrRemoveCategory = function(categoryId, xtreeNode){
	if( !this.categoryIds.contains(categoryId) ){
		// Add it but remove the children
		this._add(categoryId);
		this._removeDescendants(xtreeNode);
		this._removeAncestors(xtreeNode);
	} else {
		// Remove it
		this._remove(categoryId);
		this._removeDescendants(xtreeNode);
	}
	this.updateTracer();
	this.writeToForm();
}

CategorySelector.prototype.clear = function(){
	this._removeDescendants(this.tree);
	this.updateTracer();
	this.writeToForm();
}

CategorySelector.prototype._add = function(categoryId){
	//alert('adding ' + categoryId);
	this.categoryIds.add(categoryId);
	this.color(categoryId);
}

CategorySelector.prototype._remove = function(categoryId){
	//alert('removing ' + categoryId);
	this.categoryIds.remove(categoryId);
	this.uncolor(categoryId);
}

CategorySelector.prototype._removeDescendants = function(xtreeNode){
	for( var i=0; i < xtreeNode.childNodes.length; i++){
		var childNode = xtreeNode.childNodes[i];
		var childId = this._getId(childNode);
		//if(!confirm(i + ' == ' + childId))break;
		this._remove(childId);
		this._removeDescendants(childNode);
	}
}

CategorySelector.prototype._removeAncestors = function(xtreeNode){
	var ancestor = xtreeNode.parentNode;
	while(ancestor != undefined && ancestor.id != 'root'){
		this._remove(this._getId(ancestor));
		ancestor = ancestor.parentNode;
	}
}

CategorySelector.prototype._expandAncestors = function(xtreeNode){
	var ancestor = xtreeNode.parentNode;
	while(ancestor != undefined && ancestor.id != 'root'){
		ancestor.expand();
		ancestor = ancestor.parentNode;
	}
}

CategorySelector.prototype.color = function(categoryId){
	var xtreeDiv = document.getElementById('cat_' + this.namespace + '_' + categoryId);
	xtreeDiv.className = 'webfx-tree-item selected';
}

CategorySelector.prototype.uncolor = function(categoryId){
	var xtreeDiv = document.getElementById('cat_' + this.namespace + '_' + categoryId);
	xtreeDiv.className = 'webfx-tree-item';
}

CategorySelector.prototype.writeToForm = function(){
	var field = document.getElementById(this.fieldId);
	field.value = this.categoryIds.join(',');
}

CategorySelector.prototype.updateTracer = function(){
	if(document.getElementById(this.tracerDivId) != undefined){
		var html = "";
		if(this.categoryIds.array.length == 0){
			html = "(" + this.tree.text + ")";
		} else {
			for (var i = 0; i < this.categoryIds.array.length; i++){
				html += "<span>"+ this._getTracer(this.categoryIds.array[i]) +"</span><br>";
			}
		}
		document.getElementById(this.tracerDivId).innerHTML = html;
	}
}

CategorySelector.prototype._getTracer = function(categoryId){
	var tracer = "";
	var category = this._getCategory(categoryId);
	while(category != undefined && category.id != 'root'){
		tracer = " &gt; " + category.text + tracer;
		category = category.parentNode;
	}
	return tracer;
}

CategorySelector.prototype._getCategory = function(categoryId, xtreeNode){
	if(xtreeNode == undefined){
		xtreeNode = this.tree;
	}
	if(categoryId == this._getId(xtreeNode)){
		return xtreeNode;
	} else for(var i = 0; i < xtreeNode.childNodes.length; i++){
		var result = this._getCategory(categoryId, xtreeNode.childNodes[i]);
		if(result != null) return result;
	}
	return null;
}

CategorySelector.prototype._getId = function( xtreeNode ){
	return xtreeNode.id.replace('cat_' + this.namespace + '_', '');
}

/**
 * CategorySelector manages selected categoies in a checkbox tree and
 */
function CheckboxCategorySelector(tree){
	this.tree = tree;
}

CheckboxCategorySelector.prototype.addOrRemoveCategory = function(xtreeNode){
	if( !xtreeNode.getChecked() ){
		this._removeDescendants(xtreeNode);
		//xtreeNode.setChecked(true);
	} else {
		this._addAncestors(xtreeNode);
		//xtreeNode.setChecked(false);
	}
}

CheckboxCategorySelector.prototype._removeDescendants = function(xtreeNode){
	for( var i=0; i < xtreeNode.childNodes.length; i++){
		var childNode = xtreeNode.childNodes[i];
		var checkbox = document.getElementById("chckbx_" + childNode.id );
		if( checkbox.checked ){
			checkbox.checked = false
			this._removeDescendants(childNode);
		}
	}
}

CheckboxCategorySelector.prototype._addAncestors = function(xtreeNode){
	var ancestor = xtreeNode.parentNode;
	while(ancestor != undefined && ancestor.id != 'root'){
		document.getElementById("chckbx_" + ancestor.id ).checked = true
		ancestor = ancestor.parentNode;
	}
}


