//!wrt $BSPEC:{"icn":"apps/wmbox","cpr":"Copyright (C) Windows 96 Team 2023.","dsc":"WMBox V86 Backend","frn":"WMBox V86 Runner","ver":1,"ssy":"gui"}

const{MsgBoxSimple:MsgBoxSimple,OpenFileDialog:OpenFileDialog,SaveFileDialog:SaveFileDialog,DialogCreator:DialogCreator,Theme:Theme,MenuBar:MenuBar}=w96.ui;class WMBoxRunner extends WApplication{constructor(){super(),this.emulatorConfig={disable_keyboard:!0,disable_mouse:!0,bios:{url:"/system/apps/wmbox/libs/v86/bios/seabios.bin"},network_adapter:null,vga_bios:{url:"/system/apps/wmbox/libs/v86/bios/vgabios.bin"}},this.blobsToUnregister=[]}async main(e){if(super.main(e),null==e[1])return void DialogCreator.create({title:"WMBox",body:"No WMX file was specified to run.",icon:"error"});const t=this.createWindow({title:" - WMBox",icon:await Theme.getIconUrl("apps/wmbox","16x16"),initialWidth:728,initialHeight:473,taskbar:!0,resizable:!0,bodyClass:"wmbx-runner-app",body:'<div class="appbar"></div>\n            <iframe class="vm" src="/system/apps/wmbox/vm.html"></iframe>\n            <footer class="w96-footer">\n                <div class="cell">Visible Viewport &lt;0x0&gt;</div>\n            </footer>',center:!0,mobResize:!0},!0);t.setTitle("<null> - WMBox");const o=t.getBodyContainer(),a=new MenuBar;a.addRoot("File",[{type:"normal",label:"Exit",onclick:()=>this.terminate()}]),a.addRoot("Machine",[{type:"normal",label:"Pause",onclick:()=>{try{this.emu.stop()}catch(e){DialogCreator.create({title:"WMBox",body:"Unable to pause this machine.",icon:"error"})}}},{type:"normal",label:"Resume",onclick:()=>{try{this.emu.run()}catch(e){DialogCreator.create({title:"WMBox",body:"Unable to resume this machine.",icon:"error"})}}},{type:"separator"},{type:"normal",label:"Reset",onclick:()=>{try{this.emu.restart()}catch(e){DialogCreator.create({title:"WMBox",body:"Unable to restart this machine.",icon:"error"})}}},{type:"separator"},{type:"normal",label:"Save State",onclick:()=>{try{this.emu.save_state(((e,t)=>{e?DialogCreator.create({title:"WMBox",body:`Unable to save this machine's state: ${e}`,icon:"error"}):new SaveFileDialog("c:/user/documents",[".wms"],(async e=>{if(e&&""!=e.trim()){const o=MsgBoxSimple.idleProgress("WMBox","Saving state...");try{await FS.writebin(e,new Uint8Array(t))}catch(e){DialogCreator.create({title:"WMBox",body:`Unable to save this machine's state: ${e}`,icon:"error"})}o.closeDialog()}})).show()}))}catch(e){DialogCreator.create({title:"WMBox",body:"Unable to save this machine's state.",icon:"error"})}}},{type:"normal",label:"Load State",onclick:()=>{try{new OpenFileDialog("c:/user/documents",[".wms"],(async e=>{if(e&&""!=e.trim()){const t=MsgBoxSimple.idleProgress("WMBox","Loading state...");try{this.emu.restore_state(await FS.readbin(e))}catch(e){DialogCreator.create({title:"WMBox",body:`Unable to load this machine's state: ${e}`,icon:"error"})}t.closeDialog()}})).show()}catch(e){DialogCreator.create({title:"WMBox",body:"Unable to load this state.",icon:"error"})}}}]),a.addRoot("View",[{type:"normal",label:"Enter Fullscreen",onclick:()=>this.appFrame.requestFullscreen()},{label:"Scale Mode",type:"submenu",items:[{type:"normal",label:"Aspect",onclick:()=>this.setViewMode("aspect")},{type:"normal",label:"Scaled",onclick:()=>this.setViewMode("scaled")}]},{type:"separator"},{type:"normal",label:"Take Screenshot",onclick:()=>{try{this.appFrame.contentDocument.querySelector("canvas").toBlob((async e=>{const t=new Uint8Array(await e.arrayBuffer());new SaveFileDialog("c:/user/documents",[".png"],(async e=>{if(e&&""!=e.trim())try{await FS.writebin(e,t)}catch(e){DialogCreator.create({title:"WMBox",body:"Unable to take screenshot.",icon:"error"})}})).show()}),"image/png")}catch(e){DialogCreator.create({title:"WMBox",body:"Unable to take screenshot.",icon:"error"})}}}],!1),a.addRoot("Help",[{type:"normal",label:"About",onclick:()=>DialogCreator.alert('<span class="bold-noaa">WMBox with v86 Backend (wmbxrun-v86)</span><br>Version 1.0<br><br>v86 is made possible by <a href="https://copy.sh">copy.sh</a>',{title:"About WMBox",icon:"info"})}]),o.querySelector(".appbar").replaceWith(a.getMenuDiv());const i=o.querySelector("iframe");i.onload=async()=>{try{i.contentWindow.app.init({instance:this,onresize:e=>{o.querySelector("footer .cell").innerText=`Visible Viewport: <${e.width}x${e.height}>`}}),await this.readWMX(e[1]),this.startVM()}catch(e){DialogCreator.create({title:"WMBox",body:`An error occurred: ${e}<br><br>VM execution has been halted.`,icon:"error"}),this.terminate()}},t.show(),this.mainwnd=t,this.appFrame=i}async readWMX(e){const t=JSON.parse(await FS.readstr(e));if(!t.backend)throw new Error("This VM has no backend specified.");if("v86"!==t.backend)throw new Error("This runner only supports VMs using the v86 backend.");if(!(t.meta&&t.meta.name&&t.memory_size&&t.vga&&t.vga.memory_size&&t.attachments))throw new Error("Malformed WMX file.");this.mainwnd.setTitle(`${t.meta.name} <v86> - WMBox`),t.meta.icon&&this.mainwnd.setWindowIcon(`/system/resource/app/wmbox/icons/${t.meta.icon}.png`),this.emulatorConfig.disable_keyboard=null==t.attachments.find((e=>"keyboard"==e.type)),this.emulatorConfig.disable_mouse=null==t.attachments.find((e=>"mouse"==e.type));const o=FSUtil.getParentPath(e);this.baseWmxPath=o;const a=t.attachments.find((e=>"cdrom"==e.type));if(a){const e=FSUtil.resolvePath(o,a.path);this.emulatorConfig.cdrom={url:await FS.exists(e)?await FS.toURL(e):e},this.blobsToUnregister.push(this.emulatorConfig.cdrom.url)}const i=t.attachments.find((e=>"fda"==e.type));if(i){const e=FSUtil.resolvePath(o,i.path);this.emulatorConfig.fda={url:await FS.exists(e)?await FS.toURL(e):e},this.blobsToUnregister.push(this.emulatorConfig.fda.url)}await this.resolveUrlField(t,"bios"),await this.resolveUrlField(t,"vga_bios"),await this.resolveUrlField(t,"hdd"),this.emulatorConfig.memory_size=t.memory_size,this.emulatorConfig.vga_memory_size=t.vga.memory_size,this.emulatorConfig.boot_order=t.boot_order||void 0,this.emulatorConfig.acpi=t.acpi||void 0,this.emulatorConfig.cmdline=t.cmdline||void 0,this.emulatorConfig.v86=t.v86||void 0}async resolveUrlField(e,t){const o=e[t];if(o){const e=FSUtil.resolvePath(this.baseWmxPath,o.path);this.emulatorConfig[t]={url:await FS.exists(e)?await FS.toURL(e):e},this.blobsToUnregister.push(this.emulatorConfig[t].url)}}startVM(){this.appFrame.contentWindow.app.hookEvents();const e=this.appFrame.contentWindow.app.createEmulator({...this.emulatorConfig,autostart:!0});this.emu=e}setViewMode(e){"scaled"==e?this.appFrame.contentDocument.body.classList.add("view-scaled"):this.appFrame.contentDocument.body.classList.remove("view-scaled")}ontermination(){try{this.emu.destroy()}catch(e){}for(let e of this.blobsToUnregister)URL.revokeObjectURL(e);this.mainwnd=null,this.appFrame=null,this.emu=null,super.ontermination()}}

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