//!wrt $BSPEC:{"icn":"apps/monaco","cpr":"Copyright (C) Windows 96 Team 2023.","dsc":"Code editor based on Monaco from Microsoft.","frn":"Monaco","ver":1,"ssy":"gui"}

const{WindowParams:WindowParams,FSFeatures:FSFeatures}=w96,{Theme:Theme,MenuBar:MenuBar,MsgBoxSimple:MsgBoxSimple,OpenFileDialog:OpenFileDialog,SaveFileDialog:SaveFileDialog,DialogCreator:DialogCreator}=w96.ui,{rand:rand}=w96.util,{execCmd:execCmd}=w96.sys;class MonacoApplication extends WApplication{constructor(){super(),this.libs=[]}async main(t){super.main(t),await this.initData(),this._createWindow(t)}async initData(){const t="C:/system/local/share/monaco/types";await FS.exists(t)||await FS.mkdir(t);const e=MsgBoxSimple.idleProgress("Loading libraries","Importing typings...");for(let e of await FS.readdir(t))e.toLowerCase().endsWith(".ts")&&this.libs.push({name:`ts:int/${FSUtil.fname(e)}`,content:await FS.readstr(e)});e.closeDialog()}async _createWindow(t){var e=new WindowParams;e.title="Monaco",e.initialWidth=620,e.initialHeight=440;var n=this.createWindow(e,!0);n.registerWindow(),n.registerAppBar(),n.setHtml('\n        <div class="appbar"></div>\n        <iframe src="/system/apps/monaco/"></iframe>\n        <footer class="w96-footer">\n            <div class="cell">\n                <none>\n            </div>\n        </footer>\n        ');const i=n.wndObject.querySelector(".window-html-content");i.classList.add("monaco-app"),n.setWindowIcon(await Theme.getIconUrl("apps/monaco","16x16"));const o=new MenuBar;o.addRoot("File",[{type:"normal",label:"New",onclick:()=>{this.newDocumentUI()}},{type:"separator"},{type:"normal",label:"Open",onclick:()=>{this.openDocumentDialog()}},{type:"normal",label:"Save",onclick:async()=>{await this.saveDocumentDialog()}},{type:"normal",label:"Save As",onclick:async()=>{await this.saveDocumentDialog(!0)}},{type:"separator"},{type:"normal",label:"Exit",onclick:()=>{this.documentModified?MsgBoxSimple.confirm("Are you sure? The current document is not saved yet!",(t=>{t&&this.mainwnd.close()}),"warning"):this.mainwnd.close()}}]),o.addRoot("View",[{type:"submenu",label:"Themes",items:[{type:"normal",label:"Dark",onclick:()=>this.switchTheme("vs-dark")},{type:"normal",label:"Light",onclick:()=>this.switchTheme("vs-light")},{type:"normal",label:"High Contrast Dark",onclick:()=>this.switchTheme("hc-black")}]}],!1),o.addRoot("Document",[{type:"submenu",label:"Language",items:[{type:"normal",label:"Batch",onclick:()=>this.switchLang("bat")},{type:"normal",label:"C / C++",onclick:()=>this.switchLang("c")},{type:"normal",label:"CSS",onclick:()=>this.switchLang("css")},{type:"normal",label:"HTML",onclick:()=>this.switchLang("html")},{type:"normal",label:"INI",onclick:()=>this.switchLang("ini")},{type:"normal",label:"JavaScript",onclick:()=>this.switchLang("js")},{type:"normal",label:"JSON",onclick:()=>this.switchLang("json")},{type:"normal",label:"Lua",onclick:()=>this.switchLang("lua")},{type:"normal",label:"Markdown",onclick:()=>this.switchLang("md")},{type:"normal",label:"Python",onclick:()=>this.switchLang("py")},{type:"normal",label:"TypeScript",onclick:()=>this.switchLang("ts")},{type:"normal",label:"YAML",onclick:()=>this.switchLang("yaml")},{type:"separator"},{type:"normal",label:"Plain Text",onclick:()=>this.switchLang("plain")}]},{type:"separator"},{type:"normal",label:"Document Info",onclick:()=>this.appFrame.contentWindow.showDocInfo()}],!1),o.addRoot("Tools",[{type:"normal",label:"Preview in Browser",onclick:async()=>{const t="c:/system/temp/"+(rand(0,1e6)+".html");await FS.writestr(t,this.appFrame.contentWindow.editor.getValue()),execCmd("internete",[t])}},{type:"separator"},{type:"normal",label:"Edit Monaco Config",onclick:()=>{MsgBoxSimple.confirm("Are you sure? Please save any changes first.",(t=>{t&&this.loadDocument("c:/user/appdata/Monaco/config.json")}),"warning")}}]),o.addRoot("Help",[{type:"normal",label:"About",onclick:()=>{MsgBoxSimple.info("About Monaco",'<span class="bold-noaa">Monaco Editor</span><br>Version 1.1<br><br>Powered by <a href="https://github.com/microsoft/monaco-editor">Microsoft Monaco Editor</a>',"OK").dlg.setSize(320,140)}}]);const a=n.wndObject.querySelector("iframe");a.onload=()=>{a.contentWindow.app(w96,u96,this,(e=>{a.contentDocument.addEventListener("click",(()=>document.body.onclick({target:this.appWindow.wndObject}))),i.querySelector(".appbar").replaceWith(o.getMenuDiv()),null==t[1]?this.newDocument():this.loadDocument(t[1])}))},n.ondarkenelements=()=>{a.style.pointerEvents="none"},n.onlightenelements=()=>{a.style.pointerEvents=""},this.currentDocument=null,this.lastPath="c:/",this.documentModified=!1,this.appFrame=a,this.mainwnd=n,n.onclose=t=>{this.documentModified&&(t.canceled=!0,MsgBoxSimple.confirm("Are you sure? The current document is not saved yet!",(t=>{t&&(this.documentModified=!1,n.close())}),"warning"))},n.show()}newDocument(){this.mainwnd.setTitle("Untitled - Monaco"),this.appFrame.contentWindow.editor.setValue(""),this.appFrame.contentWindow.switchLang("plain"),this.mainwnd.wndObject.querySelector(".w96-footer>.cell").textContent="<untitled document>",this.currentDocument=null,this.setDocumentModified(!1)}updateTitle(){let t=null==this.currentDocument?"Untitled":FSUtil.fname(this.currentDocument);this.mainwnd.setTitle((this.documentModified?"*":"")+t+" - Monaco")}setDocumentModified(t){this.documentModified!==t&&(this.documentModified=t,this.updateTitle())}checkReadOnly(t){if(!t)return!1;const e=FSUtil.deconstructFullPath(t);return FS.get(e.prefix).features.includes(FSFeatures.readOnly)}switchTheme(t){this.appFrame.contentWindow.switchTheme(t)}switchLang(t){this.appFrame.contentWindow.switchLang(t)}async loadDocument(t){if(!await FS.exists(t)||!await FS.isFile(t))return MsgBoxSimple.error("Error","Cannot load file.","OK"),void this.newDocument();const e=await FS.readstr(t);this.appFrame.contentWindow.editor.setValue(e),this.appFrame.contentWindow.assumeLangFromExt(t),this.mainwnd.setTitle(FSUtil.fname(t)+" - Monaco"),this.mainwnd.wndObject.querySelector(".w96-footer>.cell").textContent=t,this.currentDocument=t,this.lastPath=FSUtil.getParentPath(t),2==this.lastPath.length&&(this.lastPath+="/"),this.setDocumentModified(!1)}async saveDocumentDialog(t){this.checkReadOnly(this.currentDocument)?MsgBoxSimple.error("Error saving document","This document is stored in a read-only location.","OK"):null==this.currentDocument||t?new SaveFileDialog(this.lastPath,[/.*/],(async t=>{t&&""!=t.trim()&&(this.currentDocument=t,await FS.writestr(this.currentDocument,this.appFrame.contentWindow.editor.getValue()),this.lastPath=FSUtil.getParentPath(t),this.appFrame.contentWindow.assumeLangFromExt(t),this.mainwnd.setTitle(FSUtil.fname(t)+" - Monaco"),this.setDocumentModified(!1),2==this.lastPath.length&&(this.lastPath+="/"))})).show():(await FS.writestr(this.currentDocument,this.appFrame.contentWindow.editor.getValue()),this.setDocumentModified(!1))}openDocumentDialog(){new OpenFileDialog(this.lastPath,[/.*/],(async t=>{t&&""!=t.trim()&&((await FS.stat(t)).length>1048576?MsgBoxSimple.confirm("The file is larger than 1 MB. Continue loading? (you may suffer)",(e=>{e&&(this.documentModified?MsgBoxSimple.confirm("Are you sure? The current document is not saved yet!",(e=>{e&&this.loadDocument(t)}),"warning"):this.loadDocument(t))}),"warning"):this.documentModified?MsgBoxSimple.confirm("Are you sure? The current document is not saved yet!",(e=>{e&&this.loadDocument(t)}),"warning"):this.loadDocument(t))})).show()}newDocumentUI(){this.documentModified?MsgBoxSimple.confirm("Are you sure? The current document is not saved yet!",(t=>{t&&this.newDocument()}),"warning"):this.newDocument()}ontermination(){super.ontermination()}}

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