function renderTalkTree(data) {
var container = document.getElementById('talktree');
if (!container) return;
if (!data || !data.talk || !data.talk.nodes) {
container.innerHTML = '
No conversation tree defined.
';
return;
}
window._talkData = data;
var nodes = data.talk.nodes;
var html = '
';
html += renderTreeNodes(nodes, 'start', {});
html += '
';
container.innerHTML = html;
}
function renderTreeNodes(nodes, rootKey, seen) {
var node = nodes[rootKey];
if (!node) return '';
if (seen[rootKey]) {
return '
' + esc(rootKey) + '(already shown)
';
}
seen[rootKey] = true;
var html = '';
html += '
';
html += '
';
html += '';
html += '' + esc(rootKey) + '';
html += '' + esc((node.message || '').substring(0, 60)) + '';
html += '
Options:';
if (node.options && node.options.length > 0) {
node.options.forEach(function(opt, idx) {
html += '
';
html += '' + esc(opt.text || '') + ' \u2192 ' + esc(opt.goto || '') + '';
if (opt.condition) html += ' [cond]';
if (opt.action) html += ' [action]';
html += ' ';
html += '
';
});
} else {
html += '
No options
';
}
html += '';
html += '
';
html += '
';
if (node.options) {
node.options.forEach(function(opt) {
if (opt.goto && nodes[opt.goto]) {
html += renderTreeNodes(nodes, opt.goto, seen);
}
});
}
return html;
}
function addOption(e, nodeKey) {
if (e) e.stopPropagation();
var data = window._talkData;
if (!data || !data.talk || !data.talk.nodes || !data.talk.nodes[nodeKey]) return;
var text = prompt('Option text:');
if (text === null) return;
var dest = prompt('Goto node key:') || '';
var node = data.talk.nodes[nodeKey];
if (!node.options) node.options = [];
node.options.push({ text: text, goto: dest });
renderTalkTree(data);
if (typeof window.onTalkTreeChange === 'function') window.onTalkTreeChange(data);
}
function deleteOption(e, nodeKey, idx) {
if (e) e.stopPropagation();
var data = window._talkData;
if (!data || !data.talk || !data.talk.nodes || !data.talk.nodes[nodeKey]) return;
var node = data.talk.nodes[nodeKey];
if (!node.options || idx < 0 || idx >= node.options.length) return;
if (!confirm('Delete this option?')) return;
node.options.splice(idx, 1);
renderTalkTree(data);
if (typeof window.onTalkTreeChange === 'function') window.onTalkTreeChange(data);
}