/**
 * Copyright 2023 The Pennsylvania State University
 * @license Apache-2.0, see License.md for full text.
 */
import{html as e,css as t}from"../../lit/index.js";import"../simple-icon/lib/simple-icon-button.js";import"../../web-dialog/index.js";import"../absolute-position-behavior/absolute-position-behavior.js";import"./lib/super-daemon-ui.js";import{SuperDaemonToastInstance as i}from"./lib/super-daemon-toast.js";import{SimpleColors as o}from"../simple-colors/simple-colors.js";class SuperDaemon extends o{static get properties(){return{...super.properties,santaMode:{type:Boolean,reflect:!0,attribute:"santa-mode"},opened:{type:Boolean,reflect:!0},loading:{type:Boolean,reflect:!0},key1:{type:String},key2:{type:String},icon:{type:String},items:{type:Array},programResults:{type:Array},programName:{type:String},allItems:{type:Array},context:{type:Array},commandContext:{type:String},program:{type:String},programSearch:{type:String},like:{type:String},value:{type:String},mini:{type:Boolean},wand:{type:Boolean,reflect:!0},activeNode:{type:Object},programTarget:{type:Object},voiceSearch:{type:Boolean,reflect:!0,attribute:"voice-search"},voiceCommands:{type:Object},listeningForInput:{type:Boolean,reflect:!0,attribute:"listening-for-input"}}}firstUpdated(t){super.firstUpdated&&super.firstUpdated(t),SuperDaemonInstance.defineOption({title:"Toggle Santa Mode",textCharacter:"🎅",tags:["Developer","big-tech","santa","all-seeing-eye"],eventName:"super-daemon-element-method",path:">settings/hohoho",voice:"(toggle) santa (mode)",context:[">"],more:e`<span
        >He sees you when your sleeping, he knows when your awake, and with this
        command active he is always listening for input ready to respond. He's..
        Santa Merlin. Ho..Ho...Ho.</span
      >`,value:{target:this,method:"toggleSantaMode",args:[]}})}constructor(){super(),this.toastInstance=i,this.activeSelection=null,this.wandTarget=null,this.voiceCommands={},this.programTarget=null,this.activeRange=null,this.santaMode=!1,this.activeNode=null,this.voiceSearch=!1,this.listeningForInput=!1,this.voiceRespondsTo="merlin",this.hal=null,this.windowControllers=new AbortController,this.windowControllers2=new AbortController,this.value="",this.icon="hardware:keyboard-return",this.context=[],this.opened=!1,this.items=[],this.loading=!1,this.like="",this.mini=!1,this.wand=!1,this._programValues={},this.programSearch="",this.allItems=[],this.programResults=[],this.programName=null,this.commandContext="*";const e=void 0!==globalThis.safari;this.key1=e?"Meta":"Alt",this.key2="Shift"}connectedCallback(){super.connectedCallback(),globalThis.addEventListener("keydown",this.keyHandler.bind(this),{signal:this.windowControllers.signal}),globalThis.addEventListener("super-daemon-define-option",this.defineOptionEvent.bind(this),{signal:this.windowControllers.signal}),globalThis.addEventListener("super-daemon-element-method",this.elementMethod.bind(this),{signal:this.windowControllers.signal}),globalThis.addEventListener("super-daemon-element-click",this.elementClick.bind(this),{signal:this.windowControllers.signal}),globalThis.addEventListener("super-daemon-run-program",this.runProgramEvent.bind(this),{signal:this.windowControllers.signal}),globalThis.addEventListener("super-daemon-voice-command",this._addVoiceCommand.bind(this),{signal:this.windowControllers.signal}),globalThis.addEventListener("super-daemon-close",this.close.bind(this),{signal:this.windowControllers.signal})}disconnectedCallback(){this.windowControllers.abort(),this.windowControllers2.abort(),super.disconnectedCallback()}waveWand(e,t=null,i=null){t||(t=this.wandTarget),this.mini=!0,this.wand=!0,this.activeNode=t,this.runProgram(...e),i&&this.playSound(i),this.open()}async runProgram(e=null,t="/",i={},o=null,s=null,a=""){if(this.commandContext=t,"string"==typeof o){const e=await this.allItems.find((e=>e.value.machineName===o));e?this._programToRun=e.value.program:console.error("Incorrect program called",o)}else this._programToRun=o;this.programSearch=a,null!=e&&(this.like=e),this._programToRun?setTimeout((()=>{this.shadowRoot.querySelector("super-daemon-ui").setupProgram(),setTimeout((async()=>{try{this.loading=!0,this.programResults=await this._programToRun(this.programSearch,i),this.loading=!1}catch(e){this.loading=!1}}),50)}),0):this.programResults=[],this.programName=s}runProgramEvent(e){if(e.detail){let t=e.detail;this._programValues=t,this.like="",this.runProgram(null,t.context,this._programValues,t.program,t.name,"")}else this.runProgram("","/"),this._programValues={}}elementMethod(e){if(e.detail){let t=e.detail;t.args||(t.args=[]),t.target[t.method](...t.args)}}elementClick(e){e.detail&&e.detail.target.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0,view:window}))}defineOptionEvent(e){this.defineOption(e.detail)}defineOption(e){if(e&&e.value&&e.title&&e.eventName){e.tags||(e.tags=[]),e.path||(e.path=""),e.priority||(e.priority=0),e.context||(e.context="*");let t={...e};delete t.icon,delete t.image,delete t.textCharacter,delete t.value,delete t.eventName,t=Object.values(t).filter((e=>{if(!["boolean","number"].includes(typeof e)&&""!==e&&null!=e)return!0}));let i=[];t.map((e=>{if("string"==typeof e){e.split("/").map((e=>{["","*","/"," ",">"].includes(e)||i.push(e.toLocaleLowerCase())}))}else Array.isArray(e)&&e.map((e=>{["","*","/"," ",">"].includes(e)||i.push(e.toLocaleLowerCase())}))}));let o=i.join(" ").replace(/\*/g,"").replace(/\?/g,"");i=[...new Set(o.split(" "))],e.index=i.join(" ")+" "+e.path,this.allItems.push(e)}}updateSearchInputViaVoice(e){this.shadowRoot.querySelector("super-daemon-ui").like=e,this.shadowRoot.querySelector("super-daemon-ui").focusInput(),setTimeout((()=>{this.setListeningStatus(!1)}),0)}addVoiceCommand(e,t,i){t&&(e=e.replace(":name:",this.voiceRespondsTo).toLocaleLowerCase(),this.voiceCommands[e]=t[i].bind(t))}_addVoiceCommand(e){let t=e.detail.context;t||(t=e.target),this.addVoiceCommand(e.detail.command,t,e.detail.callback)}keyHandler(e){this.allowedCallback()&&("Shift"==this.key2&&e.shiftKey&&("Ctrl"==this.key1&&e.ctrlKey||"Alt"==this.key1&&e.altKey?(this.opened=!this.opened,this.keyHandlerCallback()):"Meta"!=this.key1||"Meta"!==e.key&&!e.metaKey||(this.opened=!this.opened,this.keyHandlerCallback())),"Escape"==e.key&&this.opened&&this.miniCancel())}static get styles(){let e=[];return super.styles&&(e=super.styles),[e,t`
        :host {
          display: none;
        }
        :host([opened]) {
          display: block;
        }
        web-dialog {
          --dialog-border-radius: var(--simple-modal-border-radius, 2px);
          z-index: var(--simple-modal-z-index, 10000) !important;
          padding: 0;
          color: var(--simple-colors-default-theme-grey-12, black);
        }
        web-dialog::part(dialog) {
          color: var(--simple-colors-default-theme-grey-12, black);
          background-color: var(--simple-colors-default-theme-grey-1, white);
          border: 1px solid var(--simple-modal-border-color, #222);
          min-height: var(--simple-modal-min-height, unset);
          min-width: var(--simple-modal-min-width, unset);
          z-index: var(--simple-modal-z-index, 10000);
          resize: var(--simple-modal-resize, unset);
          padding: 0;
          --dialog-height: var(--simple-modal-height, auto);
          --dialog-width: var(--simple-modal-width, 75vw);
          --dialog-max-width: var(--simple-modal-max-width, 100vw);
          --dialog-max-height: var(--simple-modal-max-height, 100vh);
        }
        web-dialog.style-scope.simple-modal {
          display: none !important;
        }
        web-dialog[open].style-scope.simple-modal {
          display: flex !important;
          position: fixed !important;
          margin: auto;
        }
        web-dialog super-daemon-ui {
          --super-daemon-search-width: 100%;
        }
        :host([resize="none"]) web-dialog[open].style-scope.simple-modal,
        :host([resize="horizontal"]) web-dialog[open].style-scope.simple-modal {
          top: calc(50% - var(--simple-modal-height, auto) / 2);
        }
        :host([resize="none"]) web-dialog[open].style-scope.simple-modal,
        :host([resize="vertical"]) web-dialog[open].style-scope.simple-modal {
          left: calc(50% - var(--simple-modal-width, 75vw) / 2);
        }
        #cancel {
          position: absolute;
          right: 0px;
          top: 0px;
          z-index: 100000000;
          display: block;
          margin: 0;
          --simple-icon-width: 24px;
          --simple-icon-height: 24px;
        }
        :host([wand]) absolute-position-behavior {
          top: 24px !important;
          right: 0;
          position: fixed !important;
          display: table;
        }
        absolute-position-behavior {
          z-index: var(--simple-modal-z-index, 10000);
          min-width: 280px;
          width: 280px;
          color: var(--simple-colors-default-theme-grey-12, black);
        }
        absolute-position-behavior super-daemon-ui[mini][wand] {
          margin: -18px 0 0 0;
          padding: 0px;
        }
        absolute-position-behavior super-daemon-ui {
          width: 280px;
          margin: -64px 0 0 -8px;
          padding: 4px 0 0 0;
          color: var(--simple-colors-default-theme-grey-12, black);
          background-color: var(--simple-colors-default-theme-grey-1, white);
        }
        super-daemon-ui {
          color: var(--simple-colors-default-theme-grey-12, black);
          background-color: var(--simple-colors-default-theme-grey-1, white);
        }
      `]}setListeningStatus(e){this.santaMode?this.listeningForInput=!0:this.listeningForInput=e}close(e={}){this.activeNode=null,this.loading=!1,this.like="",this.opened=!1,this.mini=!1,this.wand=!1,this._programValues={},this.programSearch="",this.voiceCommands={},this.defaultVoiceCommands(),this.programResults=[],this.programName=null,this.commandContext="*",this.setListeningStatus(!1),this.santaMode||(e&&"super-daemon-close"===e.type||globalThis.dispatchEvent(new CustomEvent("super-daemon-close",{bubbles:!0,composed:!0,cancelable:!0,detail:!0})),e&&"super-daemon-close"!==e.type&&"close"!==e.type&&globalThis.dispatchEvent(new CustomEvent("super-daemon-toast-hide",{bubbles:!0,composed:!0,cancelable:!1,detail:!1})));const t=new MouseEvent("click",{view:window,bubbles:!0,cancelable:!0});globalThis.document.dispatchEvent(t),this.windowControllers2.abort(),globalThis.ShadyCSS&&!globalThis.ShadyCSS.nativeShadow&&(this.shadowRoot.querySelector("web-dialog").shadowRoot.querySelector("#backdrop").style.position="relative")}filterItems(e,t){let i=e.filter((e=>{if(e.context){let i=[];return"*"===e.context?e:(i="*"==this.commandContext?t.filter((t=>e.context.includes(t))):[this.commandContext].filter((t=>e.context.includes(t))),0!==i.length)}return!0}));return i.sort(((e,t)=>{var i=e.title.toUpperCase(),o=t.title.toUpperCase();return i<o?-1:i>o?1:0})),i.forEach((e=>{e.title.toLocaleLowerCase()==this.value.toLocaleLowerCase()&&(e.priority=-1e7)})),i.sort(((e,t)=>e.priority<t.priority?-1:e.priority>t.priority?1:0))}playSound(e="coin2"){return new Promise((t=>{let i=["coin2"].includes(e)?e:"coin2";this.audio=new Audio(new URL(`./lib/assets/sounds/${i}.mp3`,import.meta.url).href),this.audio.volume=.3,this.audio.onended=e=>{t()},this.audio.play(),setTimeout((()=>{t()}),1e3)}))}appendContext(e){if(e&&!this.context.includes(e)){let t=[...this.context];t.push(e),this.context=[...t]}}removeContext(e){if(e&&this.context.includes(e)){let t=[...this.context];t.splice(t.indexOf(e),1),this.context=[...t]}}clickOnMiniMode(e){e.isTrusted&&(e.target!==this?this.miniCancel():globalThis.addEventListener("click",this.clickOnMiniMode.bind(this),{once:!0,passive:!0,signal:this.windowControllers2.signal}))}miniCancel(){if(this.activeNode&&this.activeNode.focus&&this.mini&&!this.wand&&this.activeRange&&this.activeSelection)try{this.activeNode.textContent=this.value,this.activeNode.focus(),this.activeRange.setStart(this.activeNode,0),this.activeRange.collapse(!0),this.activeSelection.removeAllRanges(),this.activeSelection.addRange(this.activeRange),this.activeSelection.selectAllChildren(this.activeNode),this.activeSelection.collapseToEnd()}catch(e){console.warn(e)}this.close()}open(){this.opened=!0,this.items=this.filterItems(this.allItems,this.context);const e=this.shadowRoot.querySelector("web-dialog");e&&(e.$backdrop.addEventListener("click",e.onBackdropClick),e.addEventListener("keydown",e.onKeyDown,{capture:!0,passive:!0}),globalThis.ShadyCSS&&!globalThis.ShadyCSS.nativeShadow&&(this.shadowRoot.querySelector("web-dialog").shadowRoot.querySelector("#backdrop").style.position="fixed",this.shadowRoot.querySelector("web-dialog").shadowRoot.querySelector("#backdrop").style.top=0,this.shadowRoot.querySelector("web-dialog").shadowRoot.querySelector("#backdrop").style.bottom=0,this.shadowRoot.querySelector("web-dialog").shadowRoot.querySelector("#backdrop").style.left=0,this.shadowRoot.querySelector("web-dialog").shadowRoot.querySelector("#backdrop").style.right=0)),this.windowControllers2.abort(),this.reprocessVoiceCommands(),requestAnimationFrame((()=>{this.windowControllers2=new AbortController,this.mini&&globalThis.addEventListener("click",this.clickOnMiniMode.bind(this),{once:!0,passive:!0,signal:this.windowControllers2.signal}),this.shadowRoot.querySelector("super-daemon-ui").focusInput()}))}focusout(e){if(e){let t=e.relatedTarget;for(;t!==globalThis.document.body&&null!==t;){if(t===this.shadowRoot.querySelector("super-daemon-ui"))return;if(!t||!t.parentElement)return;t=t.parentElement}t!==this.shadowRoot.querySelector("super-daemon-ui")&&setTimeout((()=>{this.opened&&this.shadowRoot.querySelector("super-daemon-ui").focusInput()}),0)}}noResultsSlot(e){}render(){return e`${this.mini?e`
          <absolute-position-behavior
            justify
            position="${this.wand?"right":"bottom"}"
            allow-overlap
            sticky
            auto
            .target="${this.activeNode}"
            ?hidden="${!this.opened}"
          >
            <super-daemon-ui
              ?opened="${this.opened}"
              ?mini="${this.mini}"
              ?wand="${this.wand}"
              icon="${this.icon}"
              ?dark="${this.dark}"
              ?loading="${this.loading}"
              like="${this.like}"
              ?listening-for-input="${this.listeningForInput}"
              ?voice-search="${this.voiceSearch}"
              .items="${this.itemsForDisplay(this.items,this.programResults)}"
              command-context="${this.commandContext}"
              program-name="${this.programName}"
              program-search="${this.programSearch}"
              @value-changed="${this.inputfilterChanged}"
              @super-daemon-close="${this.close}"
              @super-daemon-command-context-changed="${this.commandContextChanged}"
              >${this.noResultsSlot(this.like||this.programSearch)}</super-daemon-ui
            >
          </absolute-position-behavior>
        `:e`
          <web-dialog
            id="dialog"
            center
            role="dialog"
            part="dialog"
            aria-label="Super Daemon"
            aria-modal="true"
            ?open="${this.opened}"
            @open="${this.open}"
            @close="${this.close}"
            @focusout="${this.focusout}"
          >
            <super-daemon-ui
              ?opened="${this.opened}"
              icon="${this.icon}"
              ?loading="${this.loading}"
              like="${this.like}"
              ?dark="${this.dark}"
              ?voice-search="${this.voiceSearch}"
              ?listening-for-input="${this.listeningForInput}"
              @like-changed="${this.likeChanged}"
              .items="${this.itemsForDisplay(this.items,this.programResults)}"
              command-context="${this.commandContext}"
              program-name="${this.programName}"
              program-search="${this.programSearch}"
              @value-changed="${this.inputfilterChanged}"
              @super-daemon-close="${this.close}"
              @super-daemon-command-context-changed="${this.commandContextChanged}"
              >${this.noResultsSlot(this.like||this.programSearch)}</super-daemon-ui
            >
            <simple-icon-button
              id="cancel"
              icon="cancel"
              ?dark="${this.dark}"
              @click="${this.close}"
            ></simple-icon-button>
          </web-dialog>
        `} `}likeChanged(e){this.like=e.detail.value}randomResponse(e){return e[Math.floor(Math.random()*e.length)]}toggleSantaMode(e){this.santaMode=!this.santaMode,setTimeout((()=>{let e="Santa mode activated: Watch what you say";this.santaMode||(e="Santa mode deactivated: Have a nice day believing you are not being watched"),this.hal.speak(e,this.santaMode).then((e=>{this.setListeningStatus(this.santaMode),this.hal.setToast("Listening..")}))}),0)}merlinSpeak(e){this.hal.speak(e,!1,!1).then((e=>{this.close()}))}promptMerlin(e){this.opened||this.open(),this.__closeLock=!0,this.listeningForInput=!1,this.hal.speak(this.randomResponse(["I'm here","Yes?","What?","What can I do for you?","What do you need?","How can I help?"]),this.santaMode).then((e=>{this.playSound().then((e=>{this.listeningForInput=!0,this.__closeLock=!1}))}))}stopMerlin(e){this.santaMode&&this.hal.speak("Please disable Santa mode to stop listening",this.santaMode),this.setListeningStatus(!1)}closeMerlin(e){this.santaMode?this.close():this.hal.speak(this.randomResponse(["thanks for stopping by","See ya","See you soon","Till we meet again"]),this.santaMode).then((e=>{this.close()}))}belsnickel(){this.santaMode&&this.toggleSantaMode()}defaultVoiceCommands(){this.addVoiceCommand(`(hey) ${this.voiceRespondsTo}`,this,"promptMerlin"),this.addVoiceCommand("(hey) marilyn",this,"promptMerlin"),this.addVoiceCommand("stop listening",this,"stopMerlin"),this.addVoiceCommand("close merlin",this,"closeMerlin"),this.addVoiceCommand("cancel merlin",this,"closeMerlin"),this.addVoiceCommand("disable santa (mode)",this,"belsnickel"),this.addVoiceCommand("belsnickel",this,"belsnickel"),this.addVoiceCommand("scroll",this,"scroll"),this.voiceCommands["scroll up"]=e=>{globalThis.scrollBy({top:-.5*globalThis.innerHeight,left:0,behavior:"smooth"})},this.voiceCommands["scroll (down)"]=e=>{globalThis.scrollBy({top:.5*globalThis.innerHeight,left:0,behavior:"smooth"})},this.voiceCommands["scroll (to) bottom"]=e=>{globalThis.scrollTo(0,globalThis.document.body.scrollHeight)},this.voiceCommands["scroll (to) top"]=e=>{globalThis.scrollTo(0,0)},this.voiceCommands["back to top"]=e=>{globalThis.scrollTo(0,0)},this.voiceCommands["(run) program"]=e=>{this.commandContextChanged({detail:{value:"/",label:"program"}})},this.voiceCommands["developer (mode)"]=e=>{this.commandContextChanged({detail:{value:">",label:"developer"}})},this.addVoiceCommand("*anything",this,"updateSearchInputViaVoice")}updated(e){super.updated&&super.updated(e),e.has("activeNode")&&this.activeNode&&this.wand&&this.mini&&requestAnimationFrame((()=>{const e=this.activeNode.getBoundingClientRect();this.shadowRoot.querySelector("absolute-position-behavior").style.left=e.left+e.width+"px"})),e.has("commandContext")&&this.dispatchEvent(new CustomEvent("super-daemon-command-context-changed",{bubbles:!0,composed:!0,detail:{value:this.commandContext}})),e.has("context")&&this.dispatchEvent(new CustomEvent("super-daemon-context-changed",{bubbles:!0,composed:!0,detail:{value:this.context}})),e.has("voiceSearch")&&this.voiceSearch?import("../hal-9000/hal-9000.js").then((()=>{this.hal=globalThis.Hal9000.requestAvailability(),this.hal.debug=!1,this.hal.toast=!0,this.defaultVoiceCommands()})):e.has("voiceSearch")&&!this.voiceSearch&&(this.hal=null),e.has("listeningForInput")&&this.hal&&(this.hal.enabled=this.listeningForInput,globalThis.HAXCMS&&(this.listeningForInput?(globalThis.HAXCMS.instance.setCursor("hax:loading"),globalThis.HAXCMS.instance.setFavicon("hax:loading")):(globalThis.HAXCMS.instance.resetCursor(),globalThis.HAXCMS.instance.resetFavicon())),clearTimeout(this._listeningTimeout),this._listeningTimeout=setTimeout((()=>{this.listeningForInput||this.__closeLock||globalThis.dispatchEvent(new CustomEvent("super-daemon-toast-hide",{bubbles:!0,composed:!0,cancelable:!1,detail:!1}))}),100))}async inputfilterChanged(e){this.value=e.detail.value,this.programName&&this._programToRun?(this.loading=!0,this.programResults=await this._programToRun(e.detail.value,this._programValues),this.loading=!1):(this.programResults=[],this.items=this.filterItems(this.allItems,this.context))}itemsForDisplay(e,t){return null!=this.programName?t:e}reprocessVoiceCommands(){this.hal&&this.voiceSearch&&this.items&&(clearTimeout(this._blockRerunTimeout),this._blockRerunTimeout=setTimeout((async()=>{this.defaultVoiceCommands();for await(const e of this.items)e.title&&(this.voiceCommands[e.voice?e.voice.toLocaleLowerCase():e.title.toLocaleLowerCase()]=t=>{this.shadowRoot.querySelector("super-daemon-ui").items=[e],this.value=e.title,this.shadowRoot.querySelector("super-daemon-ui").filtered=[e],setTimeout((()=>{this.shadowRoot.querySelector("super-daemon-ui").shadowRoot.querySelector("super-daemon-row").selected()}),0),e.value.program?this.playSound().then((e=>{this.shadowRoot.querySelector("super-daemon-ui").focusInput()})):this.setListeningStatus(!1)});this.hal.commands={...this.voiceCommands}}),10))}commandContextChanged(e){if(e.detail.value)switch(e.detail.value){case"/":case"*":case">":this.commandContext=e.detail.value,this.items=this.filterItems(this.allItems,this.context)}else this.commandContext="*",this.items=this.filterItems(this.allItems,this.context);this.voiceSearch&&setTimeout((()=>{e.detail.label?(this.__closeLock=!0,this.listeningForInput=!1,this.hal.speak(`${e.detail.label} mode activated`).then((e=>{this.playSound().then((e=>{this.reprocessVoiceCommands(),this.__closeLock=!1,this.listeningForInput=!0}))}))):this.reprocessVoiceCommands()}),0)}keyHandlerCallback(){return!0}allowedCallback(){return!0}static get tag(){return"super-daemon"}}customElements.define(SuperDaemon.tag,SuperDaemon);export{SuperDaemon};globalThis.SuperDaemonManager=globalThis.SuperDaemonManager||{},globalThis.SuperDaemonManager.requestAvailability=()=>(globalThis.SuperDaemonManager.instance||(globalThis.SuperDaemonManager.instance=globalThis.document.createElement("super-daemon"),globalThis.document.body.appendChild(globalThis.SuperDaemonManager.instance)),globalThis.SuperDaemonManager.instance);export const SuperDaemonInstance=globalThis.SuperDaemonManager.requestAvailability();