/*  未定义JavaScript Lib
 *  (c) 2005 Jason Ng <fivebull><email: &#x66;&#x69;&#x76;&#x65;&#x62;&#x75;&#x6c;&#x6c;&#x40;&#x67;&#x6d;&#x61;&#x69;&#x6c;&#x2e;&#x63;&#x6f;&#x6d;>
 */

 /* NOTE id211150024581: {}内定义变量(还有for系列语句等)一定要用var定义, 不然会变成全局变量!
 
 
/**
 * click后指定下拉选框(select) selectedIndex改成指定值, select变更取消click对象(如果有的话)
 */
function assignSelectedByVal(select, fire, val){
    _AddFuncToEvent("onchange", select, 
                    function() {
                        if(fire.checked !== undefined){
                            fire.checked = false;
                        }
                    }
    );
    
    _AddFuncToEvent("onclick", fire, 
                function() {
                    for(var i=0;i<select.options.length;i++){
                        if(select.options[i].value==val){
                            select.selectedIndex=i
                        }
                    }
                }
    );
}

/**
 * _AddFuncToEvent
 *
 * @param string event  事件(onclick, onchange, onxxx等, DOM标准大小写)
 * @param Object element    要被增加func的对象
 * @param Function newFunc  增加的函数
 */
function _AddFuncToEvent(eventName, element, newFunc){
    /**
    //NOTE id011150027522: 取消 FF不兼容(not compatible)!!! ;( 类里没有定义的属性或没值(但定义了),FF总会返回undefined, 按ECMA应该是有定义的是null, 没定义才是undefined
    if(element.eventName === undefined){
        throw Error(element.tagName+"不支持"+eventName+"事件");
        return false;
    }
    */
    /* NOTE id011150023522: 不能用element.eventName 只能用element[eventName] */
	/* NOTE id211150027571: 改成这样用才不会死循环 */
    if(element["_add"+eventName+"orginalHadInit"] != true){
		element["orginal_event"] = element[eventName];
		element["_add"+eventName+"orginalHadInit"] = true;
	}
    
    /** 放入对象中 **/
    //初始化函数队列
    if(element["_add"+eventName+"FuncList"] == null){
        element["_add"+eventName+"FuncList"] = new Array();
    }
    
    element["_add"+eventName+"FuncList"].push(newFunc);
    
    element[eventName] = function() {
        //执行函数队列中的函数
        var result = void(0);
        for(var i=0; i<element["_add"+eventName+"FuncList"].length;i++){
            result = element["_add"+eventName+"FuncList"][i].call(element);
        }
        
		
        if(typeof element["orginal_event"] == "function"){
            return element["orginal_event"]();
        }
		
        
        return result;
    }
    
}


/*--------------------------------------------------------------------------*/

/**
 * 数据节点对象
 */
function DataNode(id, name){
    this.id = id;
    this.name = name;
    this.child = new Array();
    this.childLevel = 0;
    this.parent = null;
}


DataNode.prototype.addChild = function(data_node, id) {
    //指向父对象
    data_node.parent = this;
    //加入组
    this.child[id] = data_node;
    
    
    //加所有parent的childLevel
    if(this.childLevel < 1){
        //加childLevel数字
        this.childLevel=1;
        
        var i = this;
        while(i.hasParent()){
			var parent = i.getParent();
            parent.childLevel = i.getChildLevel()+1;
			i = parent;
        }
    };
}

//加入子到开头
DataNode.prototype.unshiftChild = function(data_node, id) {
    //指向父对象
    data_node.parent = this;
    //加入组
    var tmp_child = new Array();
    
    tmp_child[id] = data_node;
    
    for(var key in this.child) {
    	tmp_child[key] = this.child[key];
    }
    
    this.child = tmp_child;
    
    
    //加所有parent的childLevel
    if(this.childLevel < 1){
        //加childLevel数字
        this.childLevel=1;
        
        var i = this;
        while(i.hasParent()){
			var parent = i.getParent();
            parent.childLevel = i.getChildLevel()+1;
			i = parent;
        }
    };
    
    return this.child[id];
}

DataNode.prototype.hasChild = function() {
    if (this.child.length > 0) return true;
}

DataNode.prototype.hasParent = function() {
    if (this.parent != null && this.parent instanceof DataNode) return true;
    else return false;
}

DataNode.prototype.getParent = function() {
    if (this.hasParent()) return this.parent;
}

DataNode.prototype.getChildById = function(id) {
    if (this.child[id] != null) return this.child[id];
}

DataNode.prototype.getChildLevel = function() {
    return this.childLevel;
}


/*--------------------------------------------------------------------------*/

function SelectElementInfo(select){
	this.index = select.selectedIndex;
	
	if(this.index == -1){
		this.id = null;
	}else if(this.index >= 0){
		this.id = select.options[this.index].value;
	}
}

/**
 * 绑定下拉选框. 注意(Attention!): 这是个对象, 要用 new 创建
 * @param DataNode	data_node	DataNode数据对象
 * @param Select	selectElement	最顶选框(最顶父选框)
 * @param Select	隐藏参数, 子选框, 可以多个, 父子关系顺序传入
 *
 * @todo	详细解决多选框(multiple), selectedIndex为-1(即没选中)的完全处理(现存在问题(bug) 1.最顶选框不能多选 2.多选时默认选中第一个)
 */
function AttachRelateSelect(data_node, selectElement){
    //data_node不是DataNode对象
	if(!(data_node instanceof DataNode)) return false;
	
	//required 参数
	if(selectElement == undefined) return false;
	
	this.data_node = data_node;
	
	//取得级数,以处理关联菜单级数, 暂未实现, 将来主要是用来控制关联级数
    var level = this.data_node.getChildLevel();
	
	//没下级对象, 退出
	if(level < 1) return false;
	
	//本对象的引用
	var thisObject = this;
	
	//记录select对象,按父子顺序
	if(this.selectElements == undefined){
		this.selectElements = new Array();
	}
	
	this.selectElements.push(selectElement);
	
	//用于this.reset()记录原始值, 
	if(this.selectElementsDefault == undefined){
		this.selectElementsDefault = new Array();
	}
	this.selectElementsDefault.push(new SelectElementInfo(selectElement));
    
	
    //this.changeRel(selectElement, data_node, selectElement.selectedIndex);
	
	//子对象参数开始位
	var start = 2;
	//操作子对象选框
	for(var i=start; i<arguments.length;i++){
		if(i>level) break;
		
		//var childElement = arguments[i];
		
		this.selectElements.push(arguments[i]);
		
		this.selectElementsDefault.push(new SelectElementInfo(arguments[i]));
		
		//this.childElementAttach(selectElement, childElement);
		
		//selectElement = arguments[i];
	}
	
	//解决reset();
	_AddFuncToEvent("onreset", this.selectElements[0].form, function (){thisObject.reset();});
	
}

//子select对象绑定方法
AttachRelateSelect.prototype.start = 
function(){
	this.changeRel(this.selectElements[0], this.data_node, this.selectElementsDefault[0].index);
	
	//操作子对象选框
	for(var i=0; i<this.selectElements.length-1;i++){
		//绑定对象
		this.childElementAttach(this.selectElements[i], this.selectElements[i+1]);
	}
	
	//解决reset();
	//var thisObject = this;
	//_AddFuncToEvent("onreset", this.selectElements[0].form, function (){thisObject.reset();});
};

//子select对象绑定方法
AttachRelateSelect.prototype.childElementAttach = 
function(parent, child){
	if(child.selectedIndex > -1 && child.options[child.selectedIndex].defaultSelected == true){
		this.changeRel(child, parent.data_node.getChildById(parent.options[parent.selectedIndex].value), child.selectedIndex, child.options[child.selectedIndex].value);
	}else{
		this.changeRel(child, parent.data_node.getChildById(parent.options[parent.selectedIndex].value), child.selectedIndex);
	}
	
	var thisObject = this;
	_AddFuncToEvent("onchange", parent, function(){thisObject.changeRel(child, this.data_node.getChildById(this.options[this.selectedIndex].value))});
};

//重置方法
AttachRelateSelect.prototype.reset = 
function(){
	this.changeRel(this.selectElements[0], this.selectElements[0].data_node, this.selectElementsDefault[0].index, this.selectElementsDefault[0].id);
	for(var reset_i=1; reset_i<this.selectElements.length; reset_i++){
		
		this.changeRel(this.selectElements[reset_i], this.selectElements[reset_i-1].data_node.getChildById(this.selectElementsDefault[reset_i-1].id), this.selectElementsDefault[reset_i].index, this.selectElementsDefault[reset_i].id);
		
		/*for test 随时del
		for(var k=0;k<this.selectElements[reset_i].options.length;k++){
			if(this.selectElements[reset_i].options[k].defaultSelected == true){
				alert(this.selectElements[reset_i].name+" "+this.selectElements[reset_i].options[k].text+" id:"+k);
			}
		}
		
		alert(this.selectElements[reset_i].name+" id:"+this.selectElementsDefault[reset_i].id+" index:"+this.selectElementsDefault[reset_i].index+" selectedIndex:"+this.selectElements[reset_i].selectedIndex);
		*/
	}
};

//改变关联对象的方法
/**
 * 关联下拉
 * @param Select	changed		要改变的Select对象
 * @param DataNode	data_node	属于这个选框数据的DataNode数据对象
 * @param int 		index		被选中的数字, 默认是0
 * @param mixed		selected	隐藏参数, 要被设定要选中的值
 */
AttachRelateSelect.prototype.changeRel = 
function changeRel(changed, data_node, index/*, selected*/){
    
	//加多了几个条件,解决多选被自动选中第一项的问题. 可以改进这个if else, 提高一点儿性能
	if(index == undefined && changed.selectedIndex != -1 && changed.type != "select-multiple"){
		index = 0;
    }else if(index == undefined && changed.type == "select-multiple" && changed.selectedIndex == -1){
		index = -1;
	}else if(index == undefined && changed.type == "select-multiple" && changed.selectedIndex != -1 && changed.options[changed.selectedIndex].defaultSelected != true){
		index = -1;
	}
    
    changed.options.length = 0;
    
    changed.data_node = data_node;
    
    var i = 0;
	
    for(var child in data_node.child){
            
        var option = new Option(data_node.getChildById(child).name, data_node.getChildById(child).id);
        
        changed.options[i] = option;
        
        if((arguments.length > 3 || arguments[3] != null) && data_node.getChildById(child).id == arguments[3]) {
			//defaultSelected是用在reset表单时用!!!搞了很久终于明白
			changed.options[i].defaultSelected = changed.options[i].selected = true;
		}
        
        i++;
    }
	
	//无选项时的处理
	//@todo 抽象出来, 可以自定义处理方法
	if(i == 0){
		this.noneOptionsHandler(changed, data_node);
	}else{
		//自定义选项的处理
		var add = this.customOptionsHandler(changed);
		//默认选中了的, 选番!
		if(index >= 0 && !changed.options[index] == false && changed.options[index].defaultSelected == true) index+=add;
	}
    
	if(!(arguments.length > 3 || arguments[3] != null) && index >= -1 && index < changed.options.length) {
		if(index != -1) changed.options[index].defaultSelected = changed.options[index].selected = true;
		changed.selectedIndex = index;
	}
};


/**
 * 改变无对象时处理的方法
 * @param	select	选框对象
 * @param	data_node	父对象的DataNode对象
 * @see changeRel
 */
AttachRelateSelect.prototype.noneOptionsHandler = 
function(select, data_node){
	select.options[0] = new Option(data_node.name, data_node.id);
};

/*
//目的:加入一些自定义选项, 会出现在每个子选项的最顶
*/
//AttachRelateSelect.prototype.customOptions = new Array();

AttachRelateSelect.prototype.setCustomOptions = 
function(options){
	if(this.customOptions == null && typeof(this.customOptions) != "object"){
		this.customOptions = new Array();
	}
	
	this.customOptions.push(options);
};

/**
 * 消除最顶自定义选项
 */
AttachRelateSelect.prototype.clearCustomOptions = 
function(){
	this.customOptions = new Array();
}

/**
 *
 * 用户可以改造的方法
 */
AttachRelateSelect.prototype.customOptionsHandler = 
function(select){
	if(typeof(this.customOptions) == "object" && this.customOptions.length > 0 && this.checkAllowCustomOptions(select.id)){
		var add = 0;
		var newSelect = new Array();
		for(var j=0;j<this.customOptions.length;j++){
			newSelect.push(this.customOptions[j]);
			add++;
		}
		
		for(var j=0;j<select.options.length;j++){
			newSelect.push(select.options[j]);
		}
		
		select.options.length=0;
		try{
			for(var j=0;j<newSelect.length;j++){
				select.options[select.options.length] = newSelect[j];
			}
		}catch(e){
			//alert(e.message);
		}
		
		//返回增加了的个数
		return add;
	}
	
	//没增加
	return 0;
}

/**
 * @param	Array	element_ids	HTML组件的ID数组 
*/
AttachRelateSelect.prototype.setAllowCustomOptions = 
function (element_ids){
	this.allowCustomOptions = element_ids;
}

/**
 * @param	string	element_id	HTML组件的ID
*/
AttachRelateSelect.prototype.checkAllowCustomOptions = 
function (element_id){
	if(typeof(this.allowCustomOptions) == "object" && this.allowCustomOptions.join(' ').indexOf(element_id) != -1){
		return true;
	}else{
		return false;
	}
}
/*--------------------------------------------------------------------------*/
