<%
    local fs = require "luci.openclash"
    local plugin_version = fs.oc_version()
%>
<script src="/luci-static/resources/openclash/js/common.js?v=<%=plugin_version%>"></script>
<link rel="stylesheet" href="/luci-static/resources/openclash/css/oc.css?v=<%=plugin_version%>">
<script src="/luci-static/resources/openclash/js/cm6.min.js?v=<%=plugin_version%>"></script>
<script src="/luci-static/resources/openclash/js/oc-icons.js?v=<%=plugin_version%>"></script>

<%-
local path_info = os.getenv("PATH_INFO") or ""
local sid = path_info:match("(cfg[0-9a-f]+)") or ""
-%>

<%+openclash/common%>
<script type="text/javascript">//<![CDATA[

ocRegisterEditorHotkeys();

// All editable editors use EditorView.updateListener (not view.dispatch)
// to sync content back to the hidden textarea.  The dispatch override is
// unreliable because CM6 can pass either a Transaction (with docChanged)
// or a TransactionSpec (without docChanged) to dispatch().

function editor(id, readOnly, wid, height) {
	id.style.display = 'none';
	id.parentNode.classList.add('oc');
	ocShowLoading(id.parentNode, '<%:Loading...%>', height);
	var isDark = isDarkBackground(document.body);
	var exts = [CM6.baseExtensions(), CM6.themeExtension(isDark), CM6.placeholderExtension('<%:Enter YAML configuration...%>')];
	var topSearch = (CM6 && CM6.topSearchExtension) ? CM6.topSearchExtension() : null;
	if (topSearch) exts.push(topSearch);
	exts.push(CM6.yaml());
	exts.push(CM6.yamlLinter());
	exts.push(CM6.lintGutter());
	exts.push(CM6.autocompletion({ override: [CM6.mihomoCompletion] }));
	exts.push(CM6.indentUnit.of("  "));
	exts.push(CM6.indentMarkerExtension());
	if (readOnly) exts.push(CM6.EditorState.readOnly.of(true));

	exts.push(CM6.EditorView.updateListener.of(function(update) {
		if (update.docChanged) id.value = update.state.doc.toString();
	}));

	var view = new CM6.EditorView({
		state: CM6.EditorState.create({ doc: id.value, extensions: exts })
	});
	id.parentNode.insertBefore(view.dom, id.nextSibling);
	ocHideLoading(id.parentNode);
	ocUpdateTheme();
	if (wid && height) {
		view.dom.style.width = wid;
		view.dom.style.height = height;
	}
	return view;
}

function shell_editor(id, readOnly, wid, height) {
	id.style.display = 'none';
	id.parentNode.classList.add('oc');
	ocShowLoading(id.parentNode, '<%:Loading...%>', height);
	var isDark = isDarkBackground(document.body);
	var exts = [CM6.baseExtensions(), CM6.themeExtension(isDark), CM6.placeholderExtension('<%:Enter shell script...%>')];
	var topSearch = (CM6 && CM6.topSearchExtension) ? CM6.topSearchExtension() : null;
	if (topSearch) exts.push(topSearch);
	exts.push(CM6.StreamLanguage.define(CM6.shell));
	if (readOnly) exts.push(CM6.EditorState.readOnly.of(true));

	exts.push(CM6.EditorView.updateListener.of(function(update) {
		if (update.docChanged) id.value = update.state.doc.toString();
	}));

	var view = new CM6.EditorView({
		state: CM6.EditorState.create({ doc: id.value, extensions: exts })
	});
	id.parentNode.insertBefore(view.dom, id.nextSibling);
	ocHideLoading(id.parentNode);
	ocUpdateTheme();
	if (wid && height) {
		view.dom.style.width = wid;
		view.dom.style.height = height;
	}
	return view;
}

function other_editor(id, readOnly, wid, height) {
	id.style.display = 'none';
	id.parentNode.classList.add('oc');
	ocShowLoading(id.parentNode, '<%:Loading...%>', height);
	var isDark = isDarkBackground(document.body);
	var exts = [CM6.baseExtensions(), CM6.themeExtension(isDark), CM6.placeholderExtension('<%:Enter configuration...%>')];
	var topSearch = (CM6 && CM6.topSearchExtension) ? CM6.topSearchExtension() : null;
	if (topSearch) exts.push(topSearch);
	exts.push(CM6.StreamLanguage.define(CM6.properties));
	if (readOnly) exts.push(CM6.EditorState.readOnly.of(true));

	exts.push(CM6.EditorView.updateListener.of(function(update) {
		if (update.docChanged) id.value = update.state.doc.toString();
	}));

	var view = new CM6.EditorView({
		state: CM6.EditorState.create({ doc: id.value, extensions: exts })
	});
	id.parentNode.insertBefore(view.dom, id.nextSibling);
	ocHideLoading(id.parentNode);
	ocUpdateTheme();
	if (wid && height) {
		view.dom.style.width = wid;
		view.dom.style.height = height;
	}
	return view;
}

function log_editor(id, name, readOnly, wid, height) {
	id.style.display = 'none';
	id.parentNode.classList.add('oc');
	ocShowLoading(id.parentNode, '<%:Loading...%>', height);
	var isDark = isDarkBackground(document.body);
	var exts = [CM6.lineNumbers(), CM6.EditorView.lineWrapping, CM6.EditorState.readOnly.of(true), CM6.themeExtension(isDark)];
	var topSearch = (CM6 && CM6.topSearchExtension) ? CM6.topSearchExtension() : null;
	if (topSearch) exts.push(topSearch);
	exts.push(CM6.highlightActiveLine());
	exts.push(CM6.drawSelection());
	exts.push(CM6.highlightSelectionMatches());
	exts.push(CM6.keymap.of(CM6.searchKeymap));
	exts.push(CM6.logLanguage);
	exts.push(CM6.syntaxHighlighting(CM6.logHighlightStyle));

	var view = new CM6.EditorView({
		state: CM6.EditorState.create({ doc: id.value, extensions: exts })
	});
	id.parentNode.insertBefore(view.dom, id.nextSibling);
	ocHideLoading(id.parentNode);
	ocUpdateTheme();
	window['editor_' + name] = view;
	if (wid && height) {
		view.dom.style.width = wid;
		view.dom.style.height = height;
	}
	view.getValue = function() { return view.state.doc.toString(); };
	view.setValue = function(v) { view.dispatch({ changes: { from: 0, to: view.state.doc.length, insert: v || '' } }); };
	view.refresh = function() { view.dispatch({}); if (view.requestMeasure) view.requestMeasure(); };
	view.getScrollInfo = function() { var sd = view.scrollDOM; return { top: sd.scrollTop, left: sd.scrollLeft, height: sd.scrollHeight, width: sd.scrollWidth, clientHeight: sd.clientHeight, clientWidth: sd.clientWidth }; };
	view.scrollTo = function(l, t) { if (typeof l === 'object') { t = l.top; l = l.left; } view.scrollDOM.scrollTop = t || 0; view.scrollDOM.scrollLeft = l || 0; };
	view.getCursor = function() { var h = view.state.selection.main.head, ln = view.state.doc.lineAt(h); return { line: ln.number - 1, ch: h - ln.from }; };
	view.setCursor = function(p) { var ln = view.state.doc.line(p.line + 1); view.dispatch({ selection: { anchor: ln.from + p.ch } }); };
	var _hasFocusDesc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(view), 'hasFocus');
	var _hf;
	if (_hasFocusDesc && _hasFocusDesc.get) {
		try { _hf = function() { return _hasFocusDesc.get.call(view); }; } catch(e) { _hf = null; }
	}
	if (!_hf) {
		_hf = function() { try { return view.contentDOM.ownerDocument.activeElement === view.contentDOM; } catch(e) { return false; } };
	}
	Object.defineProperty(view, 'hasFocus', { value: _hf, writable: true, configurable: true });
	view.somethingSelected = function() { return !view.state.selection.main.empty; };
	view.setSelection = function(f, t) { var lf = view.state.doc.line(f.line + 1), lt = view.state.doc.line(t.line + 1); view.dispatch({ selection: { anchor: lf.from + f.ch, head: lt.from + t.ch } }); };
	view.scrollIntoView = function(p, m) { if (p && p.line !== undefined) { var ln = view.state.doc.line(p.line + 1); view.dispatch({ selection: { anchor: ln.from + (p.ch || 0) }, scrollIntoView: true }); } else { view.dispatch({ selection: { anchor: view.state.selection.main.head }, scrollIntoView: true }); } };
	if (view.state.doc.length > 0 && view.state.doc.lines >= 1) {
		var fl = view.state.doc.line(1);
		view.dispatch({ selection: { anchor: fl.to } });
	}
	return view;
}

function markdown_editor(id, name, readOnly, wid, height) {
	id.style.display = 'none';
	id.parentNode.classList.add('oc');
	ocShowLoading(id.parentNode, '<%:Loading...%>', height);
	var isDark = isDarkBackground(document.body);
	var exts = [CM6.lineNumbers(), CM6.EditorView.lineWrapping, CM6.themeExtension(isDark), CM6.markdown()];
	if (readOnly) exts.push(CM6.EditorState.readOnly.of(true));

	var view = new CM6.EditorView({
		state: CM6.EditorState.create({ doc: id.value || '', extensions: exts })
	});
	id.parentNode.insertBefore(view.dom, id.nextSibling);
	ocHideLoading(id.parentNode);
	ocUpdateTheme();
	window['editor_' + name] = view;
	if (wid && height) {
		view.dom.style.width = wid;
		view.dom.style.height = height;
	}
	view.getValue = function() { return view.state.doc.toString(); };
	view.setValue = function(v) { view.dispatch({ changes: { from: 0, to: view.state.doc.length, insert: v || '' } }); };
	view.refresh = function() { view.dispatch({}); };
	view.dom = view.dom;
	return view;
}

var _cmWhenReady = window._cmWhenReady;

(function() {
var oc_log = document.getElementById("cbid.openclash.config.clog");
if (oc_log) { log_editor(oc_log, 'oc', true, '100%', '540px'); }

var custom_cfg_value = document.getElementById("cbid.openclash.<%=sid%>.other_parameters");
if (custom_cfg_value) {
	editor(custom_cfg_value, false, '100%', '300px');
}

var custom_firewall = document.getElementById("cbid.openclash.config.firewall_custom");
if (custom_firewall) {
	shell_editor(custom_firewall, false, "100%", '300px');
}

var myEditor_hosts = document.getElementById("cbid.openclash.config.custom_hosts");
var myEditor_fall_fil = document.getElementById("cbid.openclash.config.custom_fallback_fil");
var myEditor_name_pol = document.getElementById("cbid.openclash.config.custom_domain_dns_core");
var myEditor_name_cus_r1 = document.getElementById("cbid.openclash.config.custom_rules_2");
var myEditor_name_cus_r2 = document.getElementById("cbid.openclash.config.custom_rules");
var myEditor_fake_filter = document.getElementById("cbid.openclash.config.custom_fake_filter");
var myEditor_custom_domain_dns = document.getElementById("cbid.openclash.config.custom_domain_dns");
var myEditor_edit_file = document.getElementById("cbid.openclash.config.edit_file");
var myEditor_custom_sniffer = document.getElementById("cbid.openclash.config.sniffer_custom");
var myEditor_proxy_name_pol = document.getElementById("cbid.openclash.config.custom_proxy_server_dns_policy");
var myEditor_local_network_pass = document.getElementById("cbid.openclash.config.local_network_pass");
var myEditor_chnroute_pass = document.getElementById("cbid.openclash.config.chnroute_pass");
var myEditor_local_network6_pass = document.getElementById("cbid.openclash.config.local_network6_pass");
var myEditor_chnroute6_pass = document.getElementById("cbid.openclash.config.chnroute6_pass");

if (myEditor_hosts) { editor(myEditor_hosts, false, '100%', '300px'); }
if (myEditor_edit_file) { editor(myEditor_edit_file, false, '100%', '700px'); }
if (myEditor_fall_fil) { editor(myEditor_fall_fil, false, '100%', '300px'); }
if (myEditor_name_pol) { editor(myEditor_name_pol, false, '100%', '300px'); }
if (myEditor_proxy_name_pol) { editor(myEditor_proxy_name_pol, false, '100%', '300px'); }
if (myEditor_name_cus_r1) {
	editor(myEditor_name_cus_r1, false, '100%', '300px');
	editor(myEditor_name_cus_r2, false, '100%', '300px');
}
if (myEditor_fake_filter) { other_editor(myEditor_fake_filter, false, '100%', '300px'); }
if (myEditor_custom_domain_dns) { other_editor(myEditor_custom_domain_dns, false, '100%', '300px'); }
if (myEditor_custom_sniffer) { other_editor(myEditor_custom_sniffer, false, '100%', '300px'); }
if (myEditor_local_network_pass) { other_editor(myEditor_local_network_pass, false, '600px', '300px'); }
if (myEditor_chnroute_pass) { other_editor(myEditor_chnroute_pass, false, '600px', '300px'); }
if (myEditor_local_network6_pass) { other_editor(myEditor_local_network6_pass, false, '600px', '300px'); }
if (myEditor_chnroute6_pass) { other_editor(myEditor_chnroute6_pass, false, '600px', '300px'); }

})();

//]]>
</script> 