function yuna_parse_xml()
{
	this.arrConfig = new Array();
	this.objCurrentXml = new Object();
	this.nodTemplate = new Object();

	this.strLabelAttributeName = 'y_label';

	yuna_parse_xml.prototype.set_config = function(arrConfig)
	{
		this.arrConfig = arrConfig;
	}


	yuna_parse_xml.prototype.set_template_by_id = function(strId)
	{
		this.nodTemplate = document.getElementById(strId);
	}





	/*
	 * Will parse the given XML according to the config array that is set
	 * by calling set_config()
	 *
	 * @param [object XMLDocument] objXml
	 * @acces public
	 */
	yuna_parse_xml.prototype.parse = function(objXml)
	{
		this.objCurrentXml = objXml;
		for (var i=0;i<this.arrConfig.length;i++)
		{
			var arrConfigChunk = this.arrConfig[i];

			if (arrConfigChunk['type']=='single')
			{
				this.parse_single(arrConfigChunk);
			}
			else if (arrConfigChunk['type']=='array')
			{
				this.parse_array(arrConfigChunk);
			}
		}
	}



	/*
	 * Will parse given configChunk if it's a single value
	 *
	 * @param array arrConfigChunk
	 * @acces private
	 */
	yuna_parse_xml.prototype.parse_single = function(arrConfigChunk)
	{
			// find the sourcenode
		var nodTheNode = this.find_source_node(arrConfigChunk);

		if (nodTheNode)
		{
			var mixTheData = this.get_data_from_node(nodTheNode,arrConfigChunk);
			//var nodTemplateNode = this.store_data_in_template(mixTheData,arrConfigChunk);
			this.store_data_in_template(mixTheData,arrConfigChunk);
		}
	}



	/*
	 * Will parse given configChunk if it's an array of elements
	 *
	 * @param array arrConfigChunk
	 * @acces private
	 */
	yuna_parse_xml.prototype.parse_array = function(arrConfigChunk)
	{
			// find the sourcenode
		var arrTheNodes = this.find_multiple_source_nodes(arrConfigChunk);

		var arrDataValues = new Array();

		for (var i=0;i<arrTheNodes.length;i++)
		{
			var mixTheData = this.get_data_from_node(arrTheNodes[i],arrConfigChunk);
			arrDataValues[arrDataValues.length] = mixTheData;
		}
		var blnResult = this.store_array_data_in_template(arrDataValues,arrConfigChunk);
	}



	/*
	 * will find the node stated in the configChunk and return it
	 *
	 * @param array arrConfigChunk
	 * @return XMLNode
	 * @access private
	 */
	yuna_parse_xml.prototype.find_source_node = function(arrConfigChunk)
	{
		var mixReturn = false;

		if (arrConfigChunk['find_tagName'])
		{
			var strTagName = arrConfigChunk['find_tagName'];
			var arrAttr = arrConfigChunk['find_attributeNames'];
			var arrValues = arrConfigChunk['find_attributeValue'];

			//alert(strTagName);

			var arrSourceNodes = this.objCurrentXml.getElementsByTagName(strTagName);

			for(var i=0;i<arrSourceNodes.length;i++)
			{
				var nodTheNode = arrSourceNodes[i];
				var blnAttributesOk = true;

					// check if required attributes are present
				for (var j=0;j<arrAttr.length;j++)
				{
					strAttr = arrAttr[j];
					strValue = arrValues[j];

					if (nodTheNode.getAttribute(strAttr) != strValue) blnAttributesOk = false;
				}

				if (blnAttributesOk==true)
				{
					mixReturn = nodTheNode;
					break; // break out of node loop
				}
			}
		}
		return mixReturn;
	}




		/*
	 * will find the node stated in the configChunk and return it
	 *
	 * @param array arrConfigChunk
	 * @return XMLNode
	 * @access private
	 */
	yuna_parse_xml.prototype.find_multiple_source_nodes = function(arrConfigChunk)
	{
		var arrReturn = new Array();

		if (arrConfigChunk['find_tagName'])
		{
			var strTagName = arrConfigChunk['find_tagName'];
			var arrAttr = arrConfigChunk['find_attributeNames'];
			var arrValues = arrConfigChunk['find_attributeValue'];

			var arrSourceNodes = this.objCurrentXml.getElementsByTagName(strTagName);
			for(var i=0;i<arrSourceNodes.length;i++)
			{
				var nodTheNode = arrSourceNodes[i];
				var blnAttributesOk = true;

					// check if required attributes are present
				for (var j=0;j<arrAttr.length;j++)
				{
					strAttr = arrAttr[j];
					strValue = arrValues[j];

					if (nodTheNode.getAttribute(strAttr) != strValue) blnAttributesOk = false;
				}

				if (blnAttributesOk==true)
				{
					arrReturn[arrReturn.length] = nodTheNode;
				}
			}
		}
		return arrReturn;
	}



	/*
	 * will extract data from node according to given configChunk
	 *
	 * @param XMLNode arrConfigChunk
	 * @param array arrConfigChunk
	 * @access private
	 * @return string
	 */
	yuna_parse_xml.prototype.get_data_from_node = function(nodXmlNode,arrConfigChunk)
	{
		mixReturnData = '';
		strSourceType = arrConfigChunk['data_source'];

		if (strSourceType == 'attribute')
		{
			strAttributeName = arrConfigChunk['data_sourceAttribute'];
			mixReturnData = nodXmlNode.getAttribute(strAttributeName);
			//alert('attribute='+mixReturnData);
		}
		else if (strSourceType=='text')
		{
			mixReturnData = this.get_text_from_node(nodXmlNode);
		}
		else if (strSourceType=='innerHTML')
		{
			mixReturnData = nodXmlNode.innerHTML;
		}
		else if (strSourceType=='clone')
		{
			mixReturnData = nodXmlNode.cloneNode(true);
		}

		return mixReturnData;
	}



	/*
	 * Will parse the given XML according to the config array that is set
	 * by calling set_config()
	 *
	 * @param string strTheData
	 * @param array arrConfigChunk
	 * @acces private
	 */
	yuna_parse_xml.prototype.store_data_in_template = function (mixTheData,arrConfigChunk)
	{
		var strTargetNodeLabel = arrConfigChunk['target_label'];
		var strDataTarget = arrConfigChunk['data_target'];
		var nodTarget = this.find_target_node(this.nodTemplate,strTargetNodeLabel);

		if (nodTarget)
		{
			switch(strDataTarget)
			{
				case 'text':
					break;
				case 'innerHTML':
					nodTarget.innerHTML = mixTheData;
					break;
				case 'attribute':
					var strAttributeName = arrConfigChunk['data_targetAttribute'];
					nodTarget.setAttribute(strAttributeName,mixTheData);
					break;
				default:
					break;
			}

			nodTarget = this.post_process(nodTarget,mixTheData,arrConfigChunk);
		}
	}



	/*
	 * Will store array data according to the config array that is set
	 * for i>0 the template node will be copied within the parent
	 *
	 * @param array arrDataValues
	 * @param array arrConfigChunk
	 * @acces private
	 */
	yuna_parse_xml.prototype.store_array_data_in_template = function (arrDataValues,arrConfigChunk)
	{
		var strTargetNodeLabel = arrConfigChunk['target_label'];
		var strDataTarget = arrConfigChunk['data_target'];
		var nod1stTarget = this.find_target_node(this.nodTemplate,strTargetNodeLabel);

			// TB 20061024 added extra check to prevent js errors for not finding the target node in the template html
		if (nod1stTarget)
		{
			for (var i=0;i<arrDataValues.length;i++)
			{
				mixTheData = arrDataValues[i];
				if (i==0)
				{
					nodTheTarget = nod1stTarget;
				}
				else
				{
					nodTheTarget = nod1stTarget.cloneNode(true);
					nodParent = nod1stTarget.parentNode;
					nodParent.appendChild(nodTheTarget);
				}

				switch(strDataTarget)
				{
					case 'innerHTML':
						nodTheTarget.innerHTML = mixTheData;
						break;
					case 'postProcess':
						break;
					default:
						break;
				}

				nodTheTarget = this.post_process(nodTheTarget,mixTheData,arrConfigChunk);

			}
		}

	}



	/*
	 * Recursive: Will search the template html for the target node with label strLabel
	 *
	 * @param HTMLNode nodTemplate
	 * @param string strLabel
	 * @acces private
	 * @return HTMLNode
	 */
	yuna_parse_xml.prototype.find_target_node = function (nodTemplate,strLabel)
	{
		var mixReturn = false;
		if (nodTemplate.childNodes)
		{
			for (var i=0;i<nodTemplate.childNodes.length;i++)
			{
				if (nodTemplate.childNodes[i].getAttribute && nodTemplate.childNodes[i].getAttribute(this.strLabelAttributeName)==strLabel)
				{
					mixReturn = nodTemplate.childNodes[i];
				}
				else
				{
					mixReturn = this.find_target_node(nodTemplate.childNodes[i],strLabel);
				}

				if (mixReturn) break;
			}
		}
		return mixReturn;
	}



	/*
	 * Helper function that will get the contents of the text-node within the argument nodXmlNode
	 *
	 * @param HTMLNode nodXmlNode
	 * @acces private
	 * @return string
	 */
	yuna_parse_xml.prototype.get_text_from_node = function(nodXmlNode)
	{
		mixReturnData = '';
		if (nodXmlNode.childNodes)
		{
			for (var i=0;i<nodXmlNode.childNodes.length;i++)
			{
				if (nodXmlNode.childNodes[i].nodeType==3 || nodXmlNode.childNodes[i].nodeType==4)
				{
					mixReturnData = nodXmlNode.childNodes[i].nodeValue;
				}
			}
		}
		return mixReturnData;
	}



	/*
	 * Contains custom postprocessing functionallity based on the target_label
	 *
	 * @param HTMLNode nodTheTarget
	 * @param  string|xmlNode mixTheData
	 * @param array arrConfigChunk
	 * @acces private
	 * @return string
	 */
	yuna_parse_xml.prototype.post_process = function (nodTheTarget,mixTheData,arrConfigChunk)
	{
		strTargetNodeLabel = arrConfigChunk['target_label'];

			// personen: parse naam & rol naar string
			// ======================================
		if (strTargetNodeLabel=='persoon')
		{
			arrNameNodes = mixTheData.getElementsByTagName('naam');
			arrRolNodes = mixTheData.getElementsByTagName('rol');

			strName = (arrNameNodes[0]) ? this.get_text_from_node(arrNameNodes[0]) : '';
			strRol = (arrRolNodes[0]) ? this.get_text_from_node(arrRolNodes[0]) : '';

			strPersoonText = strName;
//			if (strRol!='') strPersoonText += ' ('+strRol+')';

			nodTheTarget.innerHTML = strPersoonText;
		}



			// afbeeldingen: data is src attribuut
			// ===================================
		if (strTargetNodeLabel=='afbeelding')
		{
			nodTheTarget.src = mixTheData;
			nodTheTarget.style.display = 'block';
		}



			// player: set href and date
			// ======================================
		if (strTargetNodeLabel=='player')
		{
			arrDateNodes = mixTheData.getElementsByTagName('begi');
			arrPlayerUrlNodes = mixTheData.getElementsByTagName('player_url');

			strDateUnformatted = (arrDateNodes[0]) ? this.get_text_from_node(arrDateNodes[0]) : '';
			strPlayerUrl = (arrPlayerUrlNodes[0]) ? this.get_text_from_node(arrPlayerUrlNodes[0]) : '';

				// check for uitzendingen that do not have a player_url
			if (strPlayerUrl=='')
			{
				nodTheTarget.parentNode.removeChild(nodTheTarget);
			}
			else
			{
				strDateFormattedYear = strDateUnformatted.substr(0,4);
				strDateFormattedMonth = strDateUnformatted.substr(5,2);
				strDateFormattedDay = strDateUnformatted.substr(8,2);
				strDateFormatted = strDateFormattedDay+'-'+strDateFormattedMonth+'-'+strDateFormattedYear;

				nodTheTarget.setAttribute('href',strPlayerUrl);

					// fill the 'strong' tag
				arrNodStrong = nodTheTarget.getElementsByTagName('strong');
				if (arrNodStrong[0])
				{
					nodStrong = arrNodStrong[0];
					nodStrong.innerHTML = strDateFormatted;
				}

			}

//			if (strRol!='') strPersoonText += ' ('+strRol+')';
		}


			// aflevering: fill with inhk and add link
			// ======================================
		if (strTargetNodeLabel=='aflevering')
		{
			arrDateNodes = mixTheData.getElementsByTagName('begi');
			arrPlayerUrlNodes = mixTheData.getElementsByTagName('player_url');
			arrInhNodes = mixTheData.getElementsByTagName('inhk');

			strDateUnformatted = (arrDateNodes[0]) ? this.get_text_from_node(arrDateNodes[0]) : '';
			strPlayerUrl = (arrPlayerUrlNodes[0]) ? this.get_text_from_node(arrPlayerUrlNodes[0]) : '';
			strInhoud = (arrInhNodes[0]) ? this.get_text_from_node(arrInhNodes[0]) : '';

				// check for uitzendingen that do not have a player_url
			if (strPlayerUrl=='')
			{
				nodTheTarget.parentNode.removeChild(nodTheTarget);
			}
			else
			{
				strDateFormattedYear = strDateUnformatted.substr(0,4);
				strDateFormattedMonth = strDateUnformatted.substr(5,2);
				strDateFormattedDay = strDateUnformatted.substr(8,2);
				strDateFormatted = strDateFormattedDay+'-'+strDateFormattedMonth+'-'+strDateFormattedYear;

				strHtmlChunk  = '<strong>'+strDateFormatted+'</strong><br />';
				strHtmlChunk += strInhoud;
				strHtmlChunk += '<br />';
				strHtmlChunk += '<a href="'+strPlayerUrl+'" target="_blank">bekijk de aflevering</a>';


				nodTheTarget.innerHTML = strHtmlChunk;

			}

//			if (strRol!='') strPersoonText += ' ('+strRol+')';
		}

		return  nodTheTarget;
	}





}

