<?php
	ini_set('display_errors', 1);
	ini_set('display_startup_errors', 1);
	error_reporting(E_ALL);

	chdir('..');
	include_once 'lib/config.php';
	include 'lib/default.php';

	$filename = GetUrlParameter('filename');
	$type = def_type(GetUrlParameter('type'));
	$title = def_title(GetUrlParameter('title'));
	$date = def_date(GetUrlParameter('date'));
	$cats = def_cats(GetUrlParameter('cats'));
	$tags = def_tags(GetUrlParameter('tags'));
	$content = GetUrlParameter('content');
?>
<!DOCTYPE html>
<html lang="<?php echo $lang; ?>">
<head>
	<base href="../" />
	<meta charset="UTF-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />

	<link rel="icon" href="<?php echo $cssVars['--WebsiteIcon']; ?>" />
	<link rel="apple-touch-icon" href="<?php echo $cssVars['--WebsiteIcon']; ?>" />
	<meta name="msapplication-TileImage" content="<?php echo $cssVars['--WebsiteIcon']; ?>" />

	<title>Vorschau</title>

	<style>
		<?php if (ExistsStylesheet(true)) include 'lib/' . GetStylesheet(true); ?>
		<?php if (ExistsUserStylesheet(true)) include 'lib/' . GetUserStylesheet(true); ?>

		html {
			--PreviewSnippetBorderColor: grey;

			--CodeBgColor: white;

			--CodeFgColor: black;
			--RemarkFgColor: #00AA00;
			--PhpFgColor: #B33535;
			--JsFgColor: #0000C0;
			--CssFgColor: #808000;

			--CodeSelColor: #CBCBCB;
			--RemarkSelColor: #A6ECA6;
			--PhpSelColor: #FFD7D7;
			--JsSelColor: #C0E0FF;
			--CssSelColor: #E1E27A;

			--LineNoFgColor: grey;
			--LineNoBgColor: #E0E0E0;

			--ColorInfoSelColor: #00000040;
		}

		@media (prefers-color-scheme: dark) {
		html {
			--PreviewSnippetBorderColor: grey;

			--CodeBgColor: #1F1F1F;

			--CodeFgColor: #C7C7C7;
			--RemarkFgColor: #40A040;
			--PhpFgColor: #DD9999;
			--JsFgColor: #40A0C0;
			--CssFgColor: #C0C040;

			--CodeSelColor: #484848;
			--RemarkSelColor: #484848;
			--PhpSelColor: #484848;
			--JsSelColor: #484848;
			--CssSelColor: #484848;

			--LineNoFgColor: #C7C7C7;
			--LineNoBgColor: #3C3C3C;

			--ColorInfoSelColor: #00000040;
		} }

		/* Die in default.css angegebenen grid-Definitionen überschreiben: */

		body {
			grid-template-areas: "main";
		}

		body.config {
			grid-template-areas: "menu" "header" "main";

		}

		@media (min-width: 800px) {
			body {
				grid-template-areas: "main";
				grid-template-columns: auto;
			}
		}

		main {
			padding: 15px;
		}

		article {
			margin-bottom: 0;
		}

		pre.preview {
			font-size: revert;
			line-height: 1.2em;
			white-space: pre-wrap;
			_line-break: anywhere; /* Zeilen werden an jeder beliebigen Stelle umgebrochen */
			word-wrap: break-word; /* Zeilen werden an jedem Wortanfang umgebrochen */
			_word-break: break-all; /* Zeilen werden mitten im Wort, aber erst nach anhängende Whitespaces umgebrochen */
			hyphens: none;
			tab-size: 2;
			margin: 0;
			padding: 0;
			color: var(--CodeFgColor);
			background-color: var(--CodeBgColor);
		}

		pre.preview::selection {
			background-color: var(--CodeSelColor);
		}

		span.remark {
			color: var(--RemarkFgColor);
		}

		span.remark::selection {
			background-color: var(--RemarkSelColor);
		}

		span.php-tag {
			color: var(--PhpFgColor);
			font-weight: bold;
		}

		span.php-code {
			color: var(--PhpFgColor);
		}

		span.php-tag::selection,
		span.php-code::selection {
			background-color: var(--PhpSelColor);
		}

		span.js-tag {
			color: var(--JsFgColor);
			font-weight: bold;
		}

		span.js-code {
			color: var(--JsFgColor);
		}

		span.js-tag::selection,
		span.js-code::selection {
			background-color: var(--JsSelColor);
		}

		span.css-tag {
			color: var(--CssFgColor);
			font-weight: bold;
		}

		span.css-code {
			color: var(--CssFgColor);
		}

		span.css-tag::selection,
		span.css-code::selection {
			background-color: var(--CssSelColor);
		}

		span.line-number {
			color: var(--LineNoFgColor);
			background-color: var(--LineNoBgColor);
			padding-left: 10px;
			padding-right: 10px;
			margin-left: 1px;
			margin-right: 10px;
		}
		span.line-number::selection {
			color: var(--LineNoFgColor);
			background-color: var(--LineNoBgColor);
		}

		span.color-info {
			border: 1px solid var(--CodeFgColor);
			margin-left: 2px;
		}

		span.color-info::selection {
			background-color: var(--ColorInfoSelColor);
		}

	</style>

	<script>
		"use strict";
		<?php include 'lib/default.js'; ?>
		document.addEventListener('DOMContentLoaded', InitPreview);
	</script>
</head>

<body>
<?php
	$g_end = false;
	$g_line = '';
	$g_cssVars = [];

	InitDefault();

	// Snippet

	if ($type === 'snippet')
	{
		if (preg_match('/^snippets[^\.]*\.xml$/', $filename))
		{
			echo '<main>';
			echo '	<article>';
			echo '		<div class="article-content">';

			$xmlSnippets = $content;
			if ($xmlSnippets)
			{
				$snippets = new SimpleXMLElement($xmlSnippets);
				foreach ($snippets->section as $section)
				{
					echo '			<h2>' . $section['caption'] . '</h2>';
					foreach ($section->item as $item)
					{
						$snippetFilename = $item['filename'];
						echo "			<h3><a href=\"snippets/$snippetFilename\">" . (string) $item . "</a></h3>";
						echo '			<div style="border: 1px dashed var(--PreviewSnippetBorderColor);">';
						if (file_exists("snippets/$snippetFilename"))
							include "snippets/$snippetFilename";
						else
							printf('<p class="center error">' . GetString('ErrorFile#NotFound') . '</p>', $snippetFilename);
						echo '			</div>';
					}
				}
			}
			echo '		</div>';
			echo '	</article>';
			echo '</main>';
			$g_end = true;
		}
	}

	// Widget

	if ($type === 'widget')
	{
		echo '<main>';
		if (preg_match('/^widgets[^\.]*\.xml$/', $filename))
		{
			PrintWidgets($content);
		}
		else
		{
			echo '	<div class="widget">';
			echo '		<h1>' . $title . '</h1>';
			file_put_contents('lib/preview.tmp', $content, LOCK_EX);
			include 'lib/preview.tmp';
			echo '	</div>';
		}
		echo '</main>';
		$g_end = true;
	}

	// Systemdatei

	if ($type === 'system')
	{
		if (preg_match('/^menu[^\.]*\.xml$/', $filename))
		{
			echo '<main>';
			echo '	<nav>';
			echo '		<div class="logo" style="all: unset;"></div>';
			echo '		<div class="menu">';
			PrintMenu($content);
			echo '		</div>';
			echo '	</nav>';
			echo '</main>';
			echo '	<script>InitMenu();</script>';
		}
		else if (preg_match('/^config[^\.]*\.php$/', $filename))
		{
			$websiteName = '';
			$headerTitle = '';
			$headerSubtitle = '';

			file_put_contents('lib/preview.tmp', $content, LOCK_EX);
			include 'lib/preview.tmp';

			echo '<nav>';
			echo '	<div class="logo"><a href="' . $baseUrl . '">' . $websiteName . '</a></div>';
			echo '	<div class="menu">'; PrintMenu(); echo '</div>';
			echo '</nav>';
			echo '<header>';
			echo '	<p>' . $headerTitle . '</p>';
			echo '	<p>' . NoWrap($headerSubtitle) . '</p>';
			echo '</header>';
			echo '<main>';
			echo '	<article class="image">';
			echo '		<div class="article-header"></div>';
			echo '		<div class="article-content">';
			echo '			<h1>' . def_title('') . '</h1>';
			echo '			<h6>' . MakeDisplayDate(def_date('')) . '</h6>';
			echo '			<p>' . def_description('') . '</p>';
			echo '		</div>';
			echo '	</article>';
			echo '</main>';
			echo '<script>InitMenu();</script>';
			echo '<script>document.body.classList.add("config");</script>';
		}
		else
		{
//			echo '<p class="center">' . GetString('PreviewNotAvailable') . '.</p>';
			echo '<main>';
			echo '	<article>';
			echo '		<pre class="preview">';
			PrintSourcecode($content);
			echo       '</pre>';
			echo '	</article>';
			echo '</main>';
		}
		$g_end = true;
	}

	// Artikel

	if (!$g_end)
	{
		echo '<main>';
		echo '	<article>';
		echo '		<div class="article-content">';

		if ($type === 'post' || $type === 'page' || $type === 'template')
		{
			$displayDate = $type !== 'page' ? MakeDisplayDate($date) : '';
			echo "			<h1>$title</h1>";
			echo "			<h6>$displayDate</h6>";
		}

		file_put_contents('lib/preview.tmp', $content, LOCK_EX);
		include 'lib/preview.tmp';

		if ($type === 'post' && (!empty($cats) || !empty($tags)))
		{
			echo '			<div class="article-links">';
			PrintCatsOrTags($cats, 'cats');
			PrintCatsOrTags($tags, 'tags');
			echo "			</div>\n";
		}

		echo '		</div>';
		echo '	</article>';
		echo '</main>';
	}

	// Funktionen
	
	function PrintSourcecode($content)
	{
		if (!empty($content))
		{
			$sourcecode = EncodeHtml($content, false);
			$sourcecode = ReplaceColors($sourcecode);
			$sourcecode = ReplaceUrls($sourcecode);
			$sourcecode = HighlightCode($sourcecode);
			$sourcecode = AddLineNumbers($sourcecode);
			echo '<script>var g_noPrettify = true;</script>';
			echo $sourcecode;
		}
	}

	function AddLineNumbers($sourcecode)
	{
		$lines = explode(PHP_EOL, $sourcecode);
		$sourcecode = '';
		$lineNo = 0;

		$tabSize = 2;
		$digits = strlen(count($lines));
		$width = ((int)(($digits - 1) / $tabSize) * $tabSize) + $tabSize;

		foreach ($lines as $line)
		{
			$lineNo++;
			//$width = $digits - strlen($lineNo);
			$line = '<span class="line-number">' . sprintf('%*d', $width, $lineNo) . '</span>' . $line;
			$sourcecode .= $line . PHP_EOL;
		}
		return rtrim($sourcecode);
	}

	function ReplaceColors($sourcecode)
	{
		global $g_line;
		global $g_cssVars;

		// HTML-Farbnamen (siehe https://www.w3schools.com/colors/colors_names.asp)
		$colorNames = array('aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure', 'beige', 'bisque', 'black', 'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan', 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen', 'darkgrey', 'darkkhaki', 'darkmagenta', 'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'darksalmon', 'darkseagreen', 'darkslateblue', 'darkslategray', 'darkslategrey', 'darkturquoise', 'darkviolet', 'deeppink', 'deepskyblue', 'dimgray', 'dimgrey', 'dodgerblue', 'firebrick', 'floralwhite', 'forestgreen', 'fuchsia', 'gainsboro', 'ghostwhite', 'gold', 'goldenrod', 'gray', 'green', 'greenyellow', 'grey', 'honeydew', 'hotpink', 'indianred', 'indigo', 'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen', 'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan', 'lightgoldenrodyellow', 'lightgray', 'lightgreen', 'lightgrey', 'lightpink', 'lightsalmon', 'lightseagreen', 'lightskyblue', 'lightslategray', 'lightslategrey', 'lightsteelblue', 'lightyellow', 'lime', 'limegreen', 'linen', 'magenta', 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple', 'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite', 'navy', 'oldlace', 'olive', 'olivedrab', 'orange', 'orangered', 'orchid', 'palegoldenrod', 'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip', 'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'purple', 'rebeccapurple', 'red', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown', 'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue', 'slategray', 'slategrey', 'snow', 'springgreen', 'steelblue', 'tan', 'teal', 'thistle', 'tomato', 'turquoise', 'violet', 'wheat', 'white', 'whitesmoke', 'yellow', 'yellowgreen');

		$lines = explode(PHP_EOL, $sourcecode);
		$sourcecode = '';

		foreach ($lines as $g_line)
		{
			foreach ($colorNames as $colorName)
			{
				$g_line = preg_replace_callback("/\b($colorName)\b/i", 'ReplaceColor', $g_line);
			}

			$g_line = preg_replace_callback('/(#[0-9A-F]+)\b/i', 'ReplaceColor', $g_line);
			$g_line = preg_replace_callback('/\b((?:rgb|rgba|hsl|hsla|hwb)\(.*?\))/', 'ReplaceColor', $g_line);

			foreach ($g_cssVars as $cssVar => $color)
			{
				$g_line = preg_replace("/\b(var\($cssVar\))/", '$1<span class="color-info" style="background-color: ' . $color . '">&nbsp;&nbsp;</span>', $g_line);
			}

			$sourcecode .= $g_line . PHP_EOL;
		}
		return rtrim($sourcecode);
	}

	function ReplaceColor($matches)
	{
		global $g_line;

		$color = '';
		if (count($matches) > 1)
		{
			$color = $matches[1];
			if (!preg_match('/^[\w]+\([\s]*\)$/', $color))
			{
				$color .= "<span class=\"color-info\" style=\"background-color: $color\">&nbsp;&nbsp;</span>";

				$search = preg_quote($matches[1], '/');
				preg_replace_callback("/(--.*):[\s]*($search)/", 'CollectVariable', $g_line);
			}
		}
		return $color;
	}

	function CollectVariable($matches)
	{
		global $g_cssVars;

		if (count($matches) > 2)
			$g_cssVars[$matches[1]] = $matches[2];
	}

	function ReplaceUrls($sourcecode)
	{
		return preg_replace_callback('/url\(\'([^\']+)\'\)/', function($matches)
		{
			$url = preg_replace('/<span[^<]+<\/span>/', '', $matches[1]); // Das durch ReplaceColors() in die URL eingefügte <span...>...</span> wieder rauslöschen.
			return "url('<a href=\"$url\" target=\"_blank\">$url</a>')";
		}, $sourcecode);
	}

	function HighlightCode($sourcecode)
	{
		$lines = explode(PHP_EOL, $sourcecode);
		$sourcecode = '';

		foreach ($lines as $line)
		{
			$line = preg_replace('/(\/\/.*)$/', '<span class="remark">$1</span>', $line); // Kommentar bis zum Zeilenende: // ...
			$line = preg_replace('/(\/\*)/', '<span class="remark">$1', $line); // Beginn Kommentar: /*
			$line = preg_replace('/(\*\/)/', '$1</span>', $line); // Ende Kommentar: */
			$line = preg_replace('/(&lt;!--)/', '<span class="remark">$1', $line); // Beginn Kommentar: <!--
			$line = preg_replace('/(--&gt;)/', '$1</span>', $line); // Ende Kommentar: -->
			$line = preg_replace('/(&lt;\?[\w]+)\b/', '<span class="php-tag">$1</span><span class="php-code">', $line); // Beginn PHP-Code
			$line = preg_replace('/(([^\\\]|^)\?&gt;)/', '</span><span class="php-tag">$1</span>', $line); // Ende PHP-Code
			$line = preg_replace('/(&lt;script.*?&gt;)/', '<span class="js-tag">$1</span><span class="js-code">', $line); // Beginn JS-Code
			$line = preg_replace('/(&lt;\/script&gt;)/', '</span><span class="js-tag">$1</span>', $line); // Ende JS-Code
			$line = preg_replace('/(&lt;style&gt;)/', '<span class="css-tag">$1</span><span class="css-code">', $line); // Beginn CSS-Code
			$line = preg_replace('/(&lt;\/style&gt;)/', '</span><span class="css-tag">$1</span>', $line); // Ende CSS-Code
			$sourcecode .= $line . PHP_EOL;
		}
		return rtrim($sourcecode);
	}

?>
	</main>
</body>
