
const lefttest = document.getElementById("lefttest");
const resizer_right = document.getElementById("resizer_right");
const resizer_top = document.getElementById("resizer_top");

// const rightBottom = document.getElementById("rightBottom");
// const rb_resizer_top = document.getElementById("rb_resizer_top");
// const rb_resizer_left = document.getElementById("rb_resizer_left");

// 左下角面板显示/隐藏
// let codemk1 = "0px";
// let codemk2 = "40%";
// function ggb_code() {
//   if (lefttest.style.width === codemk1) {
//     lefttest.style.width = codemk2;
//     lefttest.style.height = codemk2;
//   } else {
//     lefttest.style.width = codemk1;
//     lefttest.style.height = codemk1;
//   }
// }

// // 右下角面板显示/隐藏
// function js_code() {
//   if (rightBottom.style.width === codemk1) {
//     rightBottom.style.width = codemk2;
//     rightBottom.style.height = codemk2;
//   } else {
//     rightBottom.style.width = codemk1;
//     rightBottom.style.height = codemk1;
//   }
// }

// function hide_all_code(){
//   lefttest.style.width = codemk1;
//   lefttest.style.height = codemk1;
//   rightBottom.style.width = codemk1;
//   rightBottom.style.height = codemk1;
// }



// 左下角面板显示/隐藏
let codemk1 = true;
let codemk2 = true;
function show_ggb_code() {
  lefttest.style.display = "";
  lefttest.style.width = "40%";
  lefttest.style.height = "50%";
  codemk1 = false;
}
function hide_ggb_code() {
  lefttest.style.display = "None";
  lefttest.style.width = "0px";
  lefttest.style.height = "0px";
  codemk1 = true;
}
function ggb_code() {
  if (codemk1) {
    show_ggb_code()
  } else {
    hide_ggb_code()
  }
}

// 右下角面板显示/隐藏
function show_js_code() {
  rightBottom.style.display = "";
  rightBottom.style.width = "40%";
  rightBottom.style.height = "50%";
  codemk2 = false;
}
function hide_js_code() {
  rightBottom.style.display = "None";
  rightBottom.style.width = "0px";
  rightBottom.style.height = "0px";
  codemk2 = true;
}

function js_code() {
  if (codemk2) {
    show_js_code()
  } else {
    hide_js_code()
  }
}
function hide_all_code(){
  hide_ggb_code();
  hide_js_code();
}

// show_ggb_code();

// show_js_code();
// hide_js_code();


// 左下角拖动宽度
resizer_right.addEventListener("mousedown", function () {
  document.body.style.cursor = "ew-resize";
  function onMouseMove(e) {
    let newWidth = e.clientX;
    newWidth = Math.max(50, Math.min(newWidth, window.innerWidth));
    lefttest.style.width = newWidth + "px";
  }
  function onMouseUp() {
    document.body.style.cursor = "";
    document.removeEventListener("mousemove", onMouseMove);
    document.removeEventListener("mouseup", onMouseUp);
  }
  document.addEventListener("mousemove", onMouseMove);
  document.addEventListener("mouseup", onMouseUp);
});

// 左下角拖动高度
resizer_top.addEventListener("mousedown", function () {
  document.body.style.cursor = "ns-resize";
  function onMouseMove(e) {
    let newHeight = window.innerHeight - e.clientY;
    newHeight = Math.max(50, Math.min(newHeight, window.innerHeight));
    lefttest.style.height = newHeight + "px";
  }
  function onMouseUp() {
    document.body.style.cursor = "";
    document.removeEventListener("mousemove", onMouseMove);
    document.removeEventListener("mouseup", onMouseUp);
  }
  document.addEventListener("mousemove", onMouseMove);
  document.addEventListener("mouseup", onMouseUp);
});

// // 右下角拖动高度（上方）
// rb_resizer_top.addEventListener("mousedown", function () {
//   document.body.style.cursor = "ns-resize";
//   function onMouseMove(e) {
//     let bottom = rightBottom.getBoundingClientRect().bottom;
//     let newHeight = bottom - e.clientY;
//     newHeight = Math.max(50, newHeight);
//     rightBottom.style.height = newHeight + "px";
//   }
//   function onMouseUp() {
//     document.body.style.cursor = "";
//     document.removeEventListener("mousemove", onMouseMove);
//     document.removeEventListener("mouseup", onMouseUp);
//   }
//   document.addEventListener("mousemove", onMouseMove);
//   document.addEventListener("mouseup", onMouseUp);
// });

// // 右下角拖动宽度（左边）
// rb_resizer_left.addEventListener("mousedown", function () {
//   document.body.style.cursor = "ew-resize";
//   function onMouseMove(e) {
//     let right = rightBottom.getBoundingClientRect().right;
//     let newWidth = right - e.clientX;
//     newWidth = Math.max(50, newWidth);
//     rightBottom.style.width = newWidth + "px";
//   }
//   function onMouseUp() {
//     document.body.style.cursor = "";
//     document.removeEventListener("mousemove", onMouseMove);
//     document.removeEventListener("mouseup", onMouseUp);
//   }
//   document.addEventListener("mousemove", onMouseMove);
//   document.addEventListener("mouseup", onMouseUp);
// });


////////////////////////////////////////////////////////
////////////////////////////////////////////////////////







let initialCode = ``;


(function() {
  "use strict";
  const openBrackets = "([{";
  const closeBrackets = ")]}";
  const bracketPairs = { '(': ')', '[': ']', '{': '}' };
  const colorCount = 8;

CodeMirror.defineMode("javascript-rb", function(config) {
    const jsMode = CodeMirror.getMode(config, "javascript");
    const mode = {
        startState: function() {
            return { bracketStack: [], jsState: CodeMirror.startState(jsMode) };
        },
        copyState: function(state) {
            return { bracketStack: state.bracketStack.slice(), jsState: CodeMirror.copyState(jsMode, state.jsState) };
        },
        token: function(stream, state) {
            const char = stream.peek();
            if ("([{".indexOf(char) > -1) {
                const level = state.bracketStack.length;
                state.bracketStack.push(char);
                stream.next();
                return `bracket-level-${level % 8}`;
            }
            if (")]}".indexOf(char) > -1) {
                stream.next();
                const stackSize = state.bracketStack.length;
                if (stackSize > 0 && { '(':')', '[':']', '{':'}' }[state.bracketStack[stackSize - 1]] === char) {
                    state.bracketStack.pop();
                    const level = state.bracketStack.length;
                    return `bracket-level-${level % 8}`;
                } else {
                    return "mismatch-bracket";
                }
            }
            return jsMode.token(stream, state.jsState);
        }
    };
if (jsMode.lineComment) mode.lineComment = jsMode.lineComment;
if (jsMode.blockCommentStart) mode.blockCommentStart = jsMode.blockCommentStart;
if (jsMode.blockCommentEnd) mode.blockCommentEnd = jsMode.blockCommentEnd;
return mode;
});


const editor = CodeMirror.fromTextArea(document.getElementById("ggbInput"), {
mode: "javascript-rb",
lineNumbers: true,
matchBrackets: true,
indentUnit: 2,
tabSize: 2,
extraKeys: {
  "Ctrl-Q": "toggleComment",        // 行注释
  "Cmd-Q": "toggleComment",         // Mac
    "Ctrl-D": function(cm) {
        const selections = cm.listSelections();
        cm.operation(function() {
            selections.forEach(sel => {
                let from = sel.from(), to = sel.to();
                if (from.line === to.line && from.ch === to.ch) {
                    const lineText = cm.getLine(from.line);
                    cm.replaceRange(lineText + "\n", { line: from.line + 1, ch: 0 });
                } else {
                    const text = cm.getRange(from, to);
                    cm.replaceRange(text, { line: to.line + 1, ch: 0 });
                }
            });
        });
    }
},
highlightSelectionMatches: {
    showToken: /\w/,
    annotateScrollbar: true
},
hintOptions: { completeSingle: false }, // 不自动选中第一个
});



const fontslider1 = document.getElementById("fontslider1");
editor.getWrapperElement().style.fontSize = fontslider1.value + "px";
editor.refresh(); 
let ffsize = fontslider1.value;
fontslider1.addEventListener("input", function() {
  editor.getWrapperElement().style.fontSize = this.value + "px";
  editor.refresh();
  ffsize = fontslider1.value;
});

// editor.setValue(initialCode);

////////////////////////////////////
function customHint(cm) {
  const cur = cm.getCursor();
  const token = cm.getTokenAt(cur);
  let word = token.string;
  let from = CodeMirror.Pos(cur.line, token.start);
  let to = CodeMirror.Pos(cur.line, token.end);

  if (token.type === "comment") {
    const match = word.match(/([\w\u4e00-\u9fa5]+)$/);
    if (match) {
      word = match[1];
      const startOffset = token.end - match[1].length;
      from = CodeMirror.Pos(cur.line, startOffset);
    } else {
      word = "";
    }
  } else {
    word = word.replace(/[^\w\u4e00-\u9fa5]/g, "");
  }
  word = word.toLowerCase();

  const matches = functionList.filter(f => f.kw.toLowerCase().includes(word));
  const listSource = matches.length ? matches : functionList;

  const list = listSource.map(f => ({
    text: f.text,
    displayText: f.kw,
    render: function (el) {
      el.style.display = "flex";
      el.style.justifyContent = "space-between";
      el.style.alignItems = "flex-start";
      el.style.fontSize = `${ffsize}px`;
      el.style.maxWidth = "900px";
      el.style.whiteSpace = "normal";
      el.style.wordBreak = "break-word";
      el.style.padding = "3px 6px";
      
      const left = document.createElement("div");
      left.textContent = f.kw;
      left.style.flex = "1";
      left.style.fontWeight = "bold";
      left.style.marginRight = "12px";
      left.style.color = "#222";
      left.style.minWidth = "280px";
      left.style.maxWidth = "400px";
      
      const right = document.createElement("div");
      let htmlDisplay = f.displayText?.split("<br>")[0]?.split("||||")[0] || "";
      right.innerHTML = htmlDisplay;
      right.style.flex = "1";
      right.style.color = "#333";
      right.style.textAlign = "left";
      right.style.overflow = "hidden";
      right.style.textOverflow = "ellipsis";
      right.style.maxHeight = "80px";
      right.style.opacity = 0.9;
      

      left.style.zIndex = 99999;
      right.style.zIndex = 99999;
      el.style.zIndex = 99999;
      el.appendChild(left);
      el.appendChild(right);
    }
  }));

  return { list, from, to };
}



editor.on("inputRead", function (cm, change) {
  if (change.text[0].match(/[\w\u4e00-\u9fa5]/)) {
      cm.showHint({ hint: customHint, completeSingle: false });
  }
  initialCode = editor.getValue();
});
initialCode = editor.getValue();

////////////////////////////////////





let tooltipEl = null;
let hideTimer = null;

function showTooltipAt(tokenPos, htmlContent) {
  removeTooltip(); 
  const coords = editor.charCoords(tokenPos, "page");

  tooltipEl = document.createElement("div");
  tooltipEl.style.position = "absolute";
  tooltipEl.style.left = coords.left + "px";
  tooltipEl.style.background = "rgba(240,240,240,1)";
  tooltipEl.style.color = "rgba(0,0,0,1)";
  tooltipEl.style.padding = "8px";
  tooltipEl.style.borderRadius = "6px";
  tooltipEl.style.fontSize = `${ffsize}px`;
  tooltipEl.style.maxWidth = "800px";
  tooltipEl.style.maxHeight = "600px";
  tooltipEl.style.zIndex = 9999;
  tooltipEl.style.whiteSpace = "normal";
  tooltipEl.style.overflowY = "auto";
  tooltipEl.style.overflowX = "hidden";
  tooltipEl.style.boxShadow = "0 2px 8px rgba(0,0,0,0.5)";
  tooltipEl.style.userSelect = "text";
  tooltipEl.innerHTML = htmlContent;

  tooltipEl.addEventListener("mouseenter", () => {
      if (hideTimer) {
          clearTimeout(hideTimer);
          hideTimer = null;
      }
  });
  tooltipEl.addEventListener("mouseleave", () => {
      hideTimer = setTimeout(removeTooltip, 100);
  });

  document.body.appendChild(tooltipEl);

  // 🔽 关键：在插入 DOM 后重新计算 top，让 tooltip 出现在上方
  const tooltipHeight = tooltipEl.offsetHeight;
  tooltipEl.style.top = (coords.top - tooltipHeight) + "px";  // 8px 为间距
}


// 移除 tooltip
function removeTooltip() {
if (tooltipEl) {
    tooltipEl.remove();
    tooltipEl = null;
}
if (hideTimer) {
    clearTimeout(hideTimer);
    hideTimer = null;
}
}

// 在 editor 中鼠标悬浮事件
editor.getWrapperElement().addEventListener("mouseover", (e) => {
const pos = editor.coordsChar({ left: e.clientX, top: e.clientY });
const token = editor.getTokenAt(pos);

if (!token.string) return;

const match = functionList.find(f => f.text === token.string);
if (match) {
    const htmlContent = `
    <div style="margin-top:4px;">
      ${match.kw}  &nbsp;&nbsp;
            <a href="https://translate.yandex.com/translate?lang=en-zh&url=https://geogebra.github.io/docs/manual/en/commands/${match.text}" target="_blank">中文翻译文档</a> &nbsp;&nbsp;
            <a href="https://geogebra.github.io/docs/manual/en/commands/${match.text}" target="_blank">英文官方文档</a>  
        </div>
        <div>${match.displayText}</div>
    `;
    showTooltipAt({ line: pos.line, ch: token.start }, htmlContent);
}
});

// 鼠标离开 editor token
editor.getWrapperElement().addEventListener("mouseout", (e) => {
if (!tooltipEl) return;

// 延迟隐藏 tooltip
hideTimer = setTimeout(removeTooltip, 100);
});







// 运行代码
document.getElementById("runBtn").addEventListener("click", function() {
if (!ggbApI) return;
let code =  editor.getValue();
// localStorage.setItem(STORAGE_KEY, code);

let cleaned = code.replace(/\s*\/\/.*$/gm, '').replace(/,+\s*$/gm, '').replace(/;+\s*$/gm, '').replace(/^\s*[\r\n]/gm, '').trim();
let lines = cleaned.split("\n");

// trackedObjects.clear();

lines.forEach(line => {
    ggbApI.evalCommand(line);
});


});





})();

//////////////////////////////////////////
//////////////////////////////////////////

// let initialCode2 = ``;
// (function() {
//   "use strict";

// const editor2 = CodeMirror.fromTextArea(document.getElementById("jsInput"), {
// mode: "javascript",
// lineNumbers: true,
// matchBrackets: true,
// indentUnit: 2,
// tabSize: 2,
// extraKeys: {
//   "Ctrl-Q": "toggleComment",        // 行注释
//   "Cmd-Q": "toggleComment",         // Mac
//     "Ctrl-D": function(cm) {
//         const selections = cm.listSelections();
//         cm.operation(function() {
//             selections.forEach(sel => {
//                 let from = sel.from(), to = sel.to();
//                 if (from.line === to.line && from.ch === to.ch) {
//                     const lineText = cm.getLine(from.line);
//                     cm.replaceRange(lineText + "\n", { line: from.line + 1, ch: 0 });
//                 } else {
//                     const text = cm.getRange(from, to);
//                     cm.replaceRange(text, { line: to.line + 1, ch: 0 });
//                 }
//             });
//         });
//     }
// },
// highlightSelectionMatches: {
//     showToken: /\w/,
//     annotateScrollbar: true
// },
// hintOptions: { completeSingle: false }, // 不自动选中第一个
// });


// const fontslider2 = document.getElementById("fontslider2");
// editor2.getWrapperElement().style.fontSize = fontslider2.value + "px";
// editor2.refresh(); 
// fontslider2.addEventListener("input", function() {
//   editor2.getWrapperElement().style.fontSize = this.value + "px";
//   editor2.refresh();
// });



// editor2.on("inputRead", function() {
// initialCode2 = editor2.getValue();
// });
// initialCode2 = editor2.getValue();
// })();

// function runJsCode(){
//   if(!ggbApI) return;
//   try {
//     const fn = new Function("api", initialCode2);
//     fn(ggbApI);
//   } catch(err){
//     alert("执行 JS 代码出错: " + err.message);
//   }
// }


