<?php
	
	class StackPiece{
		var $position;
		var $name;
		var $prev;
		var $datanode = null;
		
		function StackPiece($position, $name, $prev=null){
			$this->position = $position;
			$this->name = $name;
			$this->prev = $prev;
		}
	}
	
	
	class AppData{
		var $depth;
		var $sp;
		var $currMessage;
		var $currElement;
		
		function AppData($msg=null){
			$this->depth = 0;
			if(isset($msg)){
				$this->currMessage = &$msg;
			}else{
				$this->currMessage = new Message();
			}
			$this->sp = null;
			$this->currElement = null;
		}
	}
	
	class AuthentXMLParser{
		var $appData;
		var $parser;
		var $parserInited = false;
		var $dataPrefix;
		
		function AuthentXMLParser($msg=null){
			$this->initParser();
			if(isset($msg)){
				$this->appData = new AppData(&$msg);
			}else{
				$this->appData = new AppData();
			}
			$this->dataPrefix = $this->appData->currMessage->dataPrefix;
		}
		
		function initParser(){
			if(!$this->parserInited)
			{
				$this->parser = xml_parser_create();
				
				xml_set_object($this->parser, &$this);
				xml_set_element_handler($this->parser, "startElement", "endElement");
				xml_set_character_data_handler($this->parser, "charHandler");
				//register_shutdown_function("$this->free");
				xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
				$this->parserInited = true;
			}
		}
		
		function free() {
			xml_parser_free($this->parser);
			$this->parserInited = false;
		}
		
		function reset(){
			$this->free();
			$this->initParser();
		}
		
		function startElement($parser, $name, $attrs){
			$this->appData->depth++;
			$sp = new StackPiece($this->appData->depth, $name); 
			$sp->prev = &$this->appData->currElement;
			$this->appData->currElement = &$sp;
			
			if(strstr($name, $this->dataPrefix) == $name){
				$strKey = substr($name, strlen($this->dataPrefix));
				$dn = new DataNode();
				//reset ($attrs);
				//while (list ($key1, $val1) = each ($attrs)) {
				$dn->attributes = $attrs;
				//}
				if(isset($this->appData->currElement->prev->datanode)){
					$this->appData->currElement->prev->datanode->childNodes[$strKey] = &$dn;
				}else{
					$this->appData->currMessage->data[$strKey] = &$dn;
				}
				
				$this->appData->currElement->datanode = &$dn;//this->appData->currMessage->data[$strKey];
			}
			
			if( strcmp($name,"result") == 0 ||
			   strcmp($name,"report") == 0 ||
			   strcmp($name,"poll") == 0 ||
			   strcmp($name,"request") == 0 )
			{
				$this->appData->currMessage->type = $name;
			}
		}
		
		function endElement($parser, $name){
			$this->appData->depth--;
			$this->appData->currElement = $this->appData->currElement->prev;
		}
		
		function charHandler($parser, $text){
			$texttest = trim($text);
			if( strcmp($texttest, "\n") == 0 || strcmp($texttest, "\r\n") == 0 || strcmp($texttest, "") == 0){ 
				return; 
			}
			
			if(strstr($this->appData->currElement->name, $this->dataPrefix) == $this->appData->currElement->name){
				$strKey = substr($this->appData->currElement->name, strlen($this->dataPrefix));
				$dn = &$this->appData->currElement->datanode;
				if(!isset($dn)){
					$dn = new DataNode();
					if(isset($this->appData->currElement->datanode)){
						$this->appData->currElement->datanode->childNodes[$strKey] = &$dn;
					}else{
						$this->appData->currMessage->data[$strKey] = &$dn;
					}
				}
				if(isset($dn)){
					$dn->text = $text;
				}
			}else{
				$vars = get_object_vars($this->appData->currMessage);
				if(array_key_exists($this->appData->currElement->name,$vars)){
					$evalstr = "\$msgPlace = &\$this->appData->currMessage->".$this->appData->currElement->name.";";
					eval($evalstr);
					$msgPlace = $text;
				}
				
			}
		}
		
		function parse($xml) {
			$val = xml_parse($this->parser, $xml);
			if( $val == TRUE){
				//echo "Parsed";
				return $this->appData->currMessage;
			}else{
				echo "Error in Parsing was ".xml_error_string(xml_get_error_code($this->parser))."<br>Happened on Line: ".xml_get_current_line_number($this->parser)." at Column ".xml_get_current_column_number($this->parser).".<br>";
				return null;
			}
		}
	}
?>
