<?php

class js_css_compressor_main
{
	protected $_cache_path='';
	protected $_compressor;

	public function __construct()
	{
		$this->_cache_path=LabVars::$vars['js_css_files'];

		$this->_proccess_css();
		$this->_proccess_js();
	}

	protected function _proccess_css()
	{
		if ($files=LabCMS::i()->getSkinCSS()) {
			foreach ($files as $file) {
				$file=LAB_PATH_ROOT.$file['path'];
				switch(config::get('concat_type_css')) {
					case(1):
						$css[dirname($file)][]=$file;
						break;
					case(2):
					default:
						$css[0][]=$file;
						break;
				}
			}
			foreach ($css as $files) {
				LabVars::$css[]=array('path'=>$this->_process_files($files, 'css'), 'media'=>'all');
			}
		}
	}

	protected function _proccess_js()
	{
		if ($files=LabCMS::i()->getSkinJS()) {
			$js=array();
			foreach ($files as $file) {
				$file=LAB_PATH_ROOT.$file;
				switch(config::get('concat_type_js')) {
					case(1):
						$js[dirname($file)][]=$file;
						break;
					case(2):
						$js[0][]=$file;
						break;
					case(0):
					default:
						$js[][]=$file;
				}
			}
			foreach ($js as $files) {
				LabVars::$js[]=$this->_process_files($files, 'js');
			}
			
		}
	}

	protected function _process_files($arr, $type)
	{
		$file_name=$this->_cache_path.'/'
		.md5(
			implode('', $arr)
			.(($type=='js')?config::get('compress_js'):config::get('compress_css'))
			.(($type=='js')?config::get('js_compressor'):config::get('css_compressor'))
		)
		.'.'.$type;

		if (file_exists($file_name)) {
			if (config::get('check')) {
				if (!$this->_isAllFilesOlder($arr, $file_name)) $this->_createCompressedFile($arr, $type, $file_name);
			}
		} else {
			$this->_createCompressedFile($arr, $type, $file_name);
		}
		return str_replace(LAB_PATH_ROOT, '', $file_name).'?'.config::get('core.lastCacheReset');
	}

	protected function _createCompressedFile($arr, $type, $name)
	{
		if (!is_dir(dirname($name))) mkdir(dirname($name), 0777);
		$handle = fopen($name, "w");
		foreach ($arr as $file) {
			if ($type=='css') {
				fwrite($handle, $this->_compressCss($file));
			} else {
				fwrite($handle, $this->_compressJs($file));
			}
		}
		fclose($handle);
		return true;
	}

	protected function _compressJs($file)
	{
		if (config::get('compress_js')) {
			return $this->_getCompressor()->getJs(file_get_contents($file));
		} else {
			return file_get_contents($file);
		}
	}

	protected function _compressCss($file)
	{
		$data=$this->_getCssData($file);
		if (config::get('compress_css')) {
			return $this->_getCompressor()->getCss($data);
		} else {
			return $data;
		}
	}

	protected function _getCssData($file)
	{
		$data='@media '.$this->_getCssMedia(basename($file, '.css')).'{'.$this->_resolveCssImports($file).'}';
		
		$data=str_replace("\r\n", "\n", $data);
		
		return $data;
	}

	protected function _getCssMedia($media)
	{
		return	(
			in_array(
				$media,
				array('braille', 'embossed', 'handheld', 'print', 'projection', 'screen', 'speech', 'tty', 'tv')
			)
		)?$media:'all';
	}

	protected function _resolveCssImports($src)
	{
		$content=$this->_getFileWithReplaceRelativePath($src);
		/* удаляем из первоначального содержимого @import внутри комментариев */
		$content = preg_replace("!/\*\s*@import.*?\*/!is", "", $content);
		/* выбираем все @import */
		preg_match_all('/@import\s*(url)?\s*\(?([^;]+?)\)?;/i', $content, $imports, PREG_SET_ORDER);
		if (is_array($imports)) {
			foreach ($imports as $import) {
				$src = false;
				/* очищаем найденный путь к файлу от пробелов и кавычек */
				if (isset($import[2])) {
					$src = $import[2];
					$src = trim($src, '\'" ');
				}
				if ($src) {
					/* запускаем рекурсию для обнаруженного файла, чтобы разрешить все @import	уже внутри него */
					$content = str_replace($import[0], $this->_resolveCssImports(LAB_PATH_ROOT.$src), $content);
					/* изменяем все пути для CSS-изображений и ресурсов (относительно заданного	файла) 
					на абсолютные (относительн корня документа) */
					//$content = $this->resolve_relative_paths($src, $content);
				}
			}
		}
		return $content;
	}

	protected function _getFileWithReplaceRelativePath($src)
	{
		$content = file_get_contents($src);
		$base=str_replace(LAB_PATH_ROOT, '', dirname($src)).'/';
		preg_match_all('/url\s*\(\s*([\'|"]?)(.+?)\1\s*\)/', $content, $strings);
		if (count($strings[2])) {
			foreach ($strings[2] as $key=>$url) {
				if (substr($url, 0, 1)=='/') continue;
				if (substr($url, 0, 7)=='http://') continue;
				if (substr($url, 0, 8)=='https://') continue;
				if (substr($url, 0, 5)=='data:') continue;
				$new_url=str_replace($url, $base.$url, $strings[0][$key]);
				$content=str_replace($strings[0][$key], $new_url, $content);
			}
		}
		return $content;
	}

	protected function _isAllFilesOlder($files, $file)
	{
		$filetime=filemtime($file);
		foreach ($files as $item) {
			if (filemtime($item)>$filetime) return false;
		}
		return true;
	}

	protected function _getCompressor()
	{
		if (!is_object($this->_compressor)) {
			$this->_compressor=Factory::create('js_css_compressor.compressor');
		}
		return $this->_compressor;
	}


}