<?php

namespace XmlStroller;

class XmlNode implements \Iterator
{
	private $itPosition;

	private $xml_name;
	private $xml_value;
	private $xml_parent;
	private $xml_children;
	private $xml_attributes;

	private function __construct($parent, $name =null)
	{
		$this->xml_children = array();
		$this->xml_name = $name;
		$this->xml_value = null;
		$this->xml_parent = $parent;
		$this->xml_attributes = array();
		$this->itPosition = 0;
	}

	private function doParse(&$reader)
	{
		while ($reader->read())
		{
			if ($reader->nodeType == \XMLReader::ELEMENT)
			{
				$i = new self($this, $reader->name);
				if ($reader->moveToFirstAttribute())
				{
					$i->xml_attributes[$reader->name] = $reader->value;
					while ($reader->moveToNextAttribute())
						$i->xml_attributes[$reader->name] = $reader->value;
				}
				$i->doParse($reader);
				$this->xml_children[] = $i;
			}
			else if ($reader->nodeType == \XMLReader::END_ELEMENT)
				return;
			else if ($reader->nodeType == \XMLReader::TEXT)
				$this->xml_value = $reader->value;
			else if ($reader->nodeType == \XMLReader::WHITESPACE || $reader->nodeType == \XMLReader::SIGNIFICANT_WHITESPACE)
				;
		}
	}

	public static function parse($data)
	{
		$root = new self(null, null);
		$reader = new \XMLReader();
		$reader->XML($data);
		$root->doParse($reader);
		return $root;
	}

	public function current()
	{
		return $this->xml_children[$this->itPosition];
	}

	public function key()
	{
		return $this->itPosition;
	}

	public function next()
	{
		$this->itPosition++;
	}

	public function rewind()
	{
		$this->itPosition = 0;
	}

	public function valid()
	{
		return isset($this->xml_children[$this->itPosition]);
	}

	public function getName()
	{ return $this->xml_name; }

	public function attributes()
	{ return array_merge($this->xml_attributes); }

	public function __clone()
	{
		$r = new self(null, $this->xml_name);
		$r->xml_value = $this->xml_value;
		$r->xml_attributes = array_merge($this->xml_attributes);
		$r->xml_children = array();
		foreach ($this->xml_children as $j)
		{
			$_j = clone($j);
			$_j->xml_parent = $r;
			$r->xml_children[] = $_j;
		}
		return $r;
	}

	public function __toString()
	{ return $this->xml_value == null ? $this->xml_name : $this->xml_value; }

	public function parent()
	{ return $this->xml_parent; }
}

