var defaultOptionText  = "请选择";
var defaultOptionValue = "";
/*
 * 名词：
 * 数据对象: dataObj
 * 分层数据对象数组:
 * 数据对象名称
 * 数据对象缀字
 * 分层数据对象数组名
 * 分层数据对象数组缀字
 * 数据文件
 * 数据名称 relationDataName、dataName
 * 
 * 节点key值
 * 节点名称
 * 节点值
 * 
 */
//==============================================================================
/**
 * 数据对象。
 * 存放关系型下拉选单的数据，呈Tree结构，每一个node都代表一笔数据。
 */
function RelationData (dataName) {
	this.parentNode = null;
	this.name       = null;
	this.value      = null;
	this.nodeKey    = null;
	this.layerNum   = null;
	this.childNodes = new Array();
	
	this.setParentNode = RelationData_setParentNode;
	this.getParentNode = RelationData_getParentNode;
	this.setName       = RelationData_setName;
	this.getName       = RelationData_getName;
	this.setValue      = RelationData_setValue;
	this.getValue      = RelationData_getValue;
	this.setNodeKey    = RelationData_setNodeKey;
	this.getNodeKey    = RelationData_getNodeKey;
	this.setLayerNum   = RelationData_setLayerNum;
	this.getLayerNum   = RelationData_getLayerNum;
	this.addChildNode  = RelationData_addChildNode;
	this.getChildNodes = RelationData_getChildNodes;
	this.clone         = RelationData_clone;
}

/**
 * 设定父节点
 * @param RelationData 物件
 */
function RelationData_setParentNode (parentNode) {
	this.parentNode = parentNode;
}
/**
 * 取得父节点
 * @return RelationData 物件
 */
function RelationData_getParentNode () {
	return this.parentNode;
}

/**
 * 设定节点名称
 * @param String 物件
 */
function RelationData_setName (name) {
	this.name = name;
}

/**
 * 取得节点名称
 * @return String 物件
 */
function RelationData_getName () {
	return this.name;
}

/**
 * 设定节点的值
 * @return String 物件
 */
function RelationData_setValue (value) {
	this.value = value;
}
/**
 * 取得节点的值
 * @param String 物件
 */
function RelationData_getValue () {
	return this.value;
}
/**
 * 设定节点的Key值
 * @return String 物件
 */
function RelationData_setNodeKey (nodeKey) {
	this.nodeKey = nodeKey;
	RelationSelectUtils.addKey(this.nodeKey);
}
/**
 * 设定节点key值
 * @param String 物件
 */
function RelationData_getNodeKey () {
	return this.nodeKey;
}

/**
 * 设定层级
 * @param layerNum int, 层级
 */
function RelationData_setLayerNum (layerNum) {
	this.layerNum = layerNum;
}

/**
 * 取得层级
 * @return int, 层级
 */
function RelationData_getLayerNum () {
	return this.layerNum;
}


/**
 * 加入一个子节点
 * @return RelationData 物件
 */
function RelationData_addChildNode (childNode) {
	this.childNodes.push(childNode);
}

/**
 * 取得所有子节点
 * @return Array 物件
 */
function RelationData_getChildNodes () {
	return this.childNodes;
}

/**
 * Clone 节点 (包括其下的子节点皆会被clone)
 * @return RelationData 物件
 */
function RelationData_clone () {
	var relationData = new RelationData ();
	relationData.setName (this.getName());
	relationData.setValue (this.getValue());
	relationData.setNodeKey (this.getNodeKey());
	if (this.getParentNode() != null) {
		relationData.setParentNode (this.getParentNode().clone());
	}
	
	if (this.getChildNodes() != null && this.getChildNodes().length > 0) {
		for (var i = 0; i < this.getChildNodes().length; i++) {
			relationData.addChildNode (this.getChildNodes()[i].clone());
		}
	}
	
	return relationData;
}
//================================================================================================//
/**
 * RelationSelect 的公用类别
 */
function RelationSelectUtils () {
	
}

RelationSelectUtils.generateDataObjName      = RelationSelectUtils_generateDataObjName;
RelationSelectUtils.generateDataObjLayerName = RelationSelectUtils_generateDataObjLayerName;
RelationSelectUtils.getRootDataObj           = RelationSelectUtils_getRootDataObj;
RelationSelectUtils.getDataObjLayer          = RelationSelectUtils_getDataObjLayer;
RelationSelectUtils.getSubDataObj            = RelationSelectUtils_getSubDataObj;
RelationSelectUtils.parseToDataObjLayer      = RelationSelectUtils_parseToDataObjLayer;
RelationSelectUtils.keyMap                   = new Array();
RelationSelectUtils.addKey                   = RelationSelectUtils_addKey;
RelationSelectUtils.getKey                   = RelationSelectUtils_getKey;
RelationSelectUtils.findDataObjByValue       = RelationSelectUtils_findDataObjByValue;
RelationSelectUtils.getFullName              = RelationSelectUtils_getFullName;
RelationSelectUtils.getName                  = RelationSelectUtils_getName;

/**
 * 产生根数据对象名称，此名称是被拿来当根数据对象的变量名称。
 * @param relationDataName String 对象，数据名称，此参数为必填参数
 * @param nodeKey String 物件，节点key值，此参数为选填参数。
 * @return String 对象，数据对象名称
 */
function RelationSelectUtils_generateDataObjName (relationDataName, nodeKey) {
	nodeKey = nodeKey == null || nodeKey.trim().length == 0 ? "" : RelationSelectUtils.getKey(nodeKey);
	return relationDataName + nodeKey + RelationDataParser.suffix;
}

/**
 * 产生分层数据对象数组名，此名称是被拿来当做分层数据对象数组的变量名称。
 * @param relationDataName String 对象，数据名称，此参数为必填参数
 * @param nodeKey String 物件，节点key值，此参数为选填参数。
 * @return String 对象，分层数据对象数组名
 */
function RelationSelectUtils_generateDataObjLayerName (relationDataName, nodeKey) {
	nodeKey = nodeKey == null || nodeKey.trim().length == 0 ? "" : RelationSelectUtils.getKey(nodeKey);
	return relationDataName + nodeKey + RelationDataParser.layerName;
}

/**
 * 取得根数据对象
 * @param relationDataName String 对象，数据名称，此参数为必填参数
 * @param nodeKey String 物件，节点key值，此参数为选填参数。
 * @return RelationData 物件。根数据对象。
 */
function RelationSelectUtils_getRootDataObj (relationDataName, nodeKey) {
	var dataObjName = RelationSelectUtils.generateDataObjName (relationDataName, nodeKey);
	if (eval("typeof(" + dataObjName + ") == 'undefined'")) {
		return null;
	} else {
		return eval (dataObjName);
	}
}
/**
 * 取得分层数据对象数组
 * @param relationDataName String 对象，数据名称，此参数为必填参数
 * @param nodeKey String 物件，节点key值，此参数为选填参数。
 * @return RelationData 物件。分层数据对象数组。
 */
function RelationSelectUtils_getDataObjLayer(relationDataName, nodeKey) {
	var dataObjLayerName = RelationSelectUtils.generateDataObjLayerName (relationDataName, nodeKey);
	if (eval("typeof(" + dataObjLayerName + ") == 'undefined'")) {
		return null;
	} else {
		return eval (dataObjLayerName);
	}
}
/**
 * 取出根数据对象中，节点key值为传入的nodeKey值的数据对象。
 * @param relationDataName String 对象，数据名称，此参数为必填参数
 * @param nodeKey String 物件，节点key值，此参数为必填参数。
 * @return RelationData 物件。节点key值为传入的nodeKey值的数据对象。
 */
function RelationSelectUtils_getSubDataObj (relationDataName, nodeKey) {
	// 取得根数据对象
	var dataObj = RelationSelectUtils.getRootDataObj(relationDataName);
	if (dataObj != null) {
		// 如果根数据对象的节点key值为传入的节点key值，则回传根数据对象
		if (dataObj.getNodeKey() == nodeKey) {
			return dataObj;
		// 如果根数据对象的节点key值不是传入的节点key值，则往下搜索其子数据对象
		} else {
			return RelationSelectUtils_getDataNodeObjByNodeKey (dataObj, nodeKey);
		}
	} else {
		return null;
	}
}
/**
 * RelationSelectUtils的私有方法。
 * 从传入的数据对象中，找出节点key值为传入的nodeKey值的数据对象。
 * @param dataNodeObj RelationData 对象，要来寻找其下是否有符合nodeKey的子数据对象，此参数为必填参数
 * @param  nodeKey String 物件，节点key值，此参数为必填参数。
 * @return RelationData 物件。节点key值为传入的nodeKey值的数据对象。
 */
function RelationSelectUtils_getDataNodeObjByNodeKey (dataNodeObj, nodeKey) {
	for (var i = 0; i < dataNodeObj.getChildNodes().length; i++) {
		if (dataNodeObj.getChildNodes()[i].getNodeKey() == nodeKey) {
			return dataNodeObj.getChildNodes()[i];
		} else {
			RelationSelectUtils_getDataNodeObjByNodeKey (dataNodeObj.getChildNodes()[i], nodeKey);
		}
	}
}

/**
 * 将传入的数据对象(dataObj)解析到传入的分层数据对象数组(dataObjLayer)中。
 * @param dataObj RelationData 对象，要被解析的数据对象
 * @param dataObjLayer Array 对象，分层数据对象数组。
 * @param layerNum int，目前的层数，从0开始计算。
 */
function RelationSelectUtils_parseToDataObjLayer (dataObj, dataObjLayer, layerNum) {
	// 先判断分层数据对象数组第layerNum层是否尚未宣告，如果尚未宣告则进行宣告的动作。
	if (typeof(dataObjLayer[layerNum]) == 'undefined') {
		dataObjLayer[layerNum] = new Array();
	}
	for (var i = 0; i < dataObj.getChildNodes().length; i++) {
		dataObjLayer[layerNum].push (dataObj.getChildNodes()[i]) ;
		RelationSelectUtils_parseToDataObjLayer (dataObj.getChildNodes()[i], dataObjLayer, layerNum + 1);
	}
}
/**
 * 将节点key值加入key值库里。
 * key值库为一个Map，键值为传入的节点key值，值为随机产生的字符串。
 * 因为节点key值会拿来当做变量名称的一部份，为了防止节点key值中有不合变量宣告规定的字符，
 * 所以使用随机产生的字符串来替代节点key值，而随机字符串与节点key值则使用key值库来做彼此的关联。
 * @param nodeKey String 物件，节点key值，此参数为必填参数。
 */
function RelationSelectUtils_addKey (nodeKey) {
	if (RelationSelectUtils.keyMap[nodeKey] != null) {
		alert ("key is already exist!")
		throw new Error (4000001, "key is already exist!");
	}
	RelationSelectUtils.keyMap[nodeKey] = generateRandomString(10);
}
/**
 * 依传入的节点key值从key值库中取出相对应的随机字符串。
 * key值库为一个Map，键值为传入的节点key值，值为随机产生的字符串。
 * 因为节点key值会拿来当做变量名称的一部份，为了防止节点key值中有不合变量宣告规定的字符，
 * 所以使用随机产生的字符串来替代节点key值，而随机字符串与节点key值则使用key值库来做彼此的关联。
 * @param nodeKey String 物件，节点key值，此参数为必填参数。 
 */
function RelationSelectUtils_getKey (nodeKey) {
	return RelationSelectUtils.keyMap[nodeKey];
}

/**
 * 至指定数据名称(relationDataName + nodeKey)的根数据对象中，取出符合传入节点值的子数据对象。
 * 可指定从那一层开始找起以增进效能，但若指定的层数无法找到符合节点值的子数据对象，则会从最底层开始
 * 重新找起。
 * @param value String 物件，节点值，此参数为必填参数。
 * @param relationDataName String 对象，数据名称，此参数为必填参数。
 * @param nodeKey String 物件，节点key值，此参数为选填参数。
 * @param startLayer int，要从那一层开始搜寻。此参数为选填参数。
 * @return RelationData 物件。节点值符合传入节点值的数据对象。
 */
function RelationSelectUtils_findDataObjByValue (value, relationDataName, nodeKey, startLayer) {
	/*
	 * 因为当User只填入三个值时，第三个值有可能是nodeKey也有可能是startLayer，
	 * 所以要额外再去做判断，看user传入的第三个参数为何
	 */
	if (arguments.length == 3) {
		if (typeof(arguments[2]) == 'string') {
			nodeKey = arguments[2];
			startLayer = null;
		} else if (typeof(arguments[2] == 'number')) {
			startLayer = arguments[2];
			nodeKey = null;
		} else {
			nodeKey = null;
			startLayer = null;
		}
	}
	
	// 取得分层数据对象数组
	var dataObjLayer = RelationSelectUtils.getDataObjLayer(relationDataName, nodeKey);
	if (dataObjLayer == null) {
		alert ("无法取得分层数据对象数组")
		throw new Error(5000602, "can't get data obj layer array.");
	}
	
	// 如果 startLayer 没有指定，则指定成最底层的层数。
	startLayer = startLayer == null ? dataObjLayer.length - 1 : startLayer;
	if (startLayer > dataObjLayer.length - 1) {
		startLayer = dataObjLayer.length - 1;
	}
	
	// 在一开始指定的层级上找寻符合初始值的数据对象
	var subDataObj = null;
	for (var i = 0; i < dataObjLayer[startLayer].length; i++) {
		if (dataObjLayer[startLayer][i].getValue() == value) {
			subDataObj = dataObjLayer[startLayer][i];
			break;
		}
	}
	
	// 如果在指定的层数找不到符合初始值的数据对象，则重新从最底层开始找。
	if (subDataObj == null) {
		for (var i = dataObjLayer.length - 1; i >= 0; i--) {
			for (var j = 0; j < dataObjLayer[i].length; j++) {
				if (dataObjLayer[i][j].getValue() == value) {
					subDataObj = dataObjLayer[i][j];
					layerIndex = i;
					break;
				}
			}
		}
	}
	
	return subDataObj;
}
/**
 * 至指定数据名称(relationDataName + nodeKey)的根数据对象中，将传入节点值转换成节点名称，
 * 并且要包含其所有父节点的节点名称，而每个节点名称之间可用指定的token值来做区隔，若token值没
 * 有输入，预设使用空白值。
 * @param value String 物件，节点值，此参数为必填参数。
 * @param relationDataName String 对象，数据名称，此参数为必填参数。
 * @param nodeKey String 物件，节点key值，此参数为选填参数。
 * @param token String 物件，token值，此参数为选填参数。
 * @param beginLayer int, 从那层父节点开始。此值若大于传入节点值所在节点的层数时，则只会显示该节点值的节点名称
 *                        而不会显示其父节点名称。此参数为选填参数。
 * @return String 对象，包含所有父节点名称的符合传入的节点值的节点名称
 */
function RelationSelectUtils_getFullName (value, relationDataName, nodeKey, token, beginLayer) {
	var dataObjLayer = null;
	/*
	// 由于JS的限制，无法分办出只输入3个参数时，第3个参数到底是nodeKey还是token, 
	// 因此使用下面的方法来强制分办
	if (arguments.length == 3) {
		// 用第3个参数配合数据名称来取出根数据对象
		dataObjLayer = RelationSelectUtils.getDataObjLayer(relationDataName, arguments[2]);
		// 如果能取出根数据对象，则表示第3个参数是nodeKey，若不能则表示第三个参数是token
		if (dataObjLayer != null) {
			nodeKey = arguments[2];
			token   = null;
		} else {
			token   = arguments[2];
			nodeKey = null;
		}
	}
	*/
	var nodeKeyStr    = null;
	var tokenStr      = null;
	var beginLayerNum = 0;
	
	if (arguments.length >= 3 && arguments.length < 5) {
		if (typeof(arguments[2]) == 'number') {
			beginLayerNum = arguments[2];
			// 如果还有第4个参数的话，则继续往下解析
			if (arguments.length == 4) {
				// 用第4个参数配合数据名称来取出根数据对象
				dataObjLayer = RelationSelectUtils.getRootDataObj(relationDataName, arguments[3]);
				// 如果能取出根数据对象，则表示第4个参数是nodeKey，若不能则表示第4个参数是token
				if (dataObjLayer != null) {
					nodeKeyStr = arguments[3];
					tokenStr   = null;
				} else {
					tokenStr   = arguments[3];
					nodeKeyStr = null;
				}
			} else {
				nodeKeyStr = null;
				tokenStr   = null;
			}
		} else {
			// 用第3个参数配合数据名称来取出根数据对象
			dataObjLayer = RelationSelectUtils.getRootDataObj(relationDataName, arguments[2]);
			// 如果能取出根数据对象，则表示第3个参数是nodeKey，若不能则表示第三个参数是token
			if (dataObjLayer != null) {
				nodeKeyStr = arguments[2];
			} else {
				tokenStr   = arguments[2];
			}
			// 如果还有第4个参数的话，则继续往下解析
			if (arguments.length == 4) {
				// 如果第4个参数是数字型态，则第4个参数即是beginLayer
				if (typeof(arguments[3]) == 'number') {
					beginLayerNum = arguments[3];
					// 判断dataObjLayer和nodeKey那个该是null
					// 若能取出根数据对象，表示第3个参数是nodeKey，所以token是null，否则nodeKey就是null
					if (dataObjLayer != null) {
						tokenStr = null;
					} else {
						nodeKeyStr = null;
					} 
				// 如果第4个参数不是数字，则要判断
				// 若能取出根数据对象，表示第3个参数是nodeKey，所以第4个参数就是token, 
				// 否则第4个参数就是nodeKey
				} else {
					if (dataObjLayer != null) {
						tokenStr   = arguments[3];
					} else {
						nodeKeyStr = arguments[3];
					}
					beginLayerNum = 0;
				}
			// 如果没有第4个参数，则要判断dataObjLayer和nodeKey那个该是null
			// 若能取出根数据对象，表示第3个参数是nodeKey，所以token是null，否则nodeKey就是null
			} else {
				if (dataObjLayer != null) {
					tokenStr = null;
				} else {
					nodeKeyStr = null;
				} 
				beginLayerNum = 0;
			}
		}
	} else if (arguments.length >= 5){
		nodeKeyStr    = nodeKey;
		tokenStr      = token;
		beginLayerNum = beginLayer;
	}

	//alert (nodeKeyStr + ":" + tokenStr+ ":" + beginLayerNum)
	// 取得符合value的对象
	var subDataObj  = RelationSelectUtils.findDataObjByValue(value, relationDataName, nodeKeyStr, beginLayerNum);
	// 取出根数据对象
	var rootDataObj = RelationSelectUtils.getRootDataObj(relationDataName, nodeKeyStr);
	
	if (subDataObj == null || rootDataObj == null) {
		return value;
	} else {
		var fullName = "";
		var rootLayerNum = rootDataObj.getLayerNum();
		rootLayerNum = rootLayerNum == null ? 0 : rootLayerNum + 1;
		tokenStr = tokenStr == null ? " " : tokenStr;
		
		do {
			fullName = tokenStr + subDataObj.getName() + fullName;
			subDataObj = subDataObj.getParentNode();
			
		} while (subDataObj != null && subDataObj != rootDataObj && (subDataObj.getLayerNum() != null && subDataObj.getLayerNum() - rootLayerNum >= beginLayerNum));

		// 将开头的token拿掉
		if (fullName.indexOf(tokenStr) == 0) {
			fullName = fullName.substring(tokenStr.length)
		}
		return fullName;
	}
}

/**
 * 至指定数据名称(relationDataName)的根数据对象中，将传入节点值转换成节点名称，
 * 
 * @param value String 物件，节点值，此参数为必填参数。
 * @param relationDataName String 对象，数据名称，此参数为必填参数。
 */
function RelationSelectUtils_getName(value, relationDataName) {
	// 取得符合value的对象
	var dataNodeObj  = RelationSelectUtils.findDataObjByValue(value, relationDataName);
	if (dataNodeObj == null) {
		return value;
	} else {
		return dataNodeObj.getName();
	}
}
//================================================================================================//
/**
 * 数据解析抽象类别，用来解析数据文件。
 * 为interface。
 */
function RelationDataParser() {	
	this.relationDataName = null;
	this.dataObjName      = null;
	this.dataObjLayerName = null;
	this.parse  = RelationDataParse_parse;
	this.parseSubDataObjToRootDataObj = RelationDataParse_parseSubDataObjToRootDataObj;
}
/**
 * 数据对象缀字，
 * 当数据名称加上数据对象缀字即变成数据对象的变量名称
 */
RelationDataParser.suffix    = "DataObject";
/**
 * 分层数据对象数组缀字
 * 当数据名称加上分层数据对象数组缀字，即变成分层数据对象数组的变量名称
 */
RelationDataParser.layerName = "Layer";

/**
 * 进行解析数据文件
 */
function RelationDataParse_parse (){
}

/**
 * 将子数据对象解析成根数据对象，并且有其自己的分层数据对象数组
 * 
 * @param nodeKey String 对象，要成为根数据对象的子数据对象节点key值。此参数为必填参数。
 * @param relationDataName String 对象，数据名称，此参数为选填参数，若此参数不填写，则
 *                         使用该解析器所解析出来的根数据对象。
 */
function RelationDataParse_parseSubDataObjToRootDataObj(nodeKey, relationDataName) {	
	if (nodeKey == null || nodeKey.trim().length == 0) {
		alert("节点key值不可为空值");
		throw new Error (5001001, "nodeKey can't be a null.");
	}
	
	relationDataName = relationDataName == null || relationDataName.trim().length == 0 ?
	                   this.relationDataName : 
	                   relationDataName;
	
	// 先判断以此子数据对象制成的根数据对象是否存在, 如果不存在才继续执行parse的动作
	if (RelationSelectUtils.getRootDataObj(relationDataName, nodeKey) == null) {
		// 从根数据对象中取出节点key值为nodeKey的子数据对象
		var subDataObj = RelationSelectUtils.getSubDataObj(relationDataName, nodeKey);
		if (subDataObj == null) {
			alert ("无法从数据对象(" + relationDataName + ")中取出节点值为(" + nodeKey + ")的子数据对象。");
			throw new Error (5001002, "can't get sub data object.");
		}
		// 将子数据对象存到以「数据对象名称+nodeKey」命名的global变量中，如此该子数据对象就变成根数据对象了。
		eval (RelationSelectUtils.generateDataObjName(relationDataName, nodeKey) + " = subDataObj");
		/*
		 * 完成后，要再依此子数据对象建立子分层数据对象数组。
		 * 子分层数据对象数组命名规则为「分层数据对象数组名 + nodeKey」
		 */
		// 取得子分层数据对象名称
		var dataObjLayerName = RelationSelectUtils.generateDataObjLayerName(relationDataName, nodeKey);
		// new 出子分层数据对象数组
		eval (dataObjLayerName + " = new Array()");
		// 将子数据对象解析成数据分层数组
		RelationSelectUtils.parseToDataObjLayer (subDataObj, eval (dataObjLayerName), 0);
		
	}
}
//================================================================================================//
/**
 * 资料解析器，实作RelationDataParser。
 */
function JsDataParser() {
	this.parse           = JsDataParser_parse;
	this.doParse         = JsDataParser_doParse;
}

function JsDataParser_parse (relationDataName) {
	// 判断以传进来的数据名称命名的变量是否存在
	if (eval("typeof(" + relationDataName + ") == 'undefined'")) {
		alert ("您传进来的关联数据( " + relationDataName + " )并不存在。");
		return;
	}
	this.relationDataName = relationDataName;
	// 为数据对象命名，命名规则为 数据名称 + 缀字
	this.dataObjName = RelationSelectUtils.generateDataObjName(relationDataName);
	// 为分层数组命名。
	this.dataObjLayerName = RelationSelectUtils.generateDataObjLayerName(relationDataName);
	
	// 判断数据对象是否存在，如果不存在才往下进行解析的动作
	if (eval("typeof(" + this.dataObjName + ") == 'undefined'")) {
		var root = new RelationData();
		root.setNodeKey (relationDataName);
		// new 出分层数组
		eval (this.dataObjLayerName + " = new Array()");
		
		
		var dataArray = eval(relationDataName);
		var node      = null;
		var tmp       = null;
		
		// 宣告第０层是一个数组
		eval (this.dataObjLayerName + "[0] = new Array()");
		
		for (var i = 0; i < dataArray.length; i++) {
			tmp  = dataArray[i];
			var node = new RelationData();
			node.setParentNode(root);
			node.setName(tmp.getLabel());
			node.setValue(tmp.getValue());
			node.setLayerNum(0);
			
			this.doParse(node, relationDataName + "Sub0", i, 1);
			
			root.addChildNode (node);
			// 将node放入第０层的分层数组中。
			eval (this.dataObjLayerName + "[0].push(node)");
		}
		
		eval (this.dataObjName + " = root");
		
	} else {
		//alert ("你传进来的关联数据(" + relationDataName + ")已被解析完成。");
	}
	
	// 回传数据对象名称
	// return dataObjName;
}
/**
 * 私有的方法
 * 用来解析资料JS文件的function
 */
function JsDataParser_doParse (dataNode, dataName, index, layerNum) {
	
	if (eval("typeof(" + dataName + ") == 'undefined'") ||
		eval("typeof(" + dataName + "[" + index + "]) == 'undefined'")) {
		return;
	} else {
		var currentDataObj  = eval(dataName + "[" + index + "]");
		var currentDataNode = null;
		
		dataNode.setNodeKey (dataName + "[" + index + "]");
		
		// 判断如果第layerNum层的分层数组尚未存在时，则要将第layerNum层的分层数组宣告出来
		if (eval("typeof(" + this.dataObjLayerName + "[" + layerNum + "])== 'undefined'")) {
			eval (this.dataObjLayerName + "[" + layerNum + "] = new Array();");
		}
		
		for (var i = 0; i < currentDataObj.length; i++) {
			currentDataNode = new RelationData();
			currentDataNode.setParentNode (dataNode);
			currentDataNode.setName (currentDataObj[i].getLabel());
			currentDataNode.setValue (currentDataObj[i].getValue());
			currentDataNode.setLayerNum (layerNum);
			this.doParse (currentDataNode, dataName + "Sub" + index, i, layerNum + 1);
			dataNode.addChildNode (currentDataNode);
			// 将属于第layerNum层的数据对象放入第layerNum层的分层数组中
			eval (this.dataObjLayerName + "[" + layerNum + "].push(currentDataNode)");
		}
	}
}

JsDataParser.prototype = new RelationDataParser();

//================================================================================================//
/**
 * 关系型下拉选单。
 * 在使用RelationSelect对象的过程中，会为Select对象加入以下几个参数。
 * 1. defaultText：该Select对象的预设文字
 * 2. defaultValue：该Select对象的默认值
 * 3. rsObj：属于该Select对象的RelationSelect对象
 * 4. relationIndex：该Select对象在关联Select中的位置(即RelationSelect对象里selectObjs数组中的index值)
 * 5. this.selectObjs[i].hiddenDefaultOption：该Select对象是否要隐藏预设选项
 * -- 4. current --
 * 
 * parameter:
 *     dataObjName:
 *         必填；用来设定本组关系型下拉选单所要取用的数据名称。
 *     nodeKey:
 *         选用；当本组关系型下拉选单只需要使用数据中某节点以下的数据时，传入该节点的key值即可。
 *     relationDataParser:
 *         选用；若所要取用的资料尚未被解析，可以使用传入的数据解析对象来进行解析。
 *              如果数据尚未解析且user也未传入解析对象，则会自动使用JsDataParser来进行解析。
 */
function RelationSelect(dataName, nodeKey, relationDataParser) {
	this.dataName            = null;
	this.nodeKey             = null;
	this.relationDataParser  = null;
	this.defaultText         = null;
	this.defaultValue        = null;
	this.shiftOptions        = true;
	this.hiddenDefaultOption = false;
	this.selectObjs  = new Array();
	
	// method
	// 初始化关系型下拉选单
	this.init = RS_init;
	// 设定关系型select对象
	this.setRelationSelect                  = RS_setRelationSelect;
	// 加入一个开联式select对象
	this.addRelationSelect                  = RS_addRelationSelect;
	// 加入一个关系型select对象，并为这个关系型对象建立一个专属的预设选项
	this.addRelationSelectAndDefaultValue   = RS_addRelationSelectAndDefaultValue;
	// 加入一个不需要预设选项的关系型select对象
	this.addRelationSelectAndNoDefaultValue = RS_addRelationSelectAndNoDefaultValue;
	// 加入一个隐藏式预设选项的关系型select对象
	this.addRelationSelectAndHiddenDefaultValue = RS_addRelationSelectAndHiddenDefaultValue;
	// 统一处理加入关系型Select对象的method，基本上这个method是属于RelationSelect的私有方法，不可在RelationSelect外呼叫。
	this.addRelationSelectOperator          = RS_addRelationSelectOperator;
	// 设定一个for本组内的所有关系型对象的预设选项，请注意，这个method必需在加入关系型Select对象前设定。
	this.setDefaultOption                   = RS_setDefaultOption;
	// 设定是否所有的关系型对象都要使用「隐藏预设选项」的功能，请注意，这个method必需在finish前设定
	this.setHiddenDefaultOption             = RS_setHiddenDefaultOption;
	// 完成所有设定
	this.finish                             = RS_finish;
	// 设定初始值
	this.setInitValue                       = RS_setInitValue;
	// 设定当下层无符合的数据时，是否要将本层所选择的option移到下层
	this.setShiftOptions                    = RS_setShiftOptions;
	
	if (arguments.length < 1 || arguments.length > 3) {
		alert ("输入的参数数量不正确")
		throw new Error (5000001, "arugment amount incorrectly.");
	}
	
	if (typeof(arguments[0]) != 'string') {
		alert ("请输入数据名称");
		throw new Error (5000002, "no data name.");
	} else {
		this.dataName = arguments[0];
	}
	
	if (arguments.length == 2) {
		if (typeof(arguments[1]) == 'string') {
			this.nodeKey = arguments[1];
		} else if (arguments[1] instanceof RelationDataParser) {
			this.relationDataParser = arguments[1];
		} else {
			alert ("传入的第二个参数必需是节点的key值或是解析对象。");
			throw new Error(500003, "argument must be a node key or a parser object.");
		}
	} else if (arguments.length == 3) {
		if (typeof(arguments[2]) != 'string') {
			alert ("传入的第二个参数必需是节点的key值");
			throw new Error(500004, "argument must be a node key value.");
		}
		if (!arguments[2] instanceof RelationDataParser) {
			alert ("传入的第三个参数必需是解析物件");
			throw new Error(500005, "argument must be a parser object.");
		}
	}
	
	this.init();
}

/**
 * 私有方法。
 * 初始化 RelationSelect 物件。
 */
function RS_init() {
	var dataObjName = RelationSelectUtils.generateDataObjName (this.dataName);
	// 先判断数据对象是否存在
	if (eval("typeof(" + dataObjName + ") == 'undefined'")) {
		// 如果数据对象不存在，则要进行数据的解析。
		// 再判断user是否有传入解析器，如果有则用user的解析器，如果没有则用预设的JsDataParser解析器来对数据进行解析
		if (this.relationDataParser == null) {
			this.relationDataParser = new JsDataParser();
		}
		this.relationDataParser.parse(this.dataName);
	}
	// 判断如果是用数据中的子数据来当本组关联Select对象所参照的data时，则进行以下步骤
	if (this.nodeKey != null) {
		//this.relationDataParser.parseSubDataObjToRootDataObj(this.nodeKey);
		new RelationDataParser().parseSubDataObjToRootDataObj(this.nodeKey, this.dataName);
	}
}

/**
 * 设定多个关联的Select对象。
 * 这些Select对象会使用RelationSelect的预设文字和默认值，
 * 若RelationSelect没有设定预设文字和默认值，则使用公用的预设文字和默认值。
 * 
 * @param selectObj Select物件。必填参数。
 */
function RS_setRelationSelect(selectObj) {
	for (var i = 0; i < arguments.length; i++) {
		this.addRelationSelect(arguments[i]);
	}
}
/**
 * 加入一个关联的Select对象。
 * 该Select对象会使用RelationSelect的预设文字和默认值，
 * 若RelationSelect没有设定预设文字和默认值，则使用公用的预设文字和默认值。
 * 
 * @param selectObj Select物件。必填参数。
 */
function RS_addRelationSelect(selectObj) {
	// 使用RelationSelect的预设文字和默认值，若RelationSelect没有设定预设文字和默认值，则使用公用的预设文字和默认值。
	if (this.defaultText == null || this.defaultValue == null) {
		this.addRelationSelectOperator (selectObj, defaultOptionText, defaultOptionValue);
	} else {
		this.addRelationSelectOperator (selectObj, this.defaultText, this.defaultValue);
	}
}
/**
 * 加入一个指定默认值和预设文字的Select对象。
 * 
 * @param selectObj Select物件。必填参数。
 * @param defaultText String对象，预设文字。必填参数。
 * @param defalutValue String对象，默认值。必填参数。
 */
function RS_addRelationSelectAndDefaultValue(selectObj, defaultText, defaultValue) {
	if (arguments.length != 3) {
		alert ("输入参数错误！\n 请依序输入 Select 对象、预设文字、默认值。")
		throw new Error(5000201, "arguemnt incorrectly.");
	}
	
	// 检查传进来的预设文字
	if (defaultText == null) {
		alert ("传进来的预设文字不可为 null")
		throw new Error(5000202, "default text can't be a null.");
	}
	if (typeof(defaultText) != "string") {
		alert ("传进来的预设文字必需是字符串")
		throw new Error(5000203, "default text must be a string.");
	}

	// 检查传进来的默认值
	if (defaultValue == null) {
		alert ("传进来的默认值不可为 null")
		throw new Error(5000204, "default value can't be a null.");
	}
	if (typeof(defaultValue) != "string" && typeof(defaultValue) != "number") {
		alert ("传进来的默认值必需是字符串或是数字")
		throw new Error(5000205, "default text must be a string.");
	}	
	
	this.addRelationSelectOperator (selectObj, defaultText, defaultValue);
}

/**
 * 加入Select对象，且此Select对象不使用默认值。
 * 
 * @param selectObj Select物件。必填参数。
 */
function RS_addRelationSelectAndNoDefaultValue(selectObj) {
	this.addRelationSelectOperator (selectObj, null, null);
}

/**
 * 加入一个隐藏式预设选项的关系型select对象。
 * 
 * @param selectObj Select物件。必填参数。
 * @param defaultText String对象，预设文字。必填参数。
 * @param defalutValue String对象，默认值。必填参数。
 */
function RS_addRelationSelectAndHiddenDefaultValue (selectObj, defaultText, defaultValue) {
	this.addRelationSelectAndDefaultValue(selectObj, defaultText, defaultValue);
	selectObj.hiddenDefaultOption = true;
}

/**
 * 统一处理加入一个Select对象的方法，为一私有方法。
 * 
 * @param selectObj Select物件。必填参数。
 * @param defaultText String对象，预设文字。必填参数。
 * @param defalutValue String对象，默认值。必填参数。
 */
function RS_addRelationSelectOperator(selectObj, defaultText, defaultValue) {
	// 先检查传进来select对象
	if (!RS_vaildateSelectObj (selectObj, this.selectObjs.length + 1)) {
		throw new Error (5000200, "incorrect select object .");
	}
	
	selectObj.defaultText  = defaultText;
	selectObj.defaultValue = defaultValue;
	
	selectObj.rsObj = this;
	selectObj.relationIndex = this.selectObjs.length;
	
	// 如果select对象数组中已存有select对象，则在将本selectObj加入之前，将目前数组中最后一个
	// select 取出并设定其处理onchange的function。
	if (this.selectObjs.length > 0) {
		try {
			this.selectObjs[this.selectObjs.length - 1].attachEvent("onchange", RS_changeRelationSelect);
		} catch (e) {
			try {
				this.selectObjs[this.selectObjs.length - 1].addEventListener ("change", RS_changeRelationSelect, false);
			} catch (e) {
				this.selectObjs[this.selectObjs.length - 1].onchange = RS_changeRelationSelect;
			}
		}
	}
	
	// 将selectObj加入到select对象数组中
	this.selectObjs.push(selectObj);
}

/**
 * 设定RelationSelect对象共享的预设文字和默认值。
 * 此方法必需在加入任何一个Select对象前呼叫。
 * 
 * @param defaultText String对象，预设文字。必填参数。
 * @param defalutValue String对象，默认值。必填参数。
 */
function RS_setDefaultOption(defaultText, defaultValue) {
	if (this.selectObjs.length > 0) {
		alert ("这个方法必需在加入Select对象前呼叫");
		throw new Error (5000300, "this mehtod must be called before add select obj.");
	}
	
	// 检查传进来的预设文字
	if (defaultText == null) {
		alert ("传进来的关联预设文字不可为 null")
		throw new Error(5000201, "default text can't be a null.");
	}
	if (typeof(defaultText) != "string") {
		alert ("传进来的关联预设文字必需是字符串")
		throw new Error(5000202, "default text must be a string.");
	}
	
	// 检查传进来的默认值
	if (defaultValue == null) {
		alert ("传进来的关联默认值不可为 null")
		throw new Error(5000303, "default value can't be a null.");
	}
	if (typeof(defaultValue) != "string" && typeof(defaultValue) != "number") {
		alert ("传进来的关联默认值必需是字符串或是数字")
		throw new Error(5000304, "default text must be a string.");
	}	
	
	this.defaultText  = defaultText;
	this.defaultValue = defaultValue;
	
}

/**
 * 设定是否所有的关系型对象都要使用「隐藏预设选项」的功能，请注意，这个method必需在finish前设定
 * 
 * @param defaultText boolean值，是否使用「隐藏预设选项」。必填参数。
 */
 
function RS_setHiddenDefaultOption (hiddenDefaultOption) {
	// 检查传进来的参数
	if (hiddenDefaultOption == null) {
		alert ("传进来的是否使用「隐藏预设选项」参数不可为 null")
		throw new Error(5000401, "argument 'hidden default option' can't be a null.");
	} else if (typeof(hiddenDefaultOption) != 'boolean') {
		alert ("传进来的是否使用「隐藏预设选项」参数必需是boolean值")
		throw new Error(5000402, "argument 'hidden default option' must be a boolean.");
	}
	
	this.hiddenDefaultOption = hiddenDefaultOption;
}


/**
 * 当所有RelationSelect对象的设定皆已完成时一定要呼叫的方法。
 * 此方法除了会判断是否有加入Select对象，并且还执行初始下拉选项的设定工作。
 */
function RS_finish() {
	if (this.selectObjs.length == 0) {
		alert ("您没有加入任何 Select 对象");
		throw new Error(5000401, "there has no any select object.");
	}
	
	for (var i = 1; i < this.selectObjs.length; i++) {
		if (this.selectObjs[i].hiddenDefaultOption == null) {
			this.selectObjs[i].hiddenDefaultOption = this.hiddenDefaultOption;
		}
	}
	
	RS_setOptions(RelationSelectUtils.getRootDataObj(this.dataName, this.nodeKey), this.selectObjs[0]);
}
/**
 * 设定初始值
 * 若selectObj参数有值，则会以selectObj所在的层级开始搜寻，
 * 若搜寻不到或是selectObj为null，则从最底层开始搜寻。
 * 
 * @param initValue String 物件，初始值。必填
 * @param selectObj String 对象，要被设定的Select对象。选填
 */
function RS_setInitValue(initValue, selectObj) {
	var layerIndex = this.selectObjs.length - 1;
	if (selectObj != null) {
		// 先检查传进来select对象
		if (selectObj.relationIndex == null) {
			alert("要设定初值的select对象尚未加入关联");
			throw new Error(5000601, "select object not yet join relation.");
		} else {
			layerIndex = selectObj.relationIndex;
		}
	}
	
	// 取得分层数据对象数组
	var dataObjLayer = RelationSelectUtils.getDataObjLayer(this.dataName, this.nodeKey);
	if (dataObjLayer == null) {
		alert ("无法取得分层数据对象数组")
		throw new Error(5000602, "can't get data obj layer array.");
	}
	
	// 开始在一开始指定的层级上找寻符合初始值的数据对象
	var subDataObj = null;
	for (var i = 0; i < dataObjLayer[layerIndex].length; i++) {
		if (dataObjLayer[layerIndex][i].getValue() == initValue) {
			subDataObj = dataObjLayer[layerIndex][i];
			break;
		}
	}
	
	// 如果在指定的层数找不到符合初始值的数据对象，则从最底层开始找。
	if (subDataObj == null) {
		for (var i = this.selectObjs.length - 1; i >= 0; i--) {
			for (var j = 0; j < dataObjLayer[i].length; j++) {
				if (dataObjLayer[i][j].getValue() == initValue) {
					subDataObj = dataObjLayer[i][j];
					layerIndex = i;
					break;
				}
			}
		}
	}
	
	if (subDataObj == null) {
		alert ("无法找到指定的初始值！");
		throw new Error(5000602, "can't set init value.");
	} else {
		var offset           = 0;
		var parentDataObj    = null;
		var settingSelectObj = null;
		var nextDataObj      = subDataObj;
		
		for (var i = layerIndex; i >= 0; i --) {
			// 取出父数据对象
			parentDataObj = subDataObj.getParentNode();

			// 取出要被设定的关联select对象
			settingSelectObj = this.selectObjs[i];
			
			if (parentDataObj == null) {
				alert ("不正确的错误！父数据对象为null");
				throw new Error(5000603, "parent data object is null.");
			} else if (settingSelectObj == null){
				alert ("不正确的错误！无法取得要被设定的Select对象");
				throw new Error(5000603, "can't get select object.");				
			} else {
				RS_setOptions(parentDataObj, settingSelectObj, false);
			}
			
			if (settingSelectObj.defaultText != null && settingSelectObj.defaultValue != null) {
				offset = 1;
			}
			
			// 处理 hidden default Option
			// 如果要被设定的select对象的「隐藏预设选项」是true，则往下执行
			if (settingSelectObj.hiddenDefaultOption != null && settingSelectObj.hiddenDefaultOption) {
				// 将偏移量设成 0
				offset = 0;
				// 如果该select对象有选项，且第一个选项为默认值，则将默认值选项移除
				if (settingSelectObj.options.length > 0 && settingSelectObj.options[0].value == settingSelectObj.defaultValue) {
					settingSelectObj.options[0] = null;
				}
			}

			for (var j = 0; j < parentDataObj.getChildNodes().length; j++) {
				if (parentDataObj.getChildNodes()[j] == subDataObj) {
					settingSelectObj.selectedIndex = j + offset;
					break;
				}
			}
			subDataObj = parentDataObj;
		}
		
		// 设定下层对象
		if (this.selectObjs[layerIndex + 1] != null) { // 表示有下层select对象
			RS_setOptions(nextDataObj, this.selectObjs[layerIndex + 1]);
		}
	}
}
/**
 * 设定当下层Select对象没有数据可以当成选项时，是否要将本层Select对象目前所选择到的
 * 选项当成下层Select对象的选项。
 * 
 * @param shiftOptions 布尔值。true:是 false:否
 */
function RS_setShiftOptions(shiftOptions) {
	if (typeof(shiftOptions) != 'boolean') {
		alert ("输入的shiftOptions参数必需为布尔值")
		throw new Error(5000701, "argument 'shiftOptions' must be a boolean.");
	}
	this.shiftOptions = shiftOptions;
}

/**
 * 私有方法
 * 检查传进来的Select对象是否为正确的Select对象。
 * 
 * @param selectObj Select 物件，必填
 * @param index int，第几个Select物件。必填。
 */
 function RS_vaildateSelectObj(selectObj, index) {
 	if (selectObj == null) {
 		alert ("要加入的第" + index + "个select对象是null");
 		return false;
 	}
 	
 	if (selectObj.length != null && selectObj.length > 0) {
		alert ("要加入的第" + index + "个select对象存在着两个以上相同的对象，请确实指定要加入的select对象");
		return false;
	}
	if (!isSpecifyHtmlTag("SELECT", selectObj)) {
		alert ("加入关联select数组发生错误！\n要加入关联select数组的第" + index + "个对象必需是Select对象");
		return false;
	}
	return true;
 }
 
/**
 * 私有方法，
 * 设定下拉选项。
 * 
 * @param dataObj RelationData 物件。数据对象。必填。
 * @param selectObj Select 物件。必填。
 * @param needDelUnderlayerOptions 布尔值。是否需要将下层Select对象中的选项全部清除
 *                                 true or null : 清除
 *                                 false        : 不清除
 */
function RS_setOptions(dataObj, selectObj, needDelUnderLayerOptions) {
	if (dataObj == null) {
		alert ("取得的数据对象是 null");
		throw new Error(5000501, "data object is null.");
	}
	if (selectObj == null) {
		alert ("要设定Option的Select对象是null");
		throw new Error(5000502, "select object is null.");
	}
	
	var hiddenDefaultOption = false; // 是否需要隐藏默认值
	
	// 将目前要设定的select对象以及其下层select对象的option全部删除，并设上默认值
	if (needDelUnderLayerOptions == null || needDelUnderLayerOptions) {
		for (var i = selectObj.relationIndex; i < selectObj.rsObj.selectObjs.length; i++) {
			hiddenDefaultOption = RS_needHiddenDefaultOption (selectObj.rsObj.selectObjs[i]);
			deleteAllSelectOptions(selectObj.rsObj.selectObjs[i]);
			if (!hiddenDefaultOption && selectObj.rsObj.selectObjs[i].defaultText != null && selectObj.rsObj.selectObjs[i].defaultValue != null) {
				selectObj.rsObj.selectObjs[i].options[0] = new Option(selectObj.rsObj.selectObjs[i].defaultText, selectObj.rsObj.selectObjs[i].defaultValue);
			}
		}
	}
		
	hiddenDefaultOption = RS_needHiddenDefaultOption (selectObj);
	
	// 计算偏移值
	var offset = 0;
	if (!hiddenDefaultOption && selectObj.defaultText != null && selectObj.defaultValue != null) {
		offset = 1;
	}

	if (dataObj.getChildNodes().length == 0) {
		if (selectObj.relationIndex > 0 && selectObj.rsObj.shiftOptions) {
			var upperSelectObj = selectObj.rsObj.selectObjs[selectObj.relationIndex - 1];
			selectObj.options[0 + offset] = new Option(upperSelectObj.options[upperSelectObj.selectedIndex].text, upperSelectObj.options[upperSelectObj.selectedIndex].value);
		}
	} else {
		for (var i=0; i<dataObj.getChildNodes().length; i++) {
			selectObj.options[i + offset] = new Option(dataObj.getChildNodes()[i].name, dataObj.getChildNodes()[i].value);
		}
	}
}

/**
 * 共享方法
 */
function RS_changeRelationSelect(theEvent) {
	// 取得触发事件的Select对象
	var srcObj = null;
	try {
		srcObj = event.srcElement;
	} catch (e) {
		try {
			srcObj = theEvent.target;
		} catch (e) {
			alert ("取得事件来源对象失败");
			throw new Error (5000100, "can't get error source.");
		}
	}
	RS_handleSelectChange (srcObj);
}

function RS_handleSelectChange (selectObj) {
	var rsObj = selectObj.rsObj; 
	
	// 如果select对象有默认值，且目前选到的是默认值，则清除掉该select对象之下的所有select对象的option
	if (selectObj.defaultText != null && selectObj.defaultValue != null && selectObj.selectedIndex == 0) {
		for (var i = selectObj.relationIndex + 1; i < rsObj.selectObjs.length; i++)	 {
			deleteAllSelectOptions(rsObj.selectObjs[i]);
			if (rsObj.selectObjs[i].defaultText != null && rsObj.selectObjs[i].defaultValue != null) {
				rsObj.selectObjs[i].options[0] = new Option(rsObj.selectObjs[i].defaultText, rsObj.selectObjs[i].defaultValue);
			}
		}
	} else {
		// 组合使用的数据对象名称
		var dataName = RelationSelectUtils.generateDataObjName(rsObj.dataName, rsObj.nodeKey);
		//var dataName = rsObj.dataName;
		//if (rsObj.nodeKey != null) {
		//	dataName = rsObj.dataName + RelationSelectUtils.getKey(rsObj.nodeKey);
		//} else {
		//	dataName = RelationSelectUtils.generateDataObjName(dataName);
		//}
		
		// 取得使用的数据对象
		var dataObj = RelationSelectUtils.getRootDataObj(rsObj.dataName, rsObj.nodeKey);
		//var dataObj = eval (dataName);
		
		// 判断使用的数据对象是否存在
		if (dataObj == null) {
			alert ("无法取得使用的数据(" + dataName + ")");
			throw new Error (5000400, "can't find data object (" + dataName + ").");
		}
		
		
		// 取得下一层的select 对象
		var nextSelectObj = rsObj.selectObjs[selectObj.relationIndex + 1];
		if (nextSelectObj != null) {
			// 取得selectedIndex的偏移量，如果select对象有默认值，则偏移量为1
			var offset = 0;
			if (selectObj.defaultText != null && selectObj.defaultValue != null) {
				offset = 1;
			}
			
			// 取得user所选取的sub data obj
			var subDataObj = dataObj;
			for (var i = 0; i <= selectObj.relationIndex; i++) {
				subDataObj = subDataObj.getChildNodes()[rsObj.selectObjs[i].selectedIndex - offset];
			}
			RS_setOptions(subDataObj, nextSelectObj);
		}
	}
}

function RS_needHiddenDefaultOption (selectObj) {
	var needHiddenDefaultOption = false;
	// 如果该下拉选单的「隐藏默认值」参数有设定，且为true，则往下执行
	if (selectObj.hiddenDefaultOption != null && selectObj.hiddenDefaultOption) {
		// 取出该下拉选单的上一层下拉选单
		var preSelectObj = selectObj.rsObj.selectObjs[selectObj.relationIndex - 1];
		// 若该下拉选单有上一层的关联下拉选单，则往下执行
		if (preSelectObj != null) {
			// 如果上一层的下拉选单有默认值，且上一层下拉选单有选值并且其所选到的值不为默认值，则要将「隐藏默认值」变量设成true
			if ((preSelectObj.defaultText != null && preSelectObj.defaultValue != null) && 
			    (preSelectObj.selectedIndex >= 0 && preSelectObj.options[preSelectObj.selectedIndex].value != preSelectObj.defaultValue))  {
				needHiddenDefaultOption = true;
			}
		}
	}
	return needHiddenDefaultOption;
}
//================================================================================================//
// 以下的Funtion 皆为向下兼容1.0版
function converToText (relationDataName, value) {
	if (RelationSelectUtils.getRootDataObj(relationDataName) == null) {
		new JsDataParser().parse(relationDataName);
	}
	
	return RelationSelectUtils.getName(value, relationDataName);
}
function converToText4StringCode (relationDataName, stringValue, token) {
	if (arguments.length < 3 || token == "") {
		token = ",";
	}
	
	var valueArray = stringValue.split(token);
	var textString = "";
	
	for (var i = 0; i < valueArray.length; i++) {
		textString += converToText (relationDataName, valueArray[i].trim());
		textString += token + " ";
	}
	
	if (textString.trim().length > 0) {
		return textString.substring(0, textString.length - 2); // 减2是因为字尾有一个空白字符
	} else {
		return "";
	}
}

function converToFullText (relationDataName, value, token, beginLayer) {
	if (arguments.length == 2) {
		token      = " ";
		beginLayer = 0;
	} else if (arguments.length == 3) {
		if (isNaN (arguments[2])) {
			token      = arguments[2];
			beginLayer = 0;
		} else {
			beginLayer = arguments[2];
			token      = " ";
		}
	}
	
	if (RelationSelectUtils.getRootDataObj(relationDataName) == null) {
		new JsDataParser().parse(relationDataName);
	}
	
	return RelationSelectUtils.getFullName(value, relationDataName, token, beginLayer);
}

function converToFullText4StringCode (relationDataName, stringValue, token, tokenString, beginLayer) {
	if (arguments.length < 3 || token == "") {
		token = ",";
	}
	
	var valueArray = stringValue.split(token);
	var textString = "";
	
	for (var i=0; i<valueArray.length; i++) {
		textString += converToFullText (relationDataName, valueArray[i].trim(), tokenString, beginLayer);
		textString += token + " ";
	}
	
	if (textString.trim().length > 0) {
		return textString.substring(0, textString.length - 2); // 减2是因为字尾有一个空白字符
	} else {
		return "";
	}
}
