// var lang = 'en';
var lang = 'zh';
var onlinepath = 'https://220311.xyz/ggb/';
var offlinepath = './';
var c = 0;
let sc = 1;
var strs = ggbs;
var n = strs.length;
let parameters = {
    "id": "ggbApplet",
    "width":mywidth/sc,
    "height":myheight/sc,
    "scale":sc,
    // "appletOnLoad":function(ggbApplet){ 
    //      // ggbApplet.registerAddListener("setStyle");
    //      ggbApplet.registerClickListener("setStyle");
    // },
    "enableShiftDragZoom":true,
    "showMenuBar":true, 
    "showAlgebraInput":true,
    "showToolBar":true,
    "ggbBase64": strs[c],
    "language":lang,
    "borderColor":"rgb(250, 250, 250)",
};

let slider = document.getElementById('slider');
let sliderValue = document.getElementById('slider-value');
slider.addEventListener('input', function() {
    sliderValue.textContent = this.value;
});
slider.addEventListener('change', updateResult);
function updateResult() {
    const value = parseInt(slider.value);
    sc = value * 0.01;
    ggbApplet.setSize(window.innerWidth/sc, (window.innerHeight - 30)/sc);
    fresh();
}
function checkInput(txt) {
  return /[\u4e00-\u9fa5]/.test(txt);
}
let urlParams = new URLSearchParams(window.location.search);
function hasSearchParams() {
    return urlParams.toString() == "";
}

var ggbpure2  = " ";
var ggbpure = " ";

if(strs.length==0){
    strs[0] = ggbpure;
    n = strs.length;
};


function setStyle(a){
    let objectType = ggbApplet.getObjectType(a);
    if (['ray', 'line', 'function', 'hyperbola', 'parabola', 'inequality'].includes(objectType)) {
        ggbApplet.setLayer(a, 3);
    }
}


// let applet = new GGBApplet(parameters,  '5.0');  

let isFullScreen = 1;
function toggleFullscreen(elem) {
    elem = elem || document.documentElement;
    if (!document.fullscreenElement && !document.mozFullScreenElement &&
      !document.webkitFullscreenElement && !document.msFullscreenElement) {
      if (elem.requestFullscreen) {
        elem.requestFullscreen();
      } else if (elem.msRequestFullscreen) {
        elem.msRequestFullscreen();
      } else if (elem.mozRequestFullScreen) {
        elem.mozRequestFullScreen();
      } else if (elem.webkitRequestFullscreen) {
        elem.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
      }
      
        document.getElementById("bt").style.display="";
        ggbApplet.showMenuBar(true);
        ggbApplet.showToolBar(true);
        // document.getElementById('btnFullscreen').style.opacity = opacity/2;
        isFullScreen = 1;
        
      
    } else {
      if (isFullScreen === 1){
        document.getElementById("bt").style.display="none";
        ggbApplet.showMenuBar(false);
        ggbApplet.showToolBar(false);
        // document.getElementById('btnFullscreen').style.opacity = opacity/4;
        ggbApplet.setSize(window.innerWidth/sc, (window.innerHeight - 30)/sc);
        isFullScreen = 0;
      }
      else{ 
        document.getElementById("bt").style.display="";
        ggbApplet.showMenuBar(true);
        ggbApplet.showToolBar(true);
        // document.getElementById('btnFullscreen').style.opacity = opacity;
        isFullScreen = 1;
          if (document.exitFullscreen) {
            document.exitFullscreen();
          } else if (document.msExitFullscreen) {
            document.msExitFullscreen();
          } else if (document.mozCancelFullScreen) {
            document.mozCancelFullScreen();
          } else if (document.webkitExitFullscreen) {
            document.webkitExitFullscreen();
          };

      }
    }
    
    
  }
  




function disableEnterKey(event) {
    var keyCode = event.keyCode || event.which;
    if (keyCode == 13) {
        event.preventDefault(); 
        SetPage();
        return false; 
    }
}


function evalInput(strInput) {
  if(checkInput(strInput)){
      ggbApplet.setLanguage("zh");
  }
  ggbApplet.evalCommand(strInput);
  return false;
}





document.getElementById('previewLink').addEventListener('click', function (e) {
  e.preventDefault();
  let tmmp = window.location.href.split('#')[0];
  window.open(`${tmmp}?page=${c + 1}&zoom=${(slider.value * 0.01).toFixed(2)}`, '_blank');
  saveChanges();
});



document.querySelectorAll('a.cooldown-link').forEach(link => {
  link.addEventListener('click', function (e) {
      if (link.classList.contains('cooling-down')) {
          e.preventDefault();
          return;
      }
      link.classList.add('cooling-down');
      setTimeout(() => {
          link.classList.remove('cooling-down');
      }, 5000);
  });
});



let tmp_panel_mark = false;
function hide_show_right_panel() {
  const leftPanelx = document.getElementById('leftPanel');
  if (tmp_panel_mark) {
    leftPanelx.style.width = '100%';
    tmp_panel_mark = !tmp_panel_mark;
  } else {
    leftPanelx.style.width = '60%';
    tmp_panel_mark = !tmp_panel_mark;
  }
}

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

 
document.getElementById("rangeValue").style.display = "none";
var mylist_ = new Array();
mylist_ = ggbs; 

let mycopy_ = '';
const container = document.getElementById('listContainer');
const slider_ = document.getElementById('highlighter');
const rangeValue = document.getElementById('rangeValue');
const tolpages2 = document.getElementById('tolpages2');

// 渲染字符框列表
function renderList() {
  container.innerHTML = '';
  mylist_.forEach((str, idx) => {
    const item = document.createElement('div');
    item.className = 'item';
    // 如果当前项编号等于滑条值，则高亮
    if (parseInt(slider_.value, 10) === idx + 1) {
      item.classList.add('highlight');
    }
    item.draggable = true;
    item.dataset.index = idx;

    // 点击非按钮区域手动选中，更新滑条值
    item.addEventListener('click', (e) => {
      // 如果点击目标是按钮或其子元素，则不触发item的点击
      if (e.target.tagName.toLowerCase() === 'button' || e.target.classList.contains('edit-input')) {
        return;
      }
      slider_.value = idx + 1;
      rangeValue.textContent = slider_.value;
      saveGgbBase();
      mylist_[c] = ggbApplet.getBase64();
      document.getElementById("Cpages").value = idx+1;
      c = idx;
      ggbApplet.setBase64(mylist_[c]);
      renderList();
    });

    // 左侧编号区域
    const number = document.createElement('div');
    number.className = 'number';
    number.textContent = idx + 1;
    item.appendChild(number);

    // 中间区域：标签与按钮
    const content = document.createElement('div');
    content.className = 'content';

    // 标签：点击后可编辑，编辑完成后恢复显示
    const label = document.createElement('span');
    label.className = 'label';
    label.textContent = labels_[idx];
    label.addEventListener('click', (e) => {
      // 防止触发item的点击事件
      e.stopPropagation();
      const input = document.createElement('input');
      input.type = 'text';
      input.value = labels_[idx];
      input.className = 'edit-input';
      input.addEventListener('blur', () => {
        labels_[idx] = input.value || labels_[idx];
        renderList();
      });
      input.addEventListener('keydown', e => {
        if (e.key === 'Enter') {
          input.blur();
        }
      });
      label.replaceWith(input);
      input.focus();
    });

    // 按钮区域：删除、添加、克隆、复制
    const buttons = document.createElement('div');
    buttons.className = 'buttons';

    // 删除按钮：删除当前项
    // const delBtn = document.createElement('button');
    // delBtn.textContent = '-';
    // delBtn.title = '删除当前页面';
    // delBtn.addEventListener('click', (e) => {
    //   e.stopPropagation();
    //   labels_.splice(idx, 1);
    //   DeletePage2();
    //   updateSlider();
    //   renderList();
    // });

    // 添加按钮：在当前项后插入一个新项（字符内容为 'newstr'，标签为原标签加上 'x'）
    const addBtn = document.createElement('button');
    addBtn.textContent = '+';
    addBtn.title = '下方新加页面';
    addBtn.addEventListener('click', (e) => {
      e.stopPropagation();
      const randomNum = Math.floor(Math.random() * 90) + 10;
      const newLabel = 'new' + randomNum;
      saveGgbBase();
      mylist_[c] = ggbApplet.getBase64();
      mylist_.splice(idx + 1, 0, ggbpure);
      labels_.splice(idx + 1, 0, newLabel);
      document.getElementById("Cpages").value = idx+2;
      document.getElementById("tolpages").value = n + 1;
      c = idx + 1;
      n = n + 1;
     
      ggbApplet.setBase64(ggbpure);
      rangeValue.textContent =  idx+2;
      slider_.value = c+1;
      updateSlider();
      renderList();
      if(n === c+1){
        Last();
      }
    });

    // 克隆按钮：在当前项后插入一个克隆项（复制字符内容，标签为原标签加上 'c'）
    const cloneBtn = document.createElement('button');
    cloneBtn.textContent = '⚣';
    cloneBtn.title = '克隆页面';
    cloneBtn.addEventListener('click', (e) => {
      e.stopPropagation();
      const randomNum = Math.floor(Math.random() * 90) + 10;
      const newLabel = labels_[c] + randomNum;
      saveGgbBase();
      mylist_[c] = ggbApplet.getBase64();
      if(c===idx){
        str = ggbApplet.getBase64();
      }
      mylist_.splice(idx + 1, 0, str);
      labels_.splice(idx + 1, 0, newLabel);
      document.getElementById("Cpages").value = idx+2;
      document.getElementById("tolpages").value = n + 1;
      c = idx + 1;
      n = n + 1;
     
      ggbApplet.setBase64(str);
      rangeValue.textContent =  idx+2;
      slider_.value = c+1;
      updateSlider();
      renderList();
      if(n === c+1){
        Last();
        saveGgbBase();
        ggbApplet.setBase64(str);
        mylist_[c] = ggbApplet.getBase64();
      }
    });

    buttons.append(addBtn, cloneBtn);
    content.append(label, buttons);
    item.appendChild(content);
    container.appendChild(item);

    // 拖拽交换位置：设置拖拽事件
    item.addEventListener('dragstart', (e) => {
      e.dataTransfer.setData('text/plain', idx);
      item.classList.add('dragging');
    });
    item.addEventListener('dragend', (e) => {
      item.classList.remove('dragging');
    });
    item.addEventListener('dragover', (e) => {
      e.preventDefault();
      item.style.border = '2px dashed #007bff';
    });
    item.addEventListener('dragleave', () => {
      item.style.border = '1px solid #ccc';
    });
    item.addEventListener('drop', (e) => {
      const fromIdx = Number(e.dataTransfer.getData('text/plain'));
      const toIdx = idx;
      if (fromIdx === toIdx) return;
      // 交换 mylist_ 与 labels_ 中对应元素的位置

      saveGgbBase();
      mylist_[c] = ggbApplet.getBase64();

      [mylist_[fromIdx], mylist_[toIdx]] = [mylist_[toIdx], mylist_[fromIdx]];
      [labels_[fromIdx], labels_[toIdx]] = [labels_[toIdx], labels_[fromIdx]];
      
      document.getElementById("Cpages").value = idx+1;
      c = idx;
      ggbApplet.setBase64(mylist_[c]);
      slider_.value = toIdx+1;
      rangeValue.textContent = toIdx+1;
      updateSlider();
      renderList();
    });
  });
}

// 更新滑条范围（max 值）并确保当前值不超过范围
function updateSlider() {
  slider_.max = mylist_.length;
  if (parseInt(slider_.value, 10) > mylist_.length) {
    slider_.value = mylist_.length;
    rangeValue.textContent = slider_.value;
  }
}


// 滑条变化时更新显示的数字和重新渲染列表（以便高亮效果生效）
slider_.addEventListener('input', () => {
  rangeValue.textContent = slider_.value;
  document.getElementById("Cpages").value = slider_.value;
  saveGgbBase();
  mylist_[c] = ggbApplet.getBase64();
  c = slider_.value-1;
  ggbApplet.setBase64(mylist_[c]);
  renderList();
});


updateSlider();
renderList();


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

const divider = document.getElementById('divider');
const container_right = document.querySelector('.container_right');
const leftPanel = document.getElementById('leftPanel');
const minWidth = 0;
const maxWidth = window.innerWidth;

let startX = 0;
let startWidth = 0;

// 鼠标按下事件
divider.addEventListener('mousedown', function(e) {
  startX = e.clientX;
  startWidth = leftPanel.offsetWidth;
  
  // 添加临时样式
  document.body.style.cursor = 'ew-resize';
  document.body.style.userSelect = 'none';
  
  // 监听鼠标移动和松开事件
  document.addEventListener('mousemove', onMouseMove);
  document.addEventListener('mouseup', onMouseUp);
});

// 鼠标移动处理
function onMouseMove(e) {
  const deltaX = e.clientX - startX;
  let newWidth = startWidth + deltaX;
  
  // 边界约束
  newWidth = Math.max(minWidth, Math.min(newWidth, maxWidth));
  
  // 更新宽度
  leftPanel.style.width = `${newWidth}px`;
}

// 鼠标松开处理
function onMouseUp() {
  // 移除事件监听
  document.removeEventListener('mousemove', onMouseMove);
  document.removeEventListener('mouseup', onMouseUp);
  
  // 恢复样式
  document.body.style.cursor = '';
  document.body.style.userSelect = '';
}



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


// 获取原始 id 的内容
const content = document.getElementById("tolpages").textContent;
document.querySelectorAll(".copy-tolpages").forEach(el => {
  el.textContent = content;
});

let uploadedFiles = [];
let uploaded_htmlFiles = [];

document.getElementById('file-input').addEventListener('change', (event) => {
  addFiles(event.target.files);
});

function handleDrop(event) {
  event.preventDefault();
  addFiles(event.dataTransfer.files);
}

function addFiles(fileList) {
  for (const file of fileList) {
    if (file.name.endsWith('.ggb')) {
      uploadedFiles.push(file);
    }
  }
  for (const file of fileList) {
    if (file.name.endsWith('.html')) {
      uploaded_htmlFiles.push(file);
    }
  }
  // alert(`${uploadedFiles.length}个 .ggb 准备就绪.  ${uploaded_htmlFiles.length}个 .html 准备就绪.`);
  showSuccess('文件准备就绪');
  processFiles();
}

async function processFiles() {
  if (uploadedFiles.length === 0 && uploaded_htmlFiles.length === 0) {
    alert("请上传.ggb或.html文件(只是上传到本地, 不会上传到云端)\n \n三种方法:\n1. 先ctrl+c复制ggb或html文件, 然后ctrl+v粘贴; \n2. 直接拖拽ggb或html文件到虚线窗口; \n3. 点击虚线窗口上传文件");
    return;
  }

  const file_name_list = uploadedFiles.map(file => file.name.substring(0, file.name.lastIndexOf('.')));
  const hfile_name_list = uploaded_htmlFiles.map(file => file.name.substring(0, file.name.lastIndexOf('.')));
  const base64_list = [];

  for (const file of uploadedFiles) {
    const base64 = await fileToBase64(file);
    base64_list.push(base64);
  }
  let ttk = 0;
  for (const file of uploaded_htmlFiles) {
    let base64 = await hfileToBase64(file);
    let rrk = 0;
    base64.forEach(bs => { 
      base64_list.push(bs);
      let tmpname = hfile_name_list[ttk]+ "_" + "p" + rrk;
      file_name_list.push(tmpname);
      rrk += 1;
    });
    ttk +=1;
  }

  let mk = false;
  if(n === c+1){
     mk = true;
  }
  let nnew = base64_list.length;
  saveGgbBase();
  mylist_[c] = ggbApplet.getBase64();
  labels_.splice(c + 1, 0, ...file_name_list);
  mylist_.splice(c + 1, 0, ...base64_list);

  // for (let i = 0; i < nnew; i++) {
  //   labels_.splice(c + 1 + i, 0, file_name_list[nnew-i-1]);
  //   mylist_.splice(c + 1 + i, 0, base64_list[nnew-i-1]);
  // }
  n = n + nnew;
  document.getElementById("tolpages").value = n;
  // DeletePage();
  updateSlider();
  renderList();
  // NextPage();
  // if(mk){
  //   // SetPage2(c);
  //   NextPage();
  // }
  // updateSlider();
  // renderList();
  uploadedFiles.length = 0;
  uploaded_htmlFiles.length = 0;

}

function fileToBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => {
      const result = reader.result;
      const base64 = result.split(',')[1];
      resolve(base64);
    };
    reader.onerror = (err) => reject(err);
    reader.readAsDataURL(file);
  });
}

function hfileToBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => {
      const result = reader.result;
      resolve(extractGgbsFromHtml(result));
    };
    reader.onerror = (err) => reject(err);
    reader.readAsText(file);
  });
}
function extractGgbsFromHtml(htmlContent) {
        let  ggbsArray = [];
        const parser = new DOMParser();
        const doc = parser.parseFromString(htmlContent, 'text/html');
        const scriptTags = doc.querySelectorAll('script');
        scriptTags.forEach(script => {
            const scriptContent = script.textContent;
            const ggbsMatches = scriptContent.match(/ggbs\[\d+\]\s*=\s*["'](.+?)["'];/g);
            if (ggbsMatches) {
                ggbsMatches.forEach(match => {
                    const valueMatch = match.match(/ggbs\[\d+\]\s*=\s*["'](.+?)["'];/);
                    if (valueMatch && valueMatch[1]) {
                        ggbsArray.push(valueMatch[1]);
                    }
                });
            }
        });
        return ggbsArray;
    }


// 粘贴支持（Ctrl+V 粘贴文件）
window.addEventListener('paste', (event) => {
  const items = event.clipboardData.items;
  const files = [];

  for (let i = 0; i < items.length; i++) {
    const item = items[i];
    if (item.kind === 'file') {
      const file = item.getAsFile();
      if (file && (file.name.endsWith('.ggb')  || file.name.endsWith('.html'))) {
        files.push(file);
      }
    }
  }

  if (files.length > 0) {
    addFiles(files);
    // processFiles();
    // saveGgbBase();
    // ggbApplet.setBase64(tmmp2);
    
  }

});


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


window.addEventListener("resize", function () {
  if (hasSearchParams()) {
      ggbApplet.setSize(window.innerWidth / sc, (window.innerHeight - 30) / sc);
  } else {
      let tmp = slider.value * 0.01;
      // let zoomx = parseFloat(urlParams.get('zoom')) || tmp;
      // let h = parseFloat(urlParams.get('h')) || 800;
      // let w = parseFloat(urlParams.get('w')) || 600;
      // ggbApplet2.setSize(window.innerWidth / zoomx, (window.innerHeight) / zoomx);
      // ggbApplet2.setSize((h/zoomx), (w/zoomx));
      // ggbApplet2.evalCommand('SetPerspective("-A")');
      // ggbApplet2.evalCommand('SetPerspective("-P")');
  }
});

window.addEventListener("beforeunload", function (e) { if (hasSearchParams()) { var confirmationMessage = "Not save"; e.returnValue = confirmationMessage; return confirmationMessage; } });

function saveChanges() {
  saveGgbBase();
  strs[c] = ggbApplet.getBase64();
  localStorage.setItem('currentPage', c);
  localStorage.setItem('strs', JSON.stringify(strs));
}




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


function myonload() {
  let applet2 = new GGBApplet(parameters, '5.0');
  if (ttttk) {
      applet2.setHTML5Codebase(offline_libpath + web3d_path);
  } else {
      applet2.setHTML5Codebase(online_libpath + web3d_path);
  }

  if (localStorage.getItem('sv')) {
      slider.value = parseInt(localStorage.getItem('sv'));
      sliderValue.textContent = slider.value;
      sc = slider.value * 0.01;
      parameters["width"] = window.innerWidth / sc;
      parameters["height"] = (window.innerHeight - 30) / sc;
  }
  if (hasSearchParams()) {
      document.getElementById("bt").style.display = "";
      document.getElementById("playpt").style.display = "";
      document.getElementById("ggbApplet").style.display = "";
      document.getElementById("ggbApplet2").style.display = "none";
      document.getElementById("divider").style.display = "";
      document.getElementById("rightPanel").style.display = "";
      applet2.inject("ggbApplet");
  } else {
      document.getElementById("bt").style.display = "none";
      document.getElementById("playpt").style.display = "none";
      document.getElementById("ggbApplet").style.display = "none";
      document.getElementById("ggbApplet2").style.display = "";
      document.getElementById("divider").style.display = "none";
      document.getElementById("rightPanel").style.display = "none";
      let zoomx = parseFloat(urlParams.get('zoom')) || sc;
      let page = parseFloat(urlParams.get('page')) || 1;
      let h = parseFloat(urlParams.get('h')) || 600;
      let w = parseFloat(urlParams.get('w')) || 400;
      // let strsx = JSON.parse(localStorage.getItem('strs'));
      var parameters2 = {
          "id": "ggbApplet2", "scale": 1,  "showAlgebraInput": false, "showToolBar": false, "borderColor": "white", "language": "en", "enableRightClick": true, "enableShiftDragZoom": true, "enableLabelDrags": true,
          "ggbBase64": ggbs[page-1],
          // "ggbBase64": strsx[page - 1],
      }
      let applet3 = new GGBApplet(parameters2, '5.0');
      if (ttttk) {
          applet3.setHTML5Codebase(offline_libpath + web3d_path);
      } else {
          applet3.setHTML5Codebase(online_libpath + web3d_path);
      }
      parameters2["width"] = (h/zoomx);
      parameters2["height"] = (w/zoomx);
      // parameters2["width"] = (h);
      // parameters2["height"] = (w);
      // parameters2["width"] = window.innerWidth / zoom;
      // parameters2["height"] = (window.innerHeight) / zoom;
      parameters2["appletOnLoad"] = function (api) {
          api.evalCommand('SetPerspective("-A")');
          api.evalCommand('SetPerspective("-P")');
      },
      applet3.inject("ggbApplet2");
  }
};

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

    // MD5 实现（压缩版）
    !function(n){"use strict";function d(n,t){var r=(65535&n)+(65535&t);return(n>>16)+(t>>16)+(r>>16)<<16|65535&r}function f(n,t,r,e,o,u){return d((u=d(d(t,n),d(e,u)))<<o|u>>>32-o,r)}function l(n,t,r,e,o,u,c){return f(t&r|~t&e,n,t,o,u,c)}function g(n,t,r,e,o,u,c){return f(t&e|r&~e,n,t,o,u,c)}function v(n,t,r,e,o,u,c){return f(t^r^e,n,t,o,u,c)}function m(n,t,r,e,o,u,c){return f(r^(t|~e),n,t,o,u,c)}function c(n,t){var r,e,o,u;n[t>>5]|=128<<t%32,n[14+(t+64>>>9<<4)]=t;for(var c=1732584193,f=-271733879,i=-1732584194,a=271733878,h=0;h<n.length;h+=16)c=l(r=c,e=f,o=i,u=a,n[h],7,-680876936),a=l(a,c,f,i,n[h+1],12,-389564586),i=l(i,a,c,f,n[h+2],17,606105819),f=l(f,i,a,c,n[h+3],22,-1044525330),c=l(c,f,i,a,n[h+4],7,-176418897),a=l(a,c,f,i,n[h+5],12,1200080426),i=l(i,a,c,f,n[h+6],17,-1473231341),f=l(f,i,a,c,n[h+7],22,-45705983),c=l(c,f,i,a,n[h+8],7,1770035416),a=l(a,c,f,i,n[h+9],12,-1958414417),i=l(i,a,c,f,n[h+10],17,-42063),f=l(f,i,a,c,n[h+11],22,-1990404162),c=l(c,f,i,a,n[h+12],7,1804603682),a=l(a,c,f,i,n[h+13],12,-40341101),i=l(i,a,c,f,n[h+14],17,-1502002290),f=l(f,i,a,c,n[h+15],22,1236535329),c=g(c,f,i,a,n[h+1],5,-165796510),a=g(a,c,f,i,n[h+6],9,-1069501632),i=g(i,a,c,f,n[h+11],14,643717713),f=g(f,i,a,c,n[h],20,-373897302),c=g(c,f,i,a,n[h+5],5,-701558691),a=g(a,c,f,i,n[h+10],9,38016083),i=g(i,a,c,f,n[h+15],14,-660478335),f=g(f,i,a,c,n[h+4],20,-405537848),c=g(c,f,i,a,n[h+9],5,568446438),a=g(a,c,f,i,n[h+14],9,-1019803690),i=g(i,a,c,f,n[h+3],14,-187363961),f=g(f,i,a,c,n[h+8],20,1163531501),c=g(c,f,i,a,n[h+13],5,-1444681467),a=g(a,c,f,i,n[h+2],9,-51403784),i=g(i,a,c,f,n[h+7],14,1735328473),f=g(f,i,a,c,n[h+12],20,-1926607734),c=v(c,f,i,a,n[h+5],4,-378558),a=v(a,c,f,i,n[h+8],11,-2022574463),i=v(i,a,c,f,n[h+11],16,1839030562),f=v(f,i,a,c,n[h+14],23,-35309556),c=v(c,f,i,a,n[h+1],4,-1530992060),a=v(a,c,f,i,n[h+4],11,1272893353),i=v(i,a,c,f,n[h+7],16,-155497632),f=v(f,i,a,c,n[h+10],23,-1094730640),c=v(c,f,i,a,n[h+13],4,681279174),a=v(a,c,f,i,n[h],11,-358537222),i=v(i,a,c,f,n[h+3],16,-722521979),f=v(f,i,a,c,n[h+6],23,76029189),c=v(c,f,i,a,n[h+9],4,-640364487),a=v(a,c,f,i,n[h+12],11,-421815835),i=v(i,a,c,f,n[h+15],16,530742520),f=v(f,i,a,c,n[h+2],23,-995338651),c=m(c,f,i,a,n[h],6,-198630844),a=m(a,c,f,i,n[h+7],10,1126891415),i=m(i,a,c,f,n[h+14],15,-1416354905),f=m(f,i,a,c,n[h+5],21,-57434055),c=m(c,f,i,a,n[h+12],6,1700485571),a=m(a,c,f,i,n[h+3],10,-1894986606),i=m(i,a,c,f,n[h+10],15,-1051523),f=m(f,i,a,c,n[h+1],21,-2054922799),c=m(c,f,i,a,n[h+8],6,1873313359),a=m(a,c,f,i,n[h+15],10,-30611744),i=m(i,a,c,f,n[h+6],15,-1560198380),f=m(f,i,a,c,n[h+13],21,1309151649),c=m(c,f,i,a,n[h+4],6,-145523070),a=m(a,c,f,i,n[h+11],10,-1120210379),i=m(i,a,c,f,n[h+2],15,718787259),f=m(f,i,a,c,n[h+9],21,-343485551),c=d(c,r),f=d(f,e),i=d(i,o),a=d(a,u);return[c,f,i,a]}function t(n){for(var t="",r=32*n.length,e=0;e<r;e+=8)t+=String.fromCharCode(n[e>>5]>>>e%32&255);return t}function r(n){var t=[];for(t[(n.length>>2)-1]=void 0,e=0;e<t.length;e+=1)t[e]=0;for(var r=8*n.length,e=0;e<r;e+=8)t[e>>5]|=(255&n.charCodeAt(e/8))<<e%32;return t}function e(n){for(var t,r="0123456789abcdef",e="",o=0;o<n.length;o+=1)t=n.charCodeAt(o),e+=r.charAt(t>>>4&15)+r.charAt(15&t);return e}function o(n){return unescape(encodeURIComponent(n))}function u(n){return function(n){return t(c(r(n),8*n.length))}(o(n))}function i(n){return e(u(n))}window.md5=i;
    }(this);

//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
const mytoggle = document.getElementById('toggle');
const canvas2 = document.getElementById('canvas2');
const canvas    = document.getElementById('canvas');
canvas.style.display = 'none';
const ctx       = canvas.getContext('2d');
const penBtn    = document.getElementById('penBtn');
const eraserBtn = document.getElementById('eraserBtn');
const penPanel  = document.getElementById('penPanel');
const ersPanel  = document.getElementById('eraserPanel');
const penSize   = document.getElementById('penSize');
const ersSize   = document.getElementById('eraserSize');
const boxErase  = document.getElementById('boxErase');
const colors    = document.querySelectorAll('.color-option');
let dpr         = window.devicePixelRatio || 1;
let usingPen    = false;
let usingEraser = false;
let painting    = false;
let lastPoint   = null, lastMid = null;

let penColor    = 'red';
let penW        = +penSize.value;
let ersW        = +ersSize.value;

let selectionRect = null;
let selStartX, selStartY;
function resize() {
  const w = window.innerWidth, h = window.innerHeight;
  canvas.style.width  = w + 'px';
  canvas.style.height = h + 'px';
  canvas.width  = w * dpr;
  canvas.height = h * dpr;
  ctx.setTransform(dpr,0,0,dpr,0,0);
  ctx.lineCap  = 'round';
  ctx.lineJoin = 'round';
  ctx.imageSmoothingEnabled = true;
}
window.addEventListener('resize', resize);
resize();

function getPos(e) {
  const r = canvas.getBoundingClientRect();
  const touch = e.touches ? e.touches[0] : e; // For touch events, get the first touch point
  return { x: touch.clientX - r.left, y: touch.clientY - r.top };
}

function startDrawing(e) {
  e.preventDefault(); // Prevents default behavior for touch devices
  if (usingEraser && boxErase.checked) {
    // 框选开始
    const touch = e.touches ? e.touches[0] : e;
    selStartX = touch.clientX;
    selStartY = touch.clientY;
    selectionRect = document.createElement('div');
    selectionRect.className = 'selection-rectangle';
    selectionRect.style.left = selStartX + 'px';
    selectionRect.style.top  = selStartY + 'px';
    selectionRect.style.width = '0px';
    selectionRect.style.height= '0px';
    document.body.appendChild(selectionRect);
    return;
  }
  painting = true;
  const p = getPos(e);
  lastPoint = p;
  lastMid   = p;
}


function draw(e) {
  e.preventDefault(); // Prevents default behavior for touch devices
  if (selectionRect) {
    // 更新框选区域
    const touch = e.touches ? e.touches[0] : e;
    const curX = touch.clientX, curY = touch.clientY;
    const x = Math.min(curX, selStartX);
    const y = Math.min(curY, selStartY);
    const w = Math.abs(curX - selStartX);
    const h = Math.abs(curY - selStartY);
    selectionRect.style.left   = x + 'px';
    selectionRect.style.top    = y + 'px';
    selectionRect.style.width  = w + 'px';
    selectionRect.style.height = h + 'px';
    return;
  }
  if (!painting) return;
  const p = getPos(e);
  const mid = { x:(lastPoint.x + p.x)/2, y:(lastPoint.y + p.y)/2 };

  ctx.beginPath();
  if (usingEraser) {
    ctx.globalCompositeOperation = 'destination-out';
    ctx.strokeStyle = 'rgba(0,0,0,1)';
    ctx.lineWidth   = ersW;
  } else {
    ctx.globalCompositeOperation = 'source-over';
    ctx.strokeStyle = penColor;
    ctx.lineWidth   = penW;
  }

  ctx.moveTo(lastMid.x, lastMid.y);
  ctx.quadraticCurveTo(lastPoint.x, lastPoint.y, mid.x, mid.y);
  ctx.stroke();

  lastPoint = p;
  lastMid   = mid;
}

function stopDrawing(e) {
  e.preventDefault(); // Prevents default behavior for touch devices
  if (selectionRect) {
    // 执行框选擦除
    const canvasRect = canvas.getBoundingClientRect();
    const selRect    = selectionRect.getBoundingClientRect();
    const x = selRect.left   - canvasRect.left;
    const y = selRect.top    - canvasRect.top;
    const w = selRect.width;
    const h = selRect.height;
    ctx.clearRect(x, y, w, h);
    selectionRect.remove();
    selectionRect = null;
    return;
  }
  painting = false;
  lastPoint = lastMid = null;
  ctx.globalCompositeOperation = 'source-over';
}

// 事件绑定
canvas.addEventListener('touchstart', startDrawing);
canvas.addEventListener('touchmove', draw);
canvas.addEventListener('touchend',   stopDrawing);
canvas.addEventListener('touchcancel', stopDrawing);

// 鼠标支持
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup',   stopDrawing);
canvas.addEventListener('mouseout',  stopDrawing);





function hidePanels() {
  penPanel.style.display = 'none';
  ersPanel.style.display = 'none';
  canvas2.style.display = 'none';
  document.getElementById('toggle').checked = false;
  penPanel.setAttribute('aria-hidden', 'true');
  ersPanel.setAttribute('aria-hidden', 'true');
}


function togglePanel(panel, btn) {  
if (panel.style.display === 'block') {  
  panel.style.display = 'none';  
} else {  
  panel.style.display = 'block';  
  // 计算并设置 panel 的 left/top  
}  
}

function CleanAll() {
  const link = document.createElement('a');
  const getTimestampStr = (sec = false) => (sec ? Math.floor(Date.now() / 1000) : Date.now()).toString();
  link.download = getTimestampStr(true)+'.png'; // 下载文件名
  link.href = canvas.toDataURL('image/png'); // 导出为透明PNG
  link.click();
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  usingPen = false;
  hidePanels();
  canvas.style.display = 'none';
  canvas.style.cursor = 'default';
  

}

function positionPanel(panel, btn) {
  const rect = btn.getBoundingClientRect();
  const pr = panel.getBoundingClientRect();
  let left = rect.right - pr.width;
  if (left < 5) left = 5;
  let bottom = window.innerHeight - rect.top + 8;
  panel.style.left = left + 'px';
  panel.style.bottom = bottom + 'px';
}

penBtn.addEventListener('click', () => {
  usingPen = !usingPen;
  usingEraser = false;
  hidePanels();
  // togglePanel(penPanel, penBtn);
  // canvas.style.display = 'none';
  if (usingPen) {
    penPanel.style.display = 'block';
    canvas.style.display = 'block';
    penPanel.setAttribute('aria-hidden', 'false');
    positionPanel(penPanel, penBtn);
    canvas.style.cursor = 'url("data:image/svg+xml,<svg xmlns=\'http://www.w3.org/2000/svg\' height=\'50\' width=\'50\'><text y=\'30\' font-size=\'30\'>🖊</text></svg>") 0 30, auto';
    canvas.style.pointerEvents = 'auto';
    
  } else {
    canvas.style.cursor = 'default';
    canvas.style.pointerEvents = 'none';
  }
});
eraserBtn.addEventListener('click', () => {
  usingEraser = !usingEraser; usingPen = false;
  hidePanels();
  // togglePanel(ersPanel, eraserBtn);
  canvas.style.pointerEvents = 'auto';
  if (usingEraser) {
    ersPanel.style.display = 'block';
    ersPanel.setAttribute('aria-hidden', 'false');
    positionPanel(ersPanel, eraserBtn);
    canvas.style.cursor = `url("data:image/svg+xml,<svg xmlns=\'http://www.w3.org/2000/svg\' height=\'50\' width=\'50\'><text y=\'30\' font-size=\'30\'>🧽</text></svg>") 30 30, auto`;
  } else {
    // canvas.style.cursor = 'default';
    canvas.style.cursor = 'url("data:image/svg+xml,<svg xmlns=\'http://www.w3.org/2000/svg\' height=\'50\' width=\'50\'><text y=\'30\' font-size=\'30\'>🖊</text></svg>") 0 30, auto';
  }
});


  // 默认首色
  colors[1].classList.add('active');
// 颜色 & 粗细
colors.forEach(c => {
  c.addEventListener('click', () => {
    colors.forEach(x=>x.classList.remove('active'));
    c.classList.add('active');
    penColor = c.dataset.color;
  });
});


penSize.addEventListener('input', e => penW = +e.target.value);
ersSize.addEventListener('input', e => ersW = +e.target.value);
//////////////////////////////////////////////////////

function updateTime() {
  const now = new Date();
  const hours = now.getHours().toString().padStart(2, '0');
  const minutes = now.getMinutes().toString().padStart(2, '0');
  document.getElementById('clock').textContent = `${hours}:${minutes}`;
}

updateTime(); // 页面加载时先调用一次
setInterval(updateTime, 1000 * 60); // 每分钟更新一次
//////////////////////////////////////////////////////

class RainbowTrail {
  constructor() {
      this.canvas = document.getElementById('canvas2');
      this.ctx = this.canvas.getContext('2d');
      this.toggle = document.getElementById('toggle');
      this.resizeCanvas();
      
      // 状态管理
      this.isDrawing = false;
      this.activeTrails = [];  // 改为存储独立线段
      this.hue = 0;
      this.lifeTime = 3000;
      this.lineWidth = 6;

      // 触摸事件绑定到canvas，并阻止默认行为
      this.canvas.addEventListener('touchstart', (e) => {
          e.preventDefault(); 
          this.startDrawing(e);
      }, {passive: false});

      this.canvas.addEventListener('touchmove', (e) => {
          e.preventDefault(); 
          this.draw(e);
      }, {passive: false});

      this.canvas.addEventListener('touchend', (e) => {
          e.preventDefault();
          this.stopDrawing();
      }, {passive: false});

      this.canvas.addEventListener('touchcancel', (e) => {
          e.preventDefault();
          this.stopDrawing();
      }, {passive: false});

      // 鼠标事件绑定在canvas
      this.canvas.addEventListener('mousedown', (e) => this.startDrawing(e));
      this.canvas.addEventListener('mousemove', (e) => this.draw(e));
      this.canvas.addEventListener('mouseup', () => this.stopDrawing());
      this.canvas.addEventListener('mouseleave', () => this.stopDrawing());

      // 监听窗口resize
      window.addEventListener('resize', () => this.resizeCanvas());

      this.animate();
  }

  resizeCanvas() {
      this.canvas.width = window.innerWidth;
      this.canvas.height = window.innerHeight;
  }

  startDrawing(e) {
      if (!this.toggle.checked) return;
      
      // 鼠标事件时，确保左键点击
      if (e.type === 'mousedown' && e.button !== 0) return;

      this.isDrawing = true;
      
      // 创建新的轨迹线段
      this.activeTrails.push({
          points: [],
          startTime: Date.now()
      });
  }

  draw(e) {
      if (!this.toggle.checked || !this.isDrawing) return;

      const currentTrail = this.activeTrails[this.activeTrails.length - 1];
      let touch;

      if (e.type.startsWith('touch')) {
          // 多点触控只取第一个触点
          touch = e.touches[0];
          if (!touch) return;
      } else {
          touch = e;
      }
      const newPoint = {
          x: touch.clientX,
          y: touch.clientY,
          hue: this.hue,
          timestamp: Date.now()
      };

      if (currentTrail.points.length > 0) {
          const lastPoint = currentTrail.points[currentTrail.points.length - 1];
          this.hue = (this.hue + Math.sqrt(
              Math.pow(newPoint.x - lastPoint.x, 2) +
              Math.pow(newPoint.y - lastPoint.y, 2)
          ) * 0.3) % 360;
      }

      newPoint.hue = this.hue;
      currentTrail.points.push(newPoint);
  }

  stopDrawing() {
      this.isDrawing = false;
  }

  animate() {
      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
      
      // 绘制所有有效轨迹
      this.activeTrails = this.activeTrails.filter(trail => {
          const age = Date.now() - trail.startTime;
          if (age > this.lifeTime) return false;
          
          for (let i = 0; i < trail.points.length - 1; i++) {
              const current = trail.points[i];
              const next = trail.points[i + 1];
              
              const opacity = 1 - (age + (current.timestamp - trail.startTime)) / this.lifeTime;
              if (opacity <= 0) continue;

              this.ctx.beginPath();
              this.ctx.moveTo(current.x, current.y);
              this.ctx.lineTo(next.x, next.y);
              this.ctx.strokeStyle = `hsla(${current.hue}, 100%, 50%, ${opacity})`;
              this.ctx.lineWidth = this.lineWidth;
              this.ctx.lineCap = 'round';
              this.ctx.stroke();
          }
          return true;
      });

      requestAnimationFrame(() => this.animate());
  }
}

new RainbowTrail();

// 控制canvas显示隐藏的代码，保持不变
canvas2.style.display = 'none';
// canvas2.style.pointerEvents = 'none';
mytoggle.addEventListener('change', function() {
  if (toggle.checked) {
    canvas2.style.display = 'block';
  } else {
    canvas2.style.display = 'none';
  }
});
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////

document.addEventListener('keydown', function(event) {
  if ((event.ctrlKey && event.shiftKey && event.key.toLowerCase() === 'o')  || (event.ctrlKey && event.key === 's')) {
    event.preventDefault();
    savefile(); 
  }
});


document.addEventListener('keydown', function(event) {
  if (event.ctrlKey && event.shiftKey && event.key.toLowerCase() === 'y') {
    event.preventDefault();
    let urltmp = window.location.href;
    copyToClipboard(urltmp);
    showSuccess('复制链接成功');
  }
});



 