//$Id: cs.js,v 1.1.1.1 2004/05/08 01:17:46 joe Exp $

/**
* constructor
* @param selObj select object
* @param data array that contains data in tree structure.
**/
function CascadeSelect(selObj,data) {
	this.form = selObj.form;
	//alert(data[1].parent);
	this.data = new Tree(data);

	this.sub = 'sub';
	this.defaultAttr = 'default';
	this.boxes = new Array();
	this.build(selObj,0);
}

/**
* build cascade select list recursively
* @param select object
* @param parent data index of parent
**/
CascadeSelect.prototype.build = function(selObj,parent,buildSubOnly) {
	data = this.data.getChildren(parent);

	//alert(selObj.name);

	//reset the options of selObj
	if(!buildSubOnly) {
		//default selected option value
		defaultOption = selObj[this.defaultAttr] ? selObj[this.defaultAttr] : selObj.getAttribute(this.defaultAttr);
		//alert(defaultOption);
		this.addBox(selObj.name,parent);
		selObj.options.length = 0;
		for(var i = 0;i < data.length;i ++) {
			//alert(selObj);
			selObj.options[i] = new Option(data[i].option.text,data[i].option.value);
			if(defaultOption != null && data[i].option.value == defaultOption) {
				selObj.selectedIndex = i;
			}
		}
	}
	subName = (selObj[this.sub]) ? selObj[this.sub] : selObj.getAttribute(this.sub);

	if(subName == null) {
		return;
	}
	subObj = this.getObj(subName);
	if(subObj == null) {
		alert("DevError:" + subName + " is not defined!");
		return;
	}
	//selectedIndex
	var index = selObj.selectedIndex;
	//alert(index);
	parent = data[index].id;
	this.build(subObj,parent);
}


/**
* get object by name
* @param string object name
*/
CascadeSelect.prototype.getObj = function(objName) {
	for(var i = 0;i < this.form.elements.length;i ++) {
		if(this.form.elements[i].name == objName) {
			return this.form.elements[i];
		}
	}
	return 'undefined';
}

/**
* handling change
**/
CascadeSelect.prototype.change = function(selObj) {	
	var box = this.getBox(selObj.name);
	if(!box) {
		alert("Error occurs!");
		return;
	}
	this.build(selObj,box.parent,true);
}


/**
* determine the give name is in the box array
*/
CascadeSelect.prototype.addBox = function(boxName,parent){
	for(var i = 0;i < this.boxes.length;i ++) {
		if(this.boxes[i].name == boxName) {
			this.boxes[i].parent = parent;
			return;
		}
	}
	var newIndex = this.boxes.length;
	this.boxes[newIndex] = new SelectBox(boxName,parent);
}

CascadeSelect.prototype.getBox = function(boxName) {
	for(var i = 0;i < this.boxes.length;i ++) {
		if(this.boxes[i].name == boxName) {
			return this.boxes[i];
		}
	}
	return false;
}

/**
* select box constructor
*/
function SelectBox(boxName,parent) {
	this.name = boxName;
	this.parent = parent;
}

/**
* TreeNode
* @param int parent index
* @param string node text
* @param string node value
*/
function TreeNode(parent,text,value) {
	this.parent = parent;
	this.option = new Option(text,value);
}

TreeNode.prototype.addID = function(id) {
	this.id = id;
}

/**
* Tree Constructor
**/
function Tree(nodes) {
	this.nodes = nodes;
}

/**
* get children the the given parent,only one level of children would be returned
* @param int parent index
* @return array
*/
Tree.prototype.getChildren = function(parent) {
	//alert(this.nodes.length);
	var j = 0;
	children = new Array();
	for(var i = 0;i < this.nodes.length;i ++) {
		if(typeof this.nodes[i] == "undefined" || this.nodes[i] == null)
			continue;
		if(this.nodes[i].parent == parent) {
			children[j] = this.nodes[i];
			children[j].addID(i);
			j ++;
		}
	}
	return children;
}

