//!wrt $BSPEC:{"icn":null,"cpr":"Copyright (C) Windows 96 Team 2023.","dsc":"","frn":"Open With","ver":1,"ssy":"gui"}

const{CheckBox:CheckBox}=w96.ui.components,{WindowParams:WindowParams}=w96,{getShellAppRegistry:getShellAppRegistry}=w96.sys.reg,{execCmd:execCmd}=w96.sys,{argParser:ArgParser,escapeHtml:escapeHtml}=w96.util,{Theme:Theme,MsgBoxSimple:MsgBoxSimple}=w96.ui,hiddenApps=["openwith","about-ui","__exe","wasmrt","devtools","__lnk","__support-us","dd","hterm","dynwp-prefs","mpmenu","wpa","credits","runlnk42","effects","dyk","uploader","jslinux","terminal","settings","wiki96","blocks","win96-chat","gltest","gameing","vm","server-stat","shareboard","notron","youare","pumkin","avabot","winspector","bsod","meme-man","matrix","winmp96","base64","welcome"],ASSOC_CONFIG_PATH="c:/system/config/assocs.json";class OpenWithApplication extends WApplication{constructor(){super()}async getAssocs(){let e={};try{!w96.isRecovery&&await FS.exists(ASSOC_CONFIG_PATH)?e=JSON.parse(await FS.readstr(ASSOC_CONFIG_PATH)):w96.isRecovery||await FS.writestr(ASSOC_CONFIG_PATH,"{}")}catch(e){console.warn("failed to read file associations")}return e}async setAssocs(e,t,s){console.log("setAssocs",...arguments),s[t]=e,await FS.writestr(ASSOC_CONFIG_PATH,JSON.stringify(s))}async main(e){if(super.main(e),e.shift(),this.args=e,null==e[0])return void MsgBoxSimple.error("Error","You are doing this wrong.","wat");if(!await FS.exists(e[0]))return void MsgBoxSimple.error("Error","Cannot find the file to open!","OK");let t=await this.getAssocs(),s=FSUtil.fname(e[0]),i=null;if(s.includes(".")){let e=s.split(".");i="."+e[e.length-1]}if(this.fileExt=i,this.assocs=t,i&&t[i]){try{await execCmd(t[i][0],[...t[i][1],...e])}catch(e){await this.setAssocs(void 0,i,t),MsgBoxSimple.error("Error",String(e),"OK",(()=>execCmd("openwith",this.args)).bind(this))}return this.terminate()}const n=new WindowParams;n.initialHeight=400,n.initialWidth=430,n.title="Open With",n.resizable=!1;const o=this.createWindow(n,!0);o.registerWindow(),o.setControlBoxStyle("WS_CBX_CLOSE");const a=o.getBodyContainer();a.classList.add("openwith-app"),a.innerHTML=`<div class="top">\n            <div class="icon" style="background: url(${await Theme.getIconUrl("mime/unknown")})"></div>\n            <div class="text">\n                Choose the program you want to use to open this file:<br>\n                <br>\n                File: ${escapeHtml(s)}\n            </div>\n        </div>\n\n        <div class="box">\n            <div class="appbox"></div>\n        </div>\n\n        <div class="bottom">\n            <div class="cmd-box">\n                <span class="bold-noaa">Custom command</span>\n                <input class="w96-textbox custom-cmd">\n            </div>\n            <div class="remember-checkbox" style="margin-top: 1em"></div>\n            <div class="dlg-buttons">\n                <button class="w96-button ok">OK</button>\n                <button class="w96-button cancel">Cancel</button>\n            </div>\n        </div>`,a.querySelector(".dlg-buttons>.cancel").addEventListener("click",(()=>this.terminate())),a.querySelector(".dlg-buttons>.ok").addEventListener("click",(async()=>{if(""!=a.querySelector(".custom-cmd").value.trim())await this.procCustomCmd(e);else if(null!=this.selectedItem){try{this.rememberChoice&&await this.setAssocs([this.selectedItem,[]],i,t),execCmd(this.selectedItem,e)}catch(e){console.error(e)}this.terminate()}}));let r=new CheckBox({label:"",checked:!1,onchange:(e=>{this.rememberChoice=e.checked}).bind(this),displayAsBlock:!0}).getElement(),c=r.querySelector("span.text");i?c.innerHTML='Always use this application for <span class="bold-noaa">'+escapeHtml(i)+"</span> files.":(r.querySelector("input[type=checkbox]").disabled=!0,c.style.textShadow="1px 1px white",c.style.color="gray",c.innerText="Always use this application for these files."),a.querySelector(".remember-checkbox").appendChild(r),a.querySelector(".custom-cmd").addEventListener("keydown",(t=>{"Enter"==t.key&&this.procCustomCmd(e)}));const l=a.querySelector(".appbox");for(let s of getShellAppRegistry()){if(hiddenApps.includes(s.exec))continue;const n=document.createElement("div");n.classList.add("item");const o=document.createElement("div");o.classList.add("icon"),o.style.backgroundImage=`url(${await Theme.getIconUrl("mime/executable")})`,n.appendChild(o);const r=document.createElement("div");r.classList.add("text"),r.innerText=s.exec,n.appendChild(r),n.addEventListener("click",(()=>{a.querySelectorAll(".appbox>.item").forEach((e=>e.classList.remove("selected"))),n.classList.add("selected"),this.selectedItem=s.exec})),n.addEventListener("dblclick",(async()=>{try{this.rememberChoice&&await this.setAssocs([this.selectedItem,[]],i,t),execCmd(this.selectedItem,e)}catch(e){console.error(e)}this.terminate()})),s.icon&&s.name&&(r.innerText=s.name,Theme.getIconUrl(s.icon,"32x32").then((e=>{o.style.backgroundImage=`url(${e})`})),l.appendChild(n))}o.show(),o.center(),this.mainwnd=o}async procCustomCmd(e){const t=this.mainwnd.getBodyContainer().querySelector(".custom-cmd"),s=ArgParser.parse(t.value);this.terminate();try{this.rememberChoice&&await this.setAssocs([s[0],[]],this.fileExt,this.assocs),await execCmd(s[0],e)}catch(e){MsgBoxSimple.error("Error",String(e),"OK",(()=>execCmd("openwith",this.args)).bind(this))}}}

return await WApplication.execAsync(new OpenWithApplication(), this.boxedEnv.args, this);