﻿/**
 * VFDL节点基础解析类
 * VFDL节点基础解析类
 *
 * @param node:		[IN]/CVFDLNode节点
 * @param nameSpace:[IN]/起始名字空间
 *
 * @author	2006-07-21	yangzhang
*/
function CVFDLItem(node, nameSpace)
{
	// 定义公共成员
	/** 名字空间 */
	if (nameSpace == null)
		nameSpace = "VFDLItem";
	this.NameSpace = nameSpace;
		
	/** 解析类类型 */
	this.GetClass				= function() {return CVFDLItem;}

	/** 别名 */
	this.GetAlias				= function() {return node.GetNodeText("@alias");}
	/** ID */
	this.GetID					= function() {return node.GetNodeText("@id");}
	/** 类型 */
	this.GetType				= function() {return node.XmlNode.tagName;}
	/** 属性 */
	this.GetAttr				= function() {return node.GetNodeText("@attribute");}
	/** 摘要 */
	this.GetAbstract			= function() {return node.XmlNode.selectSingleNode("@abstract") ?  node.GetNodeText("@abstract") : node.GetNodeText("abstract"); }
	/** 扩展类型 */
	this.GetExtendType			= function() {return node.GetNodeText('var[@name="extendtype"]/@value');}
	
	/** 创建时间 */
	this.GetCreateTime			= function() {return node.GetNodeText("@created");}
	/** 更新时间 */
	this.GetLastUpdateTime		= function() {return node.GetNodeText("@lastupdated");}

	/** 文档属性 */
	this.GetContent				= function() {return node.GetNodeText("@content");}
	/** 关联文件所有者 */
	this.GetOwnership			= function() {return node.GetNodeText("@ownership");}
	/** 关联文件位置 */
	this.GetFilePos				= function() {return node.GetNodeText("@src");}
	
	/** 主题 */
	this.GetSubject				= function() {var subject = node.GetNodeText("@subject"); if (subject == null || subject == "") subject = this.GetAlias(); return subject;}
	/** 文档类型 */
	this.GetContentType			= function() {return GetContentField(this.GetContent(), "type");}
	/** 文档处理类 */
	this.GetContentClass		= function() {return GetContentField(this.GetContent(), "class");}
	/** 文档存储模式 */
	this.GetContentDocMode		= function() {return GetContentField(this.GetContent(), "doc_mode");}
	/** 文档查看模式 */
	this.GetContentViewMode		= function() {return GetContentField(this.GetContent(), "view_mode");}
	/** 文档打包模式 */
	this.GetCoontentPackageMode	= function() {return GetContentField(this.GetContent(), "package_mode");}
	/** 文档系统类型 */
	this.GetContentOS			= function() {return GetContentField(this.GetContent(), "os");}
	
	/**
	* 合成content字段
	* 合成content字段
	*
	* @param type:			[IN]/类型
	* @param docClass:		[IN]/文档类
	* @param docMode:		[IN]/文档模式
	* @param viewMode:		[IN]/浏览模式
	* @param packageMode:	[IN]/打包模式
	* @param os:			[IN]/系统类型
	* @return string
	*
	* @author	2006-07-21	yangzhang
	*/
	function ComposeContent(type, docClass, docMode, viewMode, packageMode, os)
	{
		return "type=" + (type ? type : "")
			+ ";class=" + (docClass ? docClass : "")
			+ ";docmode=" + (docMode ? docMode : "")
			+ ";viewmode=" + (viewMode ? viewMOde : "")
			+ ";packageMode=" + (packageMode ? packageMode : "")
			+ ";os=" + (os ? os : "");
	}
	
	/**
	* 读取content属性
	* 读取content属性
	*
	* @param content:   [IN]/Content字段
	* @param name:		[IN]/属性名称
	* @return string
	*
	* @author	2006-07-21	yangzhang
	*/
	function GetContentField(content, name)
	{
		if (content != null)
		{
			var fieldList = ("type=" + content).split(";");
			
			for (var i = 0; i < fieldList.length; i++)
			{
				var field = fieldList[i].split("=");
				if (field.length == 2 && field[0].toLowerCase() == name.toLowerCase())
					return field[1];
			}
		}

		return "";
	};	
}

/**
 * VFDL节点类
 * VFDL节点类
 *
 * @param nameSpace:[IN]/起始名字空间，为空则使用"VFDLNode"
 * @param explicit:	[IN]/属性引用是否需要显式包括起始名字空间，为空则为false
 *
 * @author	2006-07-21	yangzhang
*/
function CVFDLNode(nameSpace, explicit)
{
	// 定义公共成员
	/** Xml节点 */
	this.XmlNode	= null;
	
	/** 名称空间 */
	if (nameSpace == null)
		nameSpace = "VFDLNode";	
	
	var ob = this;
	var nameList = nameSpace.split(".");
	for (var i = 0; i < nameList.length - 1; i++)
	{
		var newOb = new Object();			
		if (ob.NameSpace == null)
			newOb.NameSpace = nameList[i];
		else
			newOb.NameSpace = ob.NameSpace + "." + nameList[i];
		
		ob[nameList[i]] = newOb;
		this[nameList[i]] = newOb;
		
		ob = newOb;
	}
	if (nameList.length > 0)
	{
		ob[nameList[nameList.length - 1]]	= this;
		this[nameList[nameList.length - 1]] = this;
	}
	this.NameSpace= nameSpace;
	
	/** 显示起始名字空间标志 */
	this.ExplicitName	= explicit;
	/** 解析类类型 */
	this.GetClass		= function() {return CVFDLNode;}
	/** 文档名字 */
	this.GetDocName		= function() {return this.XmlNode.ownerDocument.lastChild.nodeName;}

	/**
	 * 加载数据类
	 * 加载数据类
	 *
	 * @param newXmlNode:[IN]/数据节点XmlNode
	 * @return null
	 *
	 * @author 2006-07-21	yangzhang
	*/
	this.LoadXmlNode = function(newXmlNode)
	{
		this.XmlNode = newXmlNode;
	}

	/**
	 * 读取指定节点值
	 * 读取指定节点值
	 *
	 * @param xPath:[IN]/节点路径
	 * @param list: [IN]/当xPath指定了多个节点，是否以列表形式返回数据
	 * @return string/array
	 *
	 * @author 2006-07-21	yangzh
	*/
	this.GetNodeText = function(xPath, list)
	{
		return CXUtility.GetXmlNodeText(this.XmlNode, xPath, list);
	}

	/**
	 * 读取属性值
	 * 读取属性值
	 *
	 * @param attr:[IN]/属性全名称
	 * @return string
	 *
	 * @author 2006-07-21	yangzh
	*/
	this.GetAttrValue = function(attr)
	{
		if (this.ExplicitName && attr.indexOf(this.NameSpace) != 0)
			return "";

	
		var ob = this;
		var nameList = attr.split(".");
		for (var i = 0; i < nameList.length - 1; i++)
		{
			ob = ob[nameList[i]];
			if (ob == null)
				break;
		}
		
		if (ob != null && nameList.length > 0)
		{
			var obTmp1 = ob[nameList[nameList.length - 1]];
			var obTmp2 = ob["Get" + nameList[nameList.length - 1]];
			
			if (typeof obTmp1 == "function")
				ob = obTmp1;
			else if (typeof obTmp2 == "function")
				ob = obTmp2;
			else ob = (obTmp1 != null ? obTmp1 : obTmp2);
		}
	
		switch (typeof ob)
		{
			case "object":
				return ob;
				
			case "function":
				return ob();
			
			default:

				return "";
		}
	}
	
	/**
	 * 引用名字空间
	 * 引用名字空间，被引用的名字空间内的变量将可以直接通过Node起始名字空间访问
	 *
	 * @param newNameSpace:[IN]/名字空间
	 * @return true/false
	 *
	 * @author 2006-07-21	yangzh
	*/	
	this.UsingNameSpace = function(newNameSpace)
	{
		return this.AddClass(this.GetAttrValue(newNameSpace + ".Class"), null, "");		
	}
	
	/**
	 * 设置显式起始名字空间标志
	 * 设置显式起始名字空间标志
	 *
	 * @param explicit:[IN]/是否设置
	 * @return true/false
	 *
	 * @author 2006-07-21	yangzh
	*/
	this.SetExplicitName = function(explicit)
	{
		this.ExplicitName = explicit;
	}
		
	/**
	 * 添加解析类
	 * 添加解析类
	 *
	 * @param nodeClass:[IN]/解析类
	 * @param parent:	[IN]/引入名字空间位置，为空则为起始名字空间下
	 * @param name:		[IN]/该类的名字空间，为空则使用解析类的默认名字空间
	 * @return true/false
	 *
	 * @author 2006-07-21	yangzh
	*/
	this.AddClass = function(nodeClass, parent, name)
	{
		if (nodeClass != null)
		{
			if (parent == null)
				parent = this;
		
			if (name == "")
			{
				for (var i in parent)
				{
					if (parent[i] == nodeClass)
						return true;
				}			
			
				for (var i = 0; ; i++)
				{
					if (parent["self" + i] == null)
						break;
				}

				// 保存GetClass值
				var GetClass = parent.GetClass;					
				parent["self" + i] = nodeClass;
				parent["self" + i](parent, parent.NameSpace);
				parent.GetClass = GetClass;
			}
			else
			{
				for (var i in parent)
				{
					if (parent[i] != null && parent[i]["GetClass"] != null && parent[i]["GetClass"]() == nodeClass)
						return true;
				}
			
				var ob = new nodeClass(this);
				if (name == null)
					name = ob.NameSpace;

				ob.NameSpace = parent.NameSpace + "." + name;
				parent[name] = ob;
			}
			
			return true;
		}
		
		return false;
	}
		
	// 添加解析类
	this.AddClass(CVFDLItem, null, "");
	this.AddClass(CVFDLRec, null, "");
	this.AddClass(CVFDLFolder, null, "");
	for (var i in CXConfig.Modules)
	{
		if (CXConfig.Modules[i].Class != null)
		{
			if (CXConfig.Modules[i].Class.constructor == Array)
			{
				for (var n in CXConfig.Modules[i].Class)
					this.AddClass(CXConfig.Modules[i].Class[n]);
			}
			else
			{
				this.AddClass(CXConfig.Modules[i].Class);
			}
		}
	}	
}

/**
 * Record解析类
 * Record解析类
 *
 * @param node:		[IN]/CVFDLNode节点
 * @param nameSpace:[IN]/起始名字空间
 * @return true/false
 *
 * @author 2006-07-21	yangzh
*/
function CVFDLRec(node, nameSpace)
{
	// 定义公共成员
	/** 名字空间 */
	if (nameSpace == null)
		nameSpace = "VFDLRec";
	this.NameSpace = nameSpace;

	/** 解析类类型 */
	this.GetClass	= function() {return CVFDLRec;}
	
	/** 参数 */
	this.GetVarValue			= function(name) {return node.GetNodeText('var[@name="' + name + '"]/@value');}
	this.GetVarList				= function(){
		var l1 = new Array();
		var l2 = node.XmlNode.selectNodes("var");
		for (var i = 0; i < l2.length; i++)
			l1.push({Name:CXUtility.GetXmlNodeText(l2[i], "@name"), 
							 FormName:CXUtility.GetXmlNodeText(l2[i], "@formname"), 
							 Value:CXUtility.GetXmlNodeText(l2[i], "@value"), 
							 Attribute:CXUtility.GetXmlNodeText(l2[i], "@attribute"), 
							 Encrypt:CXUtility.GetXmlNodeText(l2[i], "@encrypt")});

		return l1;		
	}
	
	/** 关联文件 */
	this.GetRelateValue			= function(alias) {return node.GetNodeText('relate/node[@alias="' + alias + '"]/@src');}
	this.GetRelateList				= function(){
		var l1 = new Array();
		var l2 = node.XmlNode.selectNodes("relate/node");
		for (var i = 0; i < l2.length; i++)
			l1.push({Alias:CXUtility.GetXmlNodeText(l2[i], "@alias"), 
							 Type:CXUtility.GetXmlNodeText(l2[i], "@type"), 
							 Size:CXUtility.GetXmlNodeText(l2[i], "@size"), 
							 Src:CXUtility.GetXmlNodeText(l2[i], "@src")});

		return l1;		
	}
	
	/** 关联文件 */
	this.GetPageValue			= function(alias) {return unescape(node.GetNodeText('page[@alias="' + alias + '"]/content'));}
	this.GetPageList				= function(){
		var l1 = new Array();
		var l2 = node.XmlNode.selectNodes("page");
		for (var i = 0; i < l2.length; i++)
			l1.push({Alias:CXUtility.GetXmlNodeText(l2[i], "@alias"), 
							Content:unescape(CXUtility.GetXmlNodeText(l2[i], "content"))});

		return l1;		
	}
	
	this.GetVarTextValue		= function(name, bText) {
		var strValue = bText ? name : this.GetVarValue(name);
		if (strValue != null && strValue != "")
		{
			if (strValue.lastIndexOf("]") == strValue.length - 1)
			{
				var mark = false;
				for (var i = 0; i < strValue.length; i++)
				{
					if (strValue.charAt(i) == '"' && (i == 0 || strValue.charAt(i-1) != '\\'))
						mark = !mark;
					if (mark)
						continue;
						
					if (strValue.charAt(i) == '[')
					{
						strValue = strValue.substring(0, i);
						if (strValue.search(/^\"/) != -1 && strValue.search(/\"$/) != -1)
							strValue = strValue.replace(/(^\"|\"$)/g, "");							
						return strValue;
					}
				}
			}
		}
		
		return "";
	}


	this.GetVarIDValue			= function(name, bText) {
		return this.GetVarSubValue(name, "id", bText);
	}
	this.GetVarNicknameValue	= function(name, bText) {
		return this.GetVarSubValue(name, "nickname", bText);
	}
	this.GetVarAvatarValue		= function(name, bText) {
		return this.GetVarSubValue(name, "avatar", bText);
	}	
	
	this.GetVarSubValue		= function(name, sub, bText) {
		var strValue = bText ? name : this.GetVarValue(name); 
		if (strValue != null && strValue != "")
		{
			if (strValue.lastIndexOf("]") == strValue.length - 1)
			{
				var mark = false;
				for (var i = 0; i < strValue.length; i++)
				{
					if (strValue.charAt(i) == '"' && (i == 0 || strValue.charAt(i-1) != '\\'))
						mark = !mark;
					if (mark)
						continue;
						
					if (strValue.charAt(i) == '[')
					{
						var list = this.GetVarArrayValue(strValue.substring(i + 1, strValue.length - 1), true);
						for (var i = 0; i < list.length; i++)
						{
							var reg = new RegExp("^" + sub + "(\\s*)=\\s*");
							if (list[i].search(reg) == 0)
							{
								var v = list[i].replace(reg, "");
								if (v.search(/^\"/) != -1 && v.search(/\"$/) != -1)
									v = v.replace(/(^\"|\"$)/g, "");
								return v;
							}
						}
					
						break;
					}
				}
			}
		}
		
		return "";
	}
	
	this.GetVarArrayValue	= function(name, bText){
		var list = new Array();
	
		var strValue = bText ? name : this.GetVarValue(name); 
		while(strValue != null && strValue != "")
		{
			var nLayer = 0, mark = false;
			for (var i = 0; i < strValue.length; i++)
			{
				if (strValue.charAt(i) == '"' && i > 0 && strValue.charAt(i-1) != '\\')
					mark = !mark;
				if (mark)
					continue;

				if (strValue.charAt(i) == "[")
					nLayer++;
				else if (strValue.charAt(i) == "]")
					nLayer--;
				else if (strValue.charAt(i) == "," && nLayer == 0)
					break;
			}
			
			var s = CXUtility.Trim(strValue.substring(0, i).replace(/\\\"/g, '"'));
			if (s.search(/^\"/) != -1 && s.search(/\"$/) != -1)
				s = s.replace(/(^\"|\"$)/g, "");
			list.push(s);
			
			strValue = strValue.substring(i + 1);
		}
		return list;
	}
}

/**
 * Record解析类
 * Record解析类
 *
 * @param node:		[IN]/CVFDLNode节点
 * @param nameSpace:[IN]/起始名字空间
 * @return true/false
 *
 * @author 2006-07-21	yangzh
*/
function CVFDLFolder(node, nameSpace)
{
	// 定义公共成员
	/** 名字空间 */
	if (nameSpace == null)
		nameSpace = "VFDLFolder";
	this.NameSpace = nameSpace;

	/** 解析类类型 */
	this.GetClass	= function() {return CVFDLFolder;}
	
	/** 参数 */
	this.GetPageSize			= function() {return node.GetNodeText('page/@size');}
	this.GetPageIndex			= function() {return node.GetNodeText('page/@index');}
	this.GetPageCount			= function() {return node.GetNodeText('page/@count');}
}

/**
 * VFDL文档类
 * VFDL文档类
 *
 * @param xmlDoc: [IN]/Dom文档
 *
 * @author	2006-02-20	yangzhang
*/
function CVFDLDoc(xmlDoc)
{
	// 定义公共成员
	/** Dom文档 */
	this.XmlDoc = xmlDoc;

	/** xml版本 */
	this.GetXmlVersion	= function() {return this.XmlDoc.firstChild.attributes("version").nodeValue;}
	/** 文档编码 */
	this.GetXmlEncoding = function() {return this.XmlDoc.firstChild.attributes("encoding").nodeValue;}
	/** 文档版本 */
	this.GetDocVersion	= function() {return this.XmlDoc.lastChild.attributes("ver").nodeValue;}
	/** 文档名称 */
	this.GetDocName		= function() {return this.XmlDoc.lastChild.nodeName;}
	
	/**
	 * 读取根节点
	 * 读取根节点
	 *
	 * @param null
	 * @return XmlNode
	 *
	 * @author 2006-07-21	yangzh
	*/	
	this.GetRootNode = function()
	{
		return this.XmlDoc.selectSingleNode("/*/folder[@attribute=\"root\"]");
	}

	/**
	 * 读取指定节点的父节点
	 * 读取指定节点的父节点
	 *
	 * @param node:	[IN]/xmlNode
	 * @return XmlNode
	 *
	 * @author 2006-07-21	yangzh
	*/		
	this.GetParentNode = function(node)
	{
		if (node.parentNode == null || node.parentNode.tagName == "folder" || node.parentNode.tagName == "rec" || node.parentNode.tagName == "card"||node.parentNode.tagName == "book")
			return node.parentNode;
			
		return GetParentNode(node.parentNode);
	}
	
	/**
	 * 读取指定节点的第一个子节点
	 * 读取指定节点的第一个子节点
	 *
	 * @param node:	[IN]/xmlNode
	 * @return XmlNode
	 *
	 * @author 2006-07-21	yangzh
	*/	
	this.GetFirstChild = function(node)
	{
		return node.selectSingleNode("folder|rec|card|book");
	}
	
	/**
	 * 读取指定节点的最后一个子节点
	 * 读取指定节点的最后一个子节点
	 *
	 * @param node:	[IN]/xmlNode
	 * @return XmlNode
	 *
	 * @author 2006-07-21	yangzh
	*/	
	this.GetLastChild = function(node)
	{
		var nodeList = node.selectNodes("folder|rec|card|book");
		if (nodeList.length > 0)
			return nodeList[nodeList.length-1];
			
		return null;
	}
	
	/**
	 * 读取指定节点的子节点数量
	 * 读取指定节点的子节点数量
	 *
	 * @param node:	[IN]/xmlNode
	 * @return number
	 *
	 * @author 2006-07-21	yangzh
	*/		
	this.GetChildNum = function(node)
	{
		return node.selectNodes("folder|rec|card|book").length;
	}
	
	/**
	 * 读取指定节点的前一个节点
	 * 读取指定节点的前一个节点
	 *
	 * @param node:	[IN]/xmlNode
	 * @return XmlNode
	 *
	 * @author 2006-07-21	yangzh
	*/
	this.GetPrevNode = function(node)
	{
		if (node.previousSibling == null || node.previousSibling.tagName == "folder" || node.previousSibling.tagName == "rec" || node.previousSibling.tagName == "card"||node.previousSibling.tagName=="book")
			return node.previousSibling;
			
		return 	this.GetPrevNode(node.previousSibling);
	}

	/**
	 * 读取指定节点的后一个节点
	 * 读取指定节点的后一个节点
	 *
	 * @param node:	[IN]/xmlNode
	 * @return XmlNode
	 *
	 * @author 2006-07-21	yangzh
	*/	
	this.GetNextNode = function(node)
	{
		if (node.nextSibling == null || node.nextSibling.tagName == "folder" || node.nextSibling.tagName == "rec" || node.nextSibling.tagName == "card"||node.nextSibling.tagName=="book")
			return node.nextSibling;
			
		return 	this.GetNextNode(node.nextSibling);
	}
	
	/**
	 * 根据名称读取节点
	 * 根据名称读取节点
	 *
	 * @param parentNode:	[IN]/父节点xmlNode
	 * @param alias:		[IN]/别名
	 * @return XmlNode
	 *
	 * @author 2006-07-21	yangzh
	*/		
	this.GetNode = function(parentNode, alias)
	{
		return parentNode.selectSingleNode('folder[@alias="'+alias+'"]|rec[@alias="'+alias+'"]|card[@alias="'+alias+'"]|book[@alias="'+alias+'"]');
	}
	
	/**
	 * 根据xPath路径读取节点
	 * 根据xPath路径读取节点
	 *
	 * @param xPath:		[IN]/xPath
	 * @return XmlNode
	 *
	 * @author 2006-07-21	yangzh
	*/		
	this.GetNodeByXPath = function(xPath)
	{
		var node = this.XmlDoc.selectSingleNode(xPath);
		if (node.tagName != "folder" && node.tagName != "rec" && node.tagName != "book" && node.tagName != "card")
			return null;
			
		return node;
	}
	
	/**
	 * 根据ID读取节点
	 * 根据ID读取节点
	 *
	 * @param ID:		[IN]/ID
	 * @return XmlNode
	 *
	 * @author 2006-07-21	yangzh
	*/		
	this.GetNodeByID = function(id)
	{
		return this.XmlDoc.selectSingleNode('//folder[@id="' + id + '"]|//rec[@id="' + id + '"]|//card[@id="' + id + '"]|//book[@id="'+id+'"]');
	}
	
	/**
	 * 浏览节点
	 * 浏览节点
	 *
	 * @param node:		[IN]/父节点XmlNode
	 * @return XmlNodeList
	 *
	 * @author 2006-07-21	yangzh
	*/		
	this.BrowseNode = function(node)
	{
		return node.selectNodes("//folder|//rec|//card|//book");
	}

	/**
	 * 读取节点关联文件位置
	 * 读取节点关联文件位置
	 *
	 * @param node:		[IN]/XmlNode
	 * @return string
	 *
	 * @author 2006-07-21	yangzh
	*/		
	this.GetActualFilePos = function(node)
	{
		return CXUtility.GetActualFilePos(this.XmlDoc.url, CXUtility.GetXmlNodeText(node, "@src"));
	}
}