<?php
/*
	Clase SuperSections para las secciones de la web
	@version 1.0
*/
class SuperTheme{

	public static $theme_files = array();
	
	//Definimos constantes y variables que vamos a necesitar
	const _WS_INDEX_DIR_ = _WS_DIR_ . 'dynamic/file_index/';

	
	//Constructor y destructor
	function __construct() {
	}

	function __destruct() {

	}

	public static function loadFiles(){
		$index_dir = self::_WS_INDEX_DIR_ . "file_index.php";
		self::checkFileIndex($index_dir);
		//Ahora vamos a cargar el fichero y a hacerlo nuestro:
		include($index_dir);
		//Vamos almacenar el array (array que se crea en el fichero pero es local):
		self::$theme_files = $ruta_ficheros_web;
	}
	
	public static function checkFileIndex($index_dir){
		$index_dir = self::_WS_INDEX_DIR_ . "file_index.php";
		if (!file_exists($index_dir)){
			self::createIndexFiles(_WS_THEME_HTML_DIR_, $index_dir);
		}
	}
	
	public static function createIndexFiles($ruta, $index_dir = ''){
		if($index_dir != ''){
			//Si no existe el directorio lo creamos
			$fileDir = basename($index_dir);
			if (!is_dir($fileDir)) {
				mkdir($fileDir);         
			}
			//Si existe el fichero, lo borramos
			if (file_exists($index_dir)){
				unlink($index_dir);
			}
			//Y guardamos el comienzo del fichero:
			if ($file = fopen($index_dir, 'w')){
				fwrite($file, "<?php\n");
				//Vamos a reindexar la ruta
				$resultado = self::reIndex($ruta);
				//Creamos el fichero base
				if ($file = fopen($index_dir, 'a+')){
					foreach($resultado as $clave => $valor){
						fwrite($file, '$ruta_ficheros_web[\'' . $clave . '\'] = \'' . $valor . '\';
		');
					}
				}
				fwrite($file, "?>");
				fclose($file);
			}
		}
	}
	
	//Esta función es la que recorre un directorio, es recursiva
	private static function reIndex($ruta){
		$array_ficheros = array();
		//Si "ruta" no tiene una "/" al final, se la ponemos
		if (substr($ruta, -1, 1) != "/"){
			$ruta .= "/";
		}
		//Hay que echar para atrás un nivel
		if (is_dir($ruta)) {
			//echo('Entramos al directorio ' . $ruta . '<br />');
			//No seguimos si existe el fichero noindex:
			if ((!file_exists($ruta . 'noindex')) && (!file_exists($ruta . 'NOINDEX')) ){
				if ($directorio = opendir($ruta)) {
					while (($file = readdir($directorio)) !== false) {
						//No indexamos los ficheros que empiecen por . (ocultos)
						if (substr($file, 0, 1) != '.'){
							if ( (is_dir($ruta . $file)) && ($file!=".") && ($file!="..") ){
								//Es un directorio
								$array_ficheros = array_merge($array_ficheros, self::reIndex($ruta . $file . "/"));
							}else if ( ($file!=".") && ($file!="..")  ){
								//Fichero .php encontrado, vamos a guardarlo
								$array_ficheros[$file] = realpath($ruta . $file);
								//echo("Añadido el fichero $file\n");
							}
						}
					}
					closedir($directorio);
				}
			}
		}
		return($array_ficheros);
	}
	
	public static function findFile($file, $relativa = false){
		$retorno = NULL;
		
		if ($file != ''){
			//Si por algún motivo, el array de ficheros está sin valores lo reindexamos
			$index_dir = self::_WS_INDEX_DIR_ . "file_index.php";
			self::checkFileIndex($index_dir);
			$ruta_ficheros_web = self::$theme_files;
			if (isset($ruta_ficheros_web[$file])){
				$ruta_absoluta = $ruta_ficheros_web[$file];
				//echo("Buscamos " . $ruta_absoluta . "\n<BR />");
				if ( isset($ruta_absoluta) ){
					if ($retorno = realpath($ruta_absoluta)) {
						//var_dump($ruta_absoluta);
						$ruta_tmp = $ruta_absoluta;
						if ($relativa){
							$retorno = $file;
						}
					}
				}
			}
		}
		return($retorno);
	}

	//TODO => Si se modifica la sesión hay que limpiar los "media"
	public static function createMedia($mediaList = array(), $fileName = '', $currentSection = NULL){
		/*if ($fileName == 'cssPie.css'){
			echo('<pre>');
			var_dump($mediaList);
			echo('</pre>');
		}*/
		//Si tenemos sección actual, la añadimos al nombre del fichero:
		if ($currentSection == NULL){
			$currentSection = Sections::$current_section;
		}
		if ($currentSection != ''){
			$fileName = $currentSection . '_' . $fileName;
		}
		//Si se nos pasa un array y un destino, creamos el fichero
		if ( (count($mediaList) > 0) && ($fileName != '') ){
 			$extension = pathinfo($fileName, PATHINFO_EXTENSION);
			
			//Con las carpetas creadas, vamos a asegurarnos de que existe el fichero de control:
			$createControlFile = false;
			$createMediaList = false;
			
			$listFiles = new ConfigFile('media_' . $fileName, true, 'controlFiles/');
			$realPath = $listFiles->getRealNamePath();

			//Si no hay fichero de control, tenemos que crearlo:
			if (!file_exists($realPath)){
				//Si no existe el fichero es posible que tampoco existe la carpeta, comprobamos que existe para crearla
				$controlFileUrl = _WS_DYNAMIC_DIR_ . 'controlFiles/';
				if (!file_exists($controlFileUrl)){
					@mkdir($controlFileUrl);
				}
				
				//No hay fichero de control de medios:
				$createControlFile = true;
				//Por ende, hay que crear los ficheros de medios:
				$createMediaList = true;
			}
			
			if ($createControlFile){
				//Vamos a recorrer el array con los ficheros que nos han pasado para coger la ruta y el tiempo:
				$listFiles->list = array();
				//vamos a recorrer el array comprobando que existan los ficheros en cuestión:
				foreach($mediaList as $clave => $valor){
					//Vamos a buscar el fichero dentro del tema, luego hay que tener en cuenta ese valor:
					$fullOriginPath = _WS_THEME_HTML_DIR_ . $valor;
					if (file_exists($fullOriginPath)){
						$timestamp = filemtime($fullOriginPath);
						$listFiles->list[$valor] = $timestamp;
					}
				}
				//var_dump($listFiles);
				$listFiles->save();
			}
			
			//En "listFiles" tenemos los ficheros que hay que cargar con su timestamp
			//Ahora llega el momento de controlar que los ficheros a incluir tengan el timestamp correcto:
			$finalPath = _WS_DYNAMIC_DIR_ . 'media/' . $extension . '/';
			//Antes de seguir vamos a controlar que exista el fichero de medios indicado:
			if (!file_exists($finalPath . $fileName)){
				$createMediaList = true;
				//Como no existe, vamos a ver si es necesario crear los ficheros que vamos a utilizar
				if (!file_exists(_WS_DYNAMIC_DIR_ . 'media/')){
					@mkdir(_WS_DYNAMIC_DIR_ . 'media/');
				}
				if (!file_exists($finalPath)){
					@mkdir($finalPath);
				}
			}
			
			//Si por ahora no hay que crear la lista de medios para este fichero, vamos a comprobar si los timestamp son correctos:
			if (!$createMediaList){
				foreach($listFiles->list as $clave => $valor){
					//Vamos a buscar el fichero dentro del tema, luego hay que tener en cuenta ese valor:
					$fullOriginPath = _WS_THEME_HTML_DIR_ . $clave;
					if (file_exists($fullOriginPath)){
						$timestamp = filemtime($fullOriginPath);
						if ($valor != $timestamp){
							$createMediaList = true;
							//Vamos a asignar el timestamp:
							$listFiles->list[$clave] = $timestamp;
						}
						//Si no exiisten los ficheros de destino, hay que crearlos:
						if (!file_exists($finalPath . $fileName)){
							$createMediaList = true;
						}
					}
				}
			}
			
			//Llegados a este punto, si hay que crear la lista de medios, vamos a proceder
			if ($createMediaList){
				//si hay que crear la media list, tenemos que actualizar la lista almacenada:
				$listFiles->save();
				//Comprimimos los ficheros:
					//webStore tiene varios compresores de CSS  y JS, se puede configurar para que use unos u otros:
				$compresorJs = _WS_JSQUEEZE_COMPRESSOR;
				$compresorCss = '';
				if ($extension == 'js'){
					switch($compresorJs){
						case _WS_JSHRINK_COMPRESSOR:
							JShrink::compress($listFiles, $fileName);
						break;
						case _WS_JSQUEEZE_COMPRESSOR:
							JSqueeze::compress($listFiles, $fileName);
						break;
						case _WS_MINIFY_COMPRESSOR:
							Minify::compress($listFiles, $fileName);
						break;
						case _WS_PHPWEE_COMPRESSOR:
							PHPWee::compress($listFiles, $fileName);
						break;
						default:
							self::joinFiles($listFiles, $fileName);
					}
					
				}else if ($extension == 'css'){
					switch($compresorCss){
						case _WS_MINIFY_COMPRESSOR:
							Minify::compress($listFiles, $fileName);
						break;
						case _WS_PHPWEE_COMPRESSOR:
							PHPWee::compress($listFiles, $fileName);
						break;
						default:
							self::joinFiles($listFiles, $fileName);
					}
				}
			}
		}
	}
	
	private static function joinFiles($listFiles, $fileName){
		$extension = pathinfo($fileName, PATHINFO_EXTENSION);
		$finalPath = _WS_DYNAMIC_DIR_ . 'media/' . $extension . '/';
		$resultado = '';
		foreach($listFiles->list as $clave => $filetime){
			$path = _WS_THEME_HTML_DIR_ . $clave;
			$resultado .= file_get_contents($path);
		}
		
		$ultima_posicion = 0;
		$imports = '';
		if ($extension == 'css'){
			$cadVieja = array();
			$cadNueva = array();
			do{
				//echo("vuelta $contador\n");
				$existen = strpos ( $resultado, 'url(', $ultima_posicion);
				if ($existen !== false){
					$reemplazos[] = array('', ''); //==> Metemos un array bidimesional para guardar original y reemplazo
					$existen += 3;
					//Tenemos una ruta, vamos a obtenerla entera
					$punto_y_coma = strpos ( $resultado, ')', $existen );
					$ultima_posicion = $punto_y_coma;
					//Cortamos la cadena de texto:
					$tmp_import = substr($resultado, $existen, $punto_y_coma - $existen + 1);
					//Si la cadena Import tiene dentro "http" entonces no seguimos
					if (!strpos(strtoupper($tmp_import), 'HTTP')){
						//Vamos a quitar las comillas simples y dobles:
						$buscar = array('(', ')', '\'', '"');
						$reemplazo = '';
						$ruta_limpia = str_replace ( $buscar , $reemplazo , $tmp_import);
						//Vamos a obtener el "dirname" del fichero que se ha cargado:
						$ruta_original = dirname($clave);
						$ruta_relativa = str_replace(_WS_DIR_, '', _WS_THEME_HTML_DIR_);
						$nueva_ruta = '("../../../' . $ruta_relativa . $ruta_original . '/' . $ruta_limpia . '")';
						//Vamos a quitar la sentencia de valor:
						//echo("Reemplazamos $tmp_import por $nueva_ruta en el fichero $fileName\n");
						//Si ya tenemos el reemplazo en el array, no lo metemos:
						
						if (!in_array($tmp_import, $cadVieja)){
							$cadVieja[] = $tmp_import;
							$cadNueva[] = $nueva_ruta;
						}
						//$resultado = str_replace ( $tmp_import , $nueva_ruta , $resultado);
					}
				}
			}while( ($existen !== false) );
			//Vamos a recorrer las cadenas vieja y nueva y hacemos los reemplazos:
			foreach($cadVieja as $clave => $valor){
				$resultado = str_replace ( $valor , $cadNueva[$clave] , $resultado);
			}
			//Ahora cogemos los imports para llevárnoslos arriba
			do{
				//Primero es obtener la posición del primer import:
				$existen = strpos ( $resultado, '@import' );
				if ($existen !== false){
					//Tenemos un import, vamos a obtener el ; que haya al final:
					$punto_y_coma = strpos ( $resultado, ';', $existen );
					//Cortamos la cadena de texto:
					$tmp_import = substr($resultado, $existen, $punto_y_coma - $existen + 1);
					$imports .= $tmp_import;
					//Vamos a quitar la sentencia de valor:
					$resultado = str_replace ( $tmp_import , '' , $resultado);
				}
			}while($existen !== false);
		}
		//Vamos a quitar los \n:
		$resultado = str_replace ( "\n" , '' , $resultado);
		
		if ($file = fopen($finalPath . $fileName, 'w')){
			fwrite($file, $imports . $resultado);
			fclose($file);
		}
		
	}
	
	public static function loadMedia($type = _WS_MEDIA_TYPE_CSS, $position = _WS_MEDIA_POSITION_BOTTOM, $section = NULL){
		//Si no nos han mandado sección, cogemos la actual:
		if ($section == NULL){
			$section = Sections::$current_section;
		}
		//Primero miramos la posición
		$posicion = '';
		switch($position){
			case _WS_MEDIA_POSITION_BOTTOM:
				$posicion = 'Pie';
			break;
			case _WS_MEDIA_POSITION_TOP:
				$posicion = 'Cabecera';
			break;
		}
		
		//Ahora el tipo pa devolver la llamada
		$tipo = '';
		switch($type){
			case _WS_MEDIA_TYPE_CSS:
				//Si no existe el fichero, no lo cargamos:
				$fileName = $section . '_css' . $posicion . '.css';
				if (file_exists(_WS_DYNAMIC_DIR_ . 'media/css/' . $fileName)){
			
?>
<link rel="stylesheet" type="text/css" href="<?=Shop::$configuracion->url . 'dynamic/media/css/' . $fileName;?>" >
<?php
			}
			break;
			case _WS_MEDIA_TYPE_JS:
				$fileName = $section . '_js' . $posicion . '.js';
				if (file_exists(_WS_DYNAMIC_DIR_ . 'media/js/' . $fileName)){
?>
<script type="text/javascript" src="<?=Shop::$configuracion->url . 'dynamic/media/js/' . $fileName;?>"></script>
<?php
			}
			break;
		}
	}

	//Esta función hace un include de un fichero del tema
	public static function include_file($file){
		$file = self::findFile($file);
		$incluido = false;
		if ($file != NULL){
			//Vamos a cargar las globals (por ahora), esto se tiene que quitar después
			include('comunes/globals.php');
			//25/Enero/2019 ==> Vamos a crear un objeto stdClass llamado fileParams para meter dentro los parámetros extra que se puedan añadir en la función:
			$fileParams = new stdClass();
			if (func_num_args() > 1){
				//Hemos recibido más de un argumento, vamos a meterlo en los parametros
				$args = func_get_args();
				//recorremos el array añadiendo los parámetros al objeto
				$fileParams->args = $args;
			}
			include($file);
			$incluido = true;
		}
		return($incluido);
	}
	
	public static function showContent($section = '', $extension = '.php'){
		$retorno = false;
		if ($section == ''){
			$section = Sections::$current_section;
		}
		
		$fichero_a_incluir = Theme::findFile($section . $extension);
		
		//echo("Hay que cargar la sección $fichero_a_incluir");
		
		//Si tenemos fichero para incluir, lo incluimos, en caso contrario no incluimos nada
		if ($fichero_a_incluir != NULL){
			$retorno = true;
			//Vamos a cargar las globals (por ahora), esto se tiene que quitar después
			include('comunes/globals.php');
			include($fichero_a_incluir);
		}else{
			echo('Error al intentar abrir la sección $fichero_a_incluir<br />\n');
		}
		
		//Devolvemos el resultado de la operación
		return($retorno);	
	}
}
