<?php

class TextExport {
	public $mime = 'text/plain';
	public $extension = 'txt';
	public $description = 'Fichier de texte brut';

	public function sample($dataset,$level = 0,$parent=''){
		$stream = '';
		$parent = ($parent!=''?$parent.'.':'');
		$indentation = str_repeat("\t", $level);
		foreach($dataset as $macro => $infos){
			$infos['type'] = isset($infos['type']) ? $infos['type'] : '';
			switch($infos['type']){
				case 'list':
					$stream .= $indentation.'-'.$parent.$macro.' '.(isset($infos['label'])?': '.$infos['label']:'').' (liste)'.PHP_EOL;
					$stream .= $indentation.'{{#'.$parent.$macro.'}}'.PHP_EOL;
					if(is_array($infos['value']) && isset($infos['value'][0])) $stream .=  self::sample($infos['value'][0],$level+1);
					$stream .=$indentation.'{{/'.$parent.$macro.'}}';
				break;
				case 'object':
					$stream .= $indentation.'-'.$parent.$macro.' '.(isset($infos['label'])?': '.$infos['label']:'').PHP_EOL;
					$stream .= self::sample($infos['value'],$level+1,$parent.$macro);
				break;
				case 'image': break;
				default :
					$stream .= $indentation.'{{'.$parent.$macro.'}} : '.( !isset($infos['label']) ? '': $infos['label']).PHP_EOL;
				break;
			}
		}
		return $stream;
	}

	//permet aux exports enfant de surcharger la méthode pour convertir des valeurs en fct de leurs type sur un export particulier
	// (ex: convertion des flux images en base64 sur les fichiers html)

	public  function formatValue($type,$value){
		if($type == 'image') return '';
		return $value;
	}

	public function decomposeKey($datas,$key){
		if(array_key_exists($key, $datas)) return isset($datas[$key]) ? $datas[$key] : '';

		$attributes = explode('.',$key);
		$current = $datas;
		$value = null;

        foreach ($attributes as $attribute) {
        	if(!array_key_exists($attribute, $current)) break;
        	$current = $current[$attribute];
        	$value = isset($current) ? $current : '';
        }
        return $value;
	}

	public function from_template($stream, $datas){
		//if / loop
		$loopIfRegex = '/\{\{\#([^\/\#}]*)\}\}(.*?)\{\{\/\1\}\}/is';
		$stream =  preg_replace_callback($loopIfRegex,function($matches) use ($datas) {
			$key = $matches[1];
			$streamTpl = $matches[2];
			$keyInfos = explode('::',$key);
			$key = $keyInfos[0];
			$type = isset($keyInfos[1]) ? $keyInfos[1] : 'string';

			$value = $this->decomposeKey($datas,$key);

			//gestion des boucles
			if(is_array($value)){
				$stream = '';
				foreach($value as $line){
					$localData = is_array($line) ? array_merge($datas,$line) : $datas;
					$stream .= $this->from_template($streamTpl,$localData);
				}
				return $stream;
			//gestion des if
			}else{
				return !isset($value) || (!is_array($value) && empty($value)) || (is_array($value) && count($value)==0) ? '' : $this->from_template($streamTpl,$datas);
			}
		},$stream);

		//gestion des else
		$elseRegex = '/\{\{\^([^\/\#}]*)\}\}(.*?)\{\{\/\1\}\}/is';
		$stream =  preg_replace_callback($elseRegex,function($matches) use ($datas) {
			$key = $matches[1];
			$streamTpl = $matches[2];

			$keyInfos = explode('::',$key);
			$key = $keyInfos[0];
			$type = isset($keyInfos[1]) ? $keyInfos[1] : 'string';

			$value = $this->decomposeKey($datas,$key);

			if(is_array($value)){
				$stream = '';
				foreach($value as $line){
					$localData = is_array($line) ? array_merge($datas,$line) : $datas;
					$stream .= $this->from_template($streamTpl,$localData);
				}
				return $stream;
			//gestion des else
			}else{
				return !isset($value) || (!is_array($value) && empty($value)) || (is_array($value) && count($value)==0) ? $this->from_template($streamTpl,$datas) : '';
			}
		},$stream);

		//gestion des simples variables
	    $stream = preg_replace_callback('/{{([^#\/}]*)}}/',function($matches) use ($datas) {
	        $key = $matches[1];

	        $keyInfos = explode('::',$key);
			$key = $keyInfos[0];
			$type = isset($keyInfos[1]) ? $keyInfos[1] : 'string';

	        $value = $this->decomposeKey($datas,$key);
	        if(!isset($value)) return $this->formatValue($type,$matches[0]);
	        if(is_array($value)) return 'Array';
	        return $this->formatValue($type,$value);
	    },$stream);
		return $stream;
	}
}
