<?php
/*
 * Copyright (c) 2013, webvariants GbR, http://www.webvariants.de
 *
 * This file is released under the terms of the MIT license. You can find the
 * complete text in the attached LICENSE file or online at:
 *
 * http://www.opensource.org/licenses/mit-license.php
 */

class sly_Controller_Devutilsdocs extends sly_Controller_Backend implements sly_Controller_Interface {
	private $init = 0;

	protected function init() {
		if ($this->init++) return;

		$docfiles = $this->getDocFiles();
		$curDoc   = sly_get('doc', 'string', '');
		$subpages = array(array(
			'page'  => 'devutilsdocs',
			'label' => 'Artikeltypen',
			'extra' => array('doc' => '')
		));

		foreach ($docfiles as $doc => $title) {
			$subpages[] = array('page' => 'devutilsdocs', 'label' => $title, 'extra' => array('doc' => $doc));
		}

		$_REQUEST['doc'] = $curDoc;

		$subpages = sly_Core::dispatcher()->filter('DEVUTILS_DOC_SUBPAGES', $subpages);

		// Titel ausgeben
		$layout = sly_Core::getLayout();
		$layout->pageHeader('Dokumentation', $subpages);
	}

	protected function getViewFolder() {
		return DEVUTILS_PATH.'views/';
	}

	public function indexAction() {
		$curDoc = sly_get('doc', 'string', '');

		if (!empty($curDoc)) {
			$controller = new sly_Controller_Devutilsdocs_Doc();
			return $controller->indexAction();
		}

		$this->init();

		$articleTypes = $this->collectTypes();
		$modules      = $this->collectModules();

		print $this->render('articletypes.phtml', compact('articleTypes', 'modules'));
	}

	protected function collectTypes() {
		$types       = array();
		$typeService = sly_Service_Factory::getArticleTypeService();
		$tplService  = sly_Service_Factory::getTemplateService();
		$allModules  = count($this->collectModules());

		foreach ($typeService->getArticleTypes() as $typeName => $title) {
			$typeData = array(
				'title'       => $title,
				'description' => $typeService->get($typeName, 'description', '<keine Beschreibung>')
			);

			//////////////////////////////////////////////////////////
			// which slots are available

			$template  = $typeService->getTemplate($typeName);

			if (!empty($template)) {
				$slotNames = $tplService->getSlots($template);
				$slots     = array();

				foreach ($slotNames as $slotName) {
					$modules = $typeService->getModules($typeName, $slotName);

					if (count($modules) === $allModules) {
						$modules = array('<alle>');
					}

					$slots[$slotName] = array(
						'title'   => $tplService->getSlotTitle($template, $slotName),
						'modules' => $modules
					);
				}

				$typeData['slots'] = $slots;
			}
			//////////////////////////////////////////////////////////
			// put the data in the result array

			$types[$typeName] = $typeData;
		}

		uasort($types, array($this, 'sortHelper'));
		return $types;
	}

	public function sortHelper($elA, $elB) {
		return strnatcasecmp($elA['title'], $elB['title']);
	}

	protected function collectModules() {
		$modules = array();
		$service = sly_Service_Factory::getModuleService();

		foreach ($service->getModules() as $name => $title) {
			$modules[$name] = array(
				'title'       => $title,
				'description' => $service->get($name, 'description', '<keine Beschreibung>')
			);
		}

		uasort($modules, array($this, 'sortHelper'));
		return $modules;
	}

	protected function getDocDir() {
		return SLY_DEVELOPFOLDER.'/docs/';
	}

	protected function getDocFiles($withTitle = true) {
		$dir = new sly_Util_Directory($this->getDocDir());

		if (!$dir->exists()) {
			return array();
		}

		$files  = $dir->listPlain(true, false);
		$result = array();

		foreach ($files as $filename) {
			if (!preg_match('#^(.+?)\.textile$#', $filename, $match)) continue;
			$result[$match[1]] = $withTitle ? $this->getDocTitle($filename) : $filename;
		}

		return $result;
	}

	protected function getDocTitle($filename) {
		$html = $this->getParsedDocFile($filename);

		if (!preg_match('#<h1>(.*?)</h1>#i', $html, $match)) {
			return ucfirst(str_replace('.textile', '', $filename));
		}

		return strip_tags($match[1]);
	}

	protected function getParsedDocFile($filename) {
		$realfile  = $this->getDocDir().$filename;
		$mtime     = filemtime($realfile);
		$cacheDir  = sly_Util_AddOn::internalDirectory('webvariants/developer-utils');
		$cacheFile = $cacheDir.'/'.str_replace(DIRECTORY_SEPARATOR, '_', $filename).'.html';

		if (!file_exists($cacheFile) || filemtime($cacheFile) < $mtime) {
			$html = $this->textile(file_get_contents($realfile));
			file_put_contents($cacheFile, $html);
		}
		else {
			$html = file_get_contents($cacheFile);
		}

		return $html;
	}

	protected function textile($text) {
		if (class_exists('GeSHi')) {
			preg_match_all('#(~{3,})([a-z0-9_]+)\1(.+?)\1#is', $text, $matches, PREG_SET_ORDER);

			foreach ($matches as $match) {
				$tildes   = $match[1];
				$language = $match[2];

				$geshi = new GeSHi(trim($match[3]), $language);
				$geshi->set_header_type(GESHI_HEADER_PRE);
				$geshi->enable_classes();
				$code = $geshi->parse_code();

				unset($geshi, $match[1], $match[2], $match[3]);

				// <pre>-Tag wieder entfernen

				$code = preg_replace('#^<pre.*?>#', '', $code);
				$code = preg_replace('#</pre>$#', '', $code);

				$text = str_replace($match[0], "notextile.. <pre class=\"devutils-highlighted lang-$language\">$code</pre>", $text);
			}
		}

		$parser = new Textile_Parser();
		$html   = $parser->TextileThis($text);

		return $html;
	}

	public function checkPermission($action) {
		return sly_Util_User::getCurrentUser() !== null;
	}
}
