<?php
namespace App\Bsp\Parser;

abstract class BspTraverserAbstractWithDebug extends BspTraverserAbstract
{
	protected $debug_cache = [];

	private function debug_dumpStateWithLine_extractShorthand($text)
	{
		$cacheKey = __METHOD__.$text;
		if (isset($this->debug_cache[$cacheKey])) {
			return $this->debug_cache[$cacheKey];
		}

		$ret = "";
		switch ($text) {
			case 'section':
				$ret = "sct";
			break;

			case 'inHeader':
				$ret = "inHdr";
			break;
			case 'inBopy':
				$ret = "inBdy";
			break;
			case 'lineHandled':
				$ret = "hndled";
			break;

			default:
				$len = strlen($text);

				$lc = null;
				$c = null;
				$switch = false;
				$lastSwitch = 0;
				for ($i=0; $i<$len; $i++) {
					$switch = false;
					$c = $text[$i];
					if ((strtolower($c)==$c && strtolower($lc)!=$lc) || ((strtolower($c)!=$c && strtolower($lc)==$lc))) {	// $c is lower, and $lc is not lower
						$switch = true;
						$lastSwitch = 0;
					}

					if ($switch || $lastSwitch<2) {
						$ret.=$c;
					}

					$lastSwitch++;
					$lc = $text[i];
				}
		}

		$this->debug_cache[$cacheKey] = $ret;
		return $this->debug_cache[$cacheKey];
	}

	protected function debug_dumpStateWithLine($line, $state)
	{
		/**
		 * @see http://paletton.com/#uid=72A0u0kllllfhSfehuiufdi-43b
		 */
		$output = "";
		$output.= "<div style='font-family: monospace; white-space:pre; border-style: solid none none none; border-width: 1px; border-color: #f0f0f0; background-color: #fff;'>";
		$output.= sprintf("<div style='display: inline-block; width: 500px;'>");

		uksort($state, function($a, $b) {
			$ret = 0;
			if (!$ret) {
				$ret = (is_bool($a)?1:0) - (is_bool($b)?1:0);
			}
			if (!$ret) {
				$ret = (is_int($a)?1:0) - (is_int($b)?1:0);
			}
			if (!$ret) {
				$ret = (is_string($a)?1:0) - (is_string($b)?1:0);
			}

			return $ret;
		});

		foreach ($state as $k=>$v) {
			if (is_bool($v)) {
				$output.= sprintf("<div style='padding: 0 2px 0 2px; display: inline-block; border: 1px solid %s; color: #444; background-color: %s; '>%s</div>",
					($v?'#2F5F05':'#690609'),
					($v?'#B6F781':'#FE8588'),
					$this->debug_dumpStateWithLine_extractShorthand($k)
				);
			}
			else { // is_string?
				$output.= sprintf("<div style='padding: 0 2px 0 2px; display: inline-block; border: 1px solid ; color: #444; background-color: #f0f0f0;'>%s: %s</div>",
					$this->debug_dumpStateWithLine_extractShorthand($k),
					$v
				);
			}
		}

		$output.= sprintf("</div>");

		$output.= sprintf("<div style='display: inline-block; color: #190001; border-color: #F8161C; border-width: 1px; border-style: none solid none solid; margin-left: 5px;'>%s</div>", $line);

		$output.= "</div>";

		return $output;
	}

	protected function debug_writeFile($filename, $contents)
	{
		$basePath = MODULE_REL_PATH."../files/debug_bsp/";
		\Engine\Dir::create($basePath);
		// \Engine\File::create(sprintf("%s/%s", $basePath, $filename), $contents);
		file_put_contents(sprintf("%s/%s", $basePath, $filename), $contents);
	}

	private function array2xml($array, $depth=0)
	{
		$xml = '';
		if($depth==0){
			$xml .= '<array2xml version="1.0">'."\n";
		}

		if(!$array) return $xml;

		$idendation=str_repeat("\t",$depth+1);
		foreach($array as $key=>$value) {

			$startTag=str_replace(' ','_._',$key);
			$endTag=str_replace(' ','_._',$key);
			if(is_numeric($key)){
				$startTag="indexed index='{$key}'";
				$endTag="indexed";
			}

			if(is_array($value)){
				$xml.= "$idendation <{$startTag}>\n";

				$xml.= $this->array2xml($value, $depth+1);

				$xml.= "$idendation </{$endTag}>\n";
			}else{
				$extraTags ='';
				$extraTags.='length="'.strlen($value).'" ';

				if(!isset($value)){
					$extraTags.='type="empty" ';
					$value='(EMPTY)';
				}elseif($value===null){
					$extraTags.='type="empty" ';
					$value='(NULL)';
				}elseif(is_bool($value)){
					$extraTags.='type="bool" ';
					$value=($value?'(TRUE)':'(FALSE)');
				}elseif(!$key){
					$extraTags.='type="empty key" ';
					$startTag='BLANK';
					$endTag='BLANK';
				}

				$xml.= "$idendation <{$startTag} $extraTags>";

				$xml.= $value;
				$xml.= "</{$endTag}>\n";
			}
		}

		if($depth==0){
			$xml .= "</array2xml>\n";
		}

	    return $xml;
	}


	protected function debug_writeArrayAsXml($filename, $array)
	{
		$basePath = MODULE_REL_PATH."../files/debug_bsp/";
		\Engine\Dir::create($basePath);
		// \Engine\File::create(sprintf("%s/%s", $basePath, $filename), $contents);
		file_put_contents(sprintf("%s/%s", $basePath, $filename), $this->array2xml($array));
	}
}
