<?

/*namespace ice\dom;

use \System;
use \System\IO;
use \System\Xml;*/

class html_parser {

	private $source;

	private $tokens = [];

	public function preprocess() {
		/*
			remove css and script tags /(<(s)+script(.)*>)/ 
			remove unecessary tags
		*/
		return false;
	}

	public function __construct($source) {
		$this->source = $source;

		$preg_split_instance = new preg_split('(<|>|'.$object->strings->apos().'|\")', $source);

		$this->tokens = $preg_split_instance->get();
		$this->inner_text_index = [];

		$open_quote = (-1);
		$open_tag = (-1);
		$tokens_set = [];
		$current_token = NULL;
		$current_attribute_value = NULL;
		foreach($this->tokens as $key => $value) {
			if($object->strings->strlen($object->strings->trim($value)) != 0) {
				if(($open_tag === 0 && $value != '<' && $value != '>') || ($open_tag === 0 && $open_quote !== (-1))) {
					if($value == $object->strings->apos() && ($open_quote === (-1) || $open_quote === 0)) {
						if($open_quote === (-1)) { /*vantar ad hopa saman attribute values sem tilheyra sama attribute-i*/
							$open_quote = 0;
						} else if($open_quote === 0) {
							$open_quote = (-1);
							if($current_attribute_value != NULL) {
								$current_token['attributes'][] = $current_attribute_value;
							}
						}
					} else if($value == '"' && ($open_quote === (-1) || $open_quote === 2)) {
						if($open_quote === (-1)) {
							$open_quote = 2;
						} else {
							$open_quote = (-1);
							if($current_attribute_value != NULL) {
								$current_token['attributes'][] = $current_attribute_value;
							}
						}
					} else {
						if($open_quote == (-1)) {
							$current_token['value_set'][] = $value;
							$current_attribute_value = [];
							/*$tokens_set[] = ['value' => $value, 'type' => 'tag'];*/
						} else {
							/*$current_token['attributes'][] = $value;*/
							$current_attribute_value[] = $value;
						}
					}
					/*var_dump($open_quote, $value);*/
				} else if($value != '<' && $value != '>') {
					$tokens_set[] = ['value' => $value, 'type' => 'inner_text'];
					/*$this->inner_text_index[$object->count($tokens_set)-1] = true;*/
				}
				if($value == '<' && ($open_tag == 1 || $open_tag == (-1))) {
					$open_tag = 0;
					$current_token = ['value' => NULL, 'value_set' => [], 'type' => 'tag', 'attributes' => []];
				} else if($value == '>') {
					$tokens_set[] = $current_token;
					$open_tag = 1;
				}
			}
		}
		foreach($tokens_set as $key => $value) {
			if($value['type'] == 'tag') {
				/*$tokens_set[$key]['value'] = $value['value_set'][0];*/
				$value['value'] = $value['value_set'][0];
			}
		}
		$this->tokens = $tokens_set;
		/*var_dump($this->inner_text_index);
		var_dump($tokens_set);*/
	}

	private $current_element = NULL;

	public function parse($current_element=NULL, $index=0) { /*tharf ad taka til greina ef goggur er innan double eda single quotes eda escaped?*/
		if($current_element == NULL) {
			$current_element = new html_element();
		}
		$current_element->set_tag_name('document');
		/*$token = $this->tokens[$index];
		$index++;
		$current_element->parse_tag($token);
		$this->sub_parse($current_element, $this->tokens);*/
		$current_element->set_children($this->sub_parse($current_element, $this->tokens));
		/*var_dump($current_element);*/
		return $current_element;
	}

	public function sub_parse($parent_element, $tokens) {
		$elements = [];
		$index = 0;
		$token;
		while($index < $object->count($tokens)) {
			$token = $tokens[$index];
			if($object->strings->substr($object->strings->trim($token['value']), 0, 1) != '/') {
				$current_element;
				$tag_name = NULL;
				if($tokens[$index]['type'] == 'tag') {
					$current_element = new html_element();
				} else if($tokens[$index]['type'] == 'inner_text') {
					$current_element = new html_inner_text();
				}
				$elements[] = $current_element;
				
				if($tokens[$index]['type'] == 'tag') {
					$tag_name = $current_element->parse_tag($token);
				} else {
					$tag_name = NULL;
					$current_element->set_value($token['value']);
				}
				$index++;
				if($tag_name != NULL) {
					$sub_tokens = [];
					$closing_tag_found = false;
					while(!$closing_tag_found && $index < $object->count($tokens)) {
						$token = $tokens[$index];
						$sub_tokens[] = $token;

						if(('/'.$tag_name) == $object->strings->trim($token['value'])) {
							$closing_tag_found = true;
						}
						$index++;
					}
					$current_element->set_children($this->sub_parse($current_element, $sub_tokens));
				}
			} else {
				$index++;
			}
			/*echo "index: ".$index."\n";*/
		}
		return $elements;
	}
}

class html_inner_text {

	protected $value;

	public function set_value($string) {
		$this->value = $string;
	}

	public function get_value() {
		return $this->value;
	}
}

class html_element {


	/*function __construct(\ice\dom\window_element $window, \ice\html_element $parent) {
		$this->context = $window;
		$this->parent = $parent;
	}*/
	public function __construct($window=NULL, $parent=NULL) {
		$this->window = $window;
		$this->parent = $parent;
		$this->attributes = $object->create();
	}

	/*public function set_inner_html(string $html) : void {
		$xml_document = new \System\Xml\XmlDocument();
		$xml_document->LoadXml($html);
		$this->set_inner_html_sub($xml_document->ChildNodes, $this);
	}

	public function set_inner_html_sub(\System\Xml\XmlNodeList $nodes, $parent) {
		foreach($nodes as $node) {
			$element = NULL;
			if($node->Name == '#text') {
				$element = new html_element($this->window, $parent);
				$element->set_inner_text($node->InnerText);
				$element->set_tag_name($node->Name);
				$element->set_namespace($node->NamespaceURI);
				//\System\Diagnostics\Debug::WriteLine($node->InnerText);
			} else if($node->Name == 'style') {
				$this->window->document->style_manager->run($node->InnerText);
			} else {
				$element = new html_element($this->window, $parent);
				$element->set_tag_name($node->Name);
				$element->set_namespace($node->NamespaceURI);
				//\System\Diagnostics\Debug::WriteLine($node->Name);	
				foreach($node->Attributes as $attribute) {
					//\System\Diagnostics\Debug::WriteLine($node->Name);
					//\System\Diagnostics\Debug::WriteLine($node->Value);
					$element->set_attribute($attribute->Name, $attribute->Value);
				}
				$this->set_inner_html_sub($node->ChildNodes, $element);
			}	
			if($element != NULL) {
				$parent->add_child($element);
			}
		}
	}

	public function set_view(\Xamarin\Forms\View $view) : void {
		$this->view = $view;
	}*/

	protected $inner_text;

	public function set_inner_text($inner_text) {
		$this->inner_text = $inner_text;
	} 

	public function get_inner_text() {
		return $this->inner_text;
	}

	protected $view;

	protected $window;
	protected $namespace;

	protected $parent;
	protected $tag_name;
	protected $classes = [];
	protected $id;

	protected $computed_style = [];

	public function reset_computed_style() {
		$this->computed_style = [];
	}

	public function get_computed_style() {
		return $this->computed_style;
	}

	public function attribute_is($attribute_name, $attribute_value) {
		if($object->isset($this->attributes[$attribute_name])) {
			if($object->strings->trim($this->attributes[$attribute_name]) == $object->strings->trim($attribute_value)) {
				return true;
			}
		}
		return false;
	}

	public function set_computed_style($style, $reset=false) {
		if($reset) {
			$this->computed_style = $style;
		} else {
			$this->computed_style = $object->concat($style, $this->computed_style);
		}
	}

	public function get_classes() {
		if($object->isset($this->attributes['class'])) {
			return $this->attributes['class'];
		}
		return NULL;
	}

	public function has_class($class) {
		if($object->isset($this->attributes['class'])) {
			foreach($this->attributes['class'] as $compare) {
				if($class == $compare) {
					return true;
				}
			}
		}	
		return false;
	}

	public function get_id() {
		if($object->isset($this->attributes['id'])) {
			return $this->attributes['id'];
		}
		return NULL;
	}

	protected $children = [];

	public function set_namespace($namespace) {
		$this->namespace = $namespace;
	}

	public function set_children($children) {
		$this->children = $children;
	}

	public function add_child($child) {
		$this->children[] = $child;
	}

	public function get_children() {
		return $this->children;
	}

	public function set_tag_name($tag_name) {
		$this->tag_name = $tag_name;
	}

	public function get_tag_name() {
		return $this->tag_name;
	}

	public function get_namespace() {
		return $this->namespace;
	}

	public function parse_tag($tag_value) {
		$values = $tag_value['value_set'];
		$attribute_values = $tag_value['attributes'];

		/*$tag_name = NULL;*/
		$value = $values[0];
		$preg_split_instance = new preg_split('\s', $object->strings->trim($value));

		$split = $preg_split_instance->get();
		if($object->count($split) > 0) {
			$tag_name = $split[0];
			$this->set_tag_name($tag_name);
			/*delete($split[0]);*/
			if($object->isset($split[1])) {
				$values[0] = $split[1];
			} else {
				$values = [];
			}
		}

		$index_offset = 0;
		foreach($values as $key => $value) {
			if($object->strings->strpos($value, '=') !== false) {
				$split = $object->strings->explode('=', $value);
				$attribute_name = $object->strings->trim($split[0]);
				$property_value = $object->strings->implode('', $attribute_values[$key+$index_offset]);
				$this->set_attribute($attribute_name, $property_value);
			} else {
				$this->set_attribute($object->strings->trim($value), NULL);
				$index_offset--;
			}
		}


/*		$tag_values = preg_split("/(\s)/", $object->strings->trim($values[0])); //Tharf ad breyta thesssu thannig thad taki til greina property med bili split by whitespace and quotes
		$this->set_tag_name($tag_values[0]);
		delete($values[0]);*/

		/*foreach($tag_values as $key => $tag_property) {
			//echo "tag_property_split:\n";
			$tag_property_split = preg_split("/(\s|\=)/", $object->strings->trim($tag_property), 0, PREG_SPLIT_DELIM_CAPTURE);
			$property_name = $tag_property_split[0];
			$property_value = NULL;
			if($object->count($tag_property_split) >= 2 && $tag_property_split[1] == '=') {
				$property_value = $this->parse_property_value($tag_property_split[2]);
			}
			$this->set_property($property_name, $property_value);
		}*/
		return $this->tag_name;
	}

	protected $attributes = NULL;

	public function set_attribute($attribute_name, $value) {
		if($attribute_name == 'class') {
			$preg_split_instance = new preg_split('\s+', $value);
			$value = $preg_split_instance->get();
			$this->attributes[$attribute_name] = $value;
		} else if($attribute_name == 'style') {
			$this->attributes[$attribute_name] = $value;
			$style_manager = new style_manager();
			$style_manager->run($value);
			$styles = $style_manager->style_rules;
			$this->set_computed_style($styles);
		} else {
			$this->attributes[$attribute_name] = $value;
		}		
	}

	/*function parse_property_value($value) {
		$first_character = $object->strings->substr($value, 0, 1);
		$last_character = $object->strings->substr($value, $object->strings->strlen($value)-1, 1);
		//var_dump($first_character, $last_character);
		if($first_character == "'" && $last_character == "'") {
			//$split = preg_split("/(\s|'|\")/", $object->strings->trim($value));
			$split = preg_split("/(\s|')/", $object->strings->trim($value));
			foreach($split as $key => $value) {
				if($object->strings->strlen($object->strings->trim($value)) > 0) {
					return $value;
				}
			}
		} else if($fist_character == '"' && $last_character == '"') {
			$split = preg_split("/(\s|\")/", $object->strings->trim($value));
			foreach($split as $key => $value) {
				if($object->strings->strlen($object->strings->trim($value)) > 0) {
					return $value;
				}
			}
		} else if(is_numeric($value)) {
			return $value;
		}
		return NULL;
	}*/

}
/*
$source = "
	<html >
		<head>

			<title>test</title>
		</head>
		<body>
			<div id=\"2\" class='test_1'>
				<div id='test2'>
					test content
					<div id='sub_container'>
						test
					</div>
				</div>
			</div>
			<div>test this</div>
			<div class='container' attribute='1<\"2'>
				inner text with divs test
				<div class='button'>click me1</div>
				more text
				<div class='button'>click me2</div>
				another test
			</div>
			<div>another container</div>
		</body>

	</html>
";// id='2' class='test'

$html_parser = new html_parser($source);
$html_parser->parse();
*/
?>