<?php

/**
 * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 * @package clearFusionCMS\module\codemirror
 * @copyright Copyright (c) 2014 - 2016 clearFusionCMS. All rights reserved.
 * @link http://clearfusioncms.com
 */

/**
 * codemirrorWYSIWYG Class
 *
 * Class to draw the editor.
 *
 * @package clearFusionCMS\module\codemirror
 */
class codemirrorWYSIWYG extends flFormElementWYSIWYGCodeModule {

	/**
	 * Get the CSS class to add to the textarea.
	 *
	 * @return string The CSS class or null if not used.
	 */
	function getCSSClass() {
		return null;
	}

	/**
	 * Get if dimensions must be included in the style of the textarea.
	 *
	 * @return bool true if dimensions in style attribute; else false.
	 */
	function dimensionsInStyle() {
		return false;
	}

	/**
	 * Render the editor code.
	 *
	 * @param flDb $db The database object.
	 * @param flBufferCode $codeBuffer The code buffer.
	 * @param array $settings The array of settings for editor.
	 * @return string The HTML for inclusion.
	 */
	function render($db, $codeBuffer, $settings) {
		$cfg = isset($settings['_internal_cfg']) ? $settings['_internal_cfg'] : clearFusionCMS::getSiteConfig('cfCodeMirror');

		$codeBuffer->bufferCSS('system/modules/codemirror/scripts/lib/codemirror.css')
			->bufferCSS('system/modules/codemirror/scripts/addon/dialog/dialog.css')
			->bufferCSS('system/modules/codemirror/editor.css')
			->bufferHeadJS('system/modules/codemirror/scripts/lib/codemirror.js')
			->bufferHeadJS('system/modules/codemirror/scripts/addon/edit/matchbrackets.js')
			->bufferHeadJS('system/modules/codemirror/scripts/addon/edit/closebrackets.js')
			->bufferHeadJS('system/modules/codemirror/scripts/addon/comment/continuecomment.js')
			->bufferHeadJS('system/modules/codemirror/scripts/addon/selection/active-line.js')
			->bufferHeadJS('system/modules/codemirror/scripts/addon/search/searchcursor.js')
			->bufferHeadJS('system/modules/codemirror/scripts/addon/search/search.js')
			->bufferHeadJS('system/modules/codemirror/scripts/addon/dialog/dialog.js')
			->bufferHeadJS('system/modules/codemirror/scripts/addon/search/match-highlighter.js');

		if($settings['allowFullScreen'])
			$codeBuffer->bufferHeadJS('system/modules/codemirror/scripts/addon/display/fullscreen.js');

		if(!empty($cfg->theme)) {
			$codeBuffer->bufferCSS('system/modules/codemirror/scripts/theme/' . $cfg->theme . '.css');
			$theme = ',theme: "' . $cfg->theme . '"';
		}
		else
			$theme = '';

		static $firstInst = true;
		if($firstInst) {
			$firstInst = false;
			$codeBuffer->bufferCSS(".CodeMirror { border: 1px solid #ccc; }
.CodeMirror-focused .cm-matchhighlight { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFklEQVQI12NgYGBgkKzc8x9CMDAwAAAmhwSbidEoSQAAAABJRU5ErkJggg==); background-position: bottom; background-repeat: repeat-x; }");
		}

		$mode = '';

		$wrap = $cfg->get('alwaysWrap', true) ? 'true' : 'false';
		switch($settings['contentType']) {
			case 'snippet':
				$codeBuffer->bufferHeadJS('system/modules/codemirror/scripts/mode/clike/clike.js')
					->bufferHeadJS('system/modules/codemirror/js/snippet.js');
				$mode = 'mode: "application/x-httpd-php",';
				break;

			case 'css':
			case 'text/css':
				$codeBuffer
					->bufferHeadJS('system/modules/codemirror/scripts/mode/css/css.js');
				$mode = 'mode: "text/x-less",';
				break;

			case 'md':
			case 'text/markdown':
			case 'text/x-markdown':
				$codeBuffer->bufferHeadJS('system/modules/codemirror/scripts/addon/mode/overlay.js')
					->bufferHeadJS('system/modules/codemirror/scripts/mode/xml/xml.js')
					->bufferHeadJS('system/modules/codemirror/scripts/mode/markdown/markdown.js')
					->bufferHeadJS('system/modules/codemirror/scripts/mode/gfm/gfm.js')
					->bufferHeadJS('system/modules/codemirror/scripts/mode/javascript/javascript.js')
					->bufferHeadJS('system/modules/codemirror/scripts/mode/css/css.js')
					->bufferHeadJS('system/modules/codemirror/scripts/mode/htmlmixed/htmlmixed.js')
					->bufferHeadJS('system/modules/codemirror/scripts/mode/clike/clike.js')
					->bufferHeadJS('system/modules/codemirror/scripts/mode/meta.js')
					->bufferHeadJS('system/modules/codemirror/scripts/mode/shell/shell.js')
					->bufferHeadJS('system/modules/codemirror/scripts/mode/php/php.js');
				$mode = 'mode: "gfm",';
				break;

			case 'xml':
			case 'text/xml':
				$codeBuffer->bufferHeadJS('system/modules/codemirror/scripts/mode/xml/xml.js');
				$mode = 'mode: {name: "xml", alignCDATA: true},';
				break;

			case 'text/javascript':
			case 'application/javascript':
			case 'application/x-javascript':
				$codeBuffer->bufferHeadJS('system/modules/codemirror/scripts/mode/javascript/javascript.js');
				$mode = 'mode: "text/javascript",';
				break;

			case 'application/json':
				$codeBuffer->bufferHeadJS('system/modules/codemirror/scripts/mode/javascript/javascript.js');
				$mode = 'mode: "application/json",';
				break;

			case 'textwrap':
				$wrap = 'true';

			case 'text':
			case 'text/plain':
				break;

			case 'html':
			case 'chunk':
			default:
				$codeBuffer->bufferHeadJS('system/modules/codemirror/scripts/mode/xml/xml.js')
					->bufferHeadJS('system/modules/codemirror/scripts/mode/javascript/javascript.js')
					->bufferHeadJS('system/modules/codemirror/scripts/mode/css/css.js')
					->bufferHeadJS('system/modules/codemirror/scripts/mode/htmlmixed/htmlmixed.js');
				$mode = 'mode: "text/html",';
				break;
		}

		$edName = str_replace('.', '_', $this->name) . '_CodeMirror';
		$js = "<script type=\"text/javascript\">
//<![CDATA[" . "
(function() {
var $edName = CodeMirror.fromTextArea(document.getElementById('{$this->name}'), {
		matchBrackets: true,
		$mode
		" . (isset($settings['_internal_opts']) ? $settings['_internal_opts'] : '') . "
		lineNumbers: true,
		styleActiveLine: true,
		highlightSelectionMatches: true,
		autoCloseBrackets: true,
		matchBrackets: true,
		indentUnit: 4,
		indentWithTabs: true,
		readOnly: " . ($settings['readOnly'] ? 'true' : 'false') . ",
		enterMode: \"keep\",
		tabMode: \"shift\",
		lineWrapping: $wrap" . ($settings['allowFullScreen'] ? ",
		extraKeys: {
			\"Esc\": function(cm) {
				cm.setOption(\"fullScreen\", !cm.getOption(\"fullScreen\"));
			}
		}" : '') . "
		$theme
	});
$edName.on('blur', function() {
	var l = {
		position: $edName.getCursor(),
		page: window.location.href
	};
	sessionStorage.setItem('$edName.location', JSON.stringify(l));
});
";

		// Setup additional events
		if(isset($settings['_internal_events'])) {
			foreach($settings['_internal_events'] as $e => $code) {
				$js .= "$edName.on('$e', $code);\n";
			}
		}

		$js .= "var d = sessionStorage.getItem('$edName.location');
if(d) {
	d = JSON.parse(d);
	if(d.page == window.location.href)
		$edName.setCursor(d.position);
}
\$fl(document).ready(function() {
	$edName.setSize('$settings[width]', '$settings[height]');
});
" . (isset($settings['_internal_js']) ? $settings['_internal_js'] : '') . "
})();
//]]>
</script>
";

		return $js;
	}
}
