// gui object classes? // Why am I doing this? class auxillery_dialog { constructor (title) { var me = this; this.root = document.createElement("div"); this.root.classList.add("dialog"); this.title = "string" == typeof title ? title : ""; var title_bar = document.createElement("div"); title_bar.classList.add("title_bar"); var titleText = document.createElement("span"); titleText.innerText = this.title; titleText.classList.add("title_text"); title_bar.appendChild(titleText); this.root.appendChild(title_bar); this.body = document.createElement("div"); this.root.appendChild(me.body); var close = document.createElement("span"); close.innerText = "<"; close.classList.add("close"); title_bar.appendChild(close); close.addEventListener("click", ()=>{ me.root.classList.remove("focused"); }); } } // Functions function systemMsg (message,level=0) { // abstraction? // Yes, but it allows us to easilly redirect error // output to where we want, for now, just the console... switch (level) { case 0: console.log("INFO: "+message); break; case 1: console.error("WARNING: "+message); break; case 2: console.error("ERROR: "+message); break; case 3: console.log("DEBUG: "+message); break; default: console.log(message); } // but later we will also have it push an error toast in the ui. } function inRange(target,min,max) { if (isNaN(target) || isNaN(min) || isNaN(max)) { return false; } return (min <= target && target <= max); } function invokeLibrary(e) { // Breaking this out of event so its not an // annon function, so we can swap it in and out var targetID = ((e.currentTarget.getAttribute("id")).split("pec"))[1]; if (isNaN(targetID)) { return systemMsg("invokeLibrary targetID not a number",2); } var targetPec = app.gui["pec"+targetID]; if (undefined == targetPec) { return systemMsg("invokeLibrary targetPec undefined: "+targetID,2); } if (!inRange(targetID,0,15)) { return systemMsg("invokeLibrary targetID out of range: "+targetPecIndex,2); } app.targetPec = targetPec; app.targetPecIndex = targetID; app.gui.library.root.classList.add("focused"); } function clearPec (index=null) { if (!inRange(index,0,15)) { return systemMsg("clearPec was given an out of range index",2); } var targetPec = app.gui["pec"+index]; if (undefined == targetPec) { return systemMsg("clearPec targetPec undefined",2); } targetPec.classList.add("empty"); targetPec.innerHTML = "

+

"; targetPec.addEventListener("click", invokeLibrary); } function setPec(pecTemplate=null, targetIndex=null) { if (null == pecTemplate) { return systemMsg("setPec was not provided data",2); } if (!(pecTemplate instanceof pec)) { return systemMsg("setPec was not provided a valid template",2); } if (isNaN(targetIndex)) { return systemMsg("setPec was not provided a valid targetIndex",2); } var targetPec = app.gui["pec"+targetIndex]; targetPec.removeEventListener("click", invokeLibrary); targetPec.innerHTML = ""; targetPec.classList.remove("empty"); targetPec.appendChild(pecTemplate.DOM); } function repopBoards (current=0) { //app.boards; //app.currentBoards; //app.menu; // Normally we only want <, but we want an extra // iteration here for the "add new board" element for (var i = 0; i <= app.boards.length; i++) { var boardTab = document.getElementById("board"+i); if (null == boardTab) { boardTab = document.createElement("span"); boardTab.setAttribute("id", "board"+i); boardTab.classList.add("board_tab"); app.gui.menu.appendChild(boardTab); } // Clear event listeners var oldTab = boardTab; boardTab = oldTab.cloneNode(true); oldTab.parentNode.replaceChild(boardTab, oldTab); // not sure how memory safe the above lines are var name = "Board "+i; if (i == app.boards.length) { name = "+"; boardTab.addEventListener("click",(e)=>{ var current = app.boards.findIndex(i=>i==app.currentBoard); app.boards.push(new pecBoard()); repopBoards(current); repopGrid(app.currentBoard); }); } else { if (current != i) { boardTab.classList.remove("active_board"); boardTab.addEventListener("click", (e)=>{ var sourceID = ((e.currentTarget.getAttribute("id")).split("board"))[1]; app.currentBoard = app.boards[sourceID]; repopBoards(sourceID); repopGrid(app.currentBoard); }); } else { boardTab.classList.add("active_board"); } if (undefined != app.boards[i].name) { name = app.boards[i].name; } } boardTab.innerText = name; console.log(boardTab); } } function repopGrid (board=null) { if (null == board) { return systemMsg("repopGrid was not provided data",2); } if (!(board instanceof pecBoard)) { return systemMsg("repopGrid was not provided data of type pecBoard",2); } board.pecs.forEach((p,i)=>{ if (null == p) { return clearPec(i); } if (!(p instanceof pec)) { systemMsg("Invalid Pec found, scrubbing and returning to null",1); board.pecs[i] = null; return clearPec(i); } setPec(p,i); }); } function useThisPec (e) { var sourceID = ((e.currentTarget.getAttribute("id")).split("lPec"))[1]; app.gui.library.root.classList.remove("focused"); app.gui.library.body.childNodes.entries().forEach(p=>{ p[1].getAttribute("id") == "lPec"+sourceID ? p[1].style.display = "none" : null; }); app.currentBoard.pecs[app.targetPecIndex] = app.library[sourceID]; repopGrid(app.currentBoard); } // Initialize gui window.app = {}; app.gui = {}; app.gui.main = document.createElement("div"); app.gui.main.id = "root"; document.body.appendChild(app.gui.main); app.gui.menu = document.createElement("nav"); app.gui.menu.id = "navigation"; app.gui.main.appendChild(app.gui.menu); app.gui.view = document.createElement("div"); app.gui.view.id = "view"; app.gui.main.appendChild(app.gui.view); // Library popup app.gui.library = new auxillery_dialog("Library"); app.gui.library.body.classList.add("dialog_body"); app.gui.main.append(app.gui.library.root); // Options popup app.gui.options = new auxillery_dialog("Options"); app.gui.library.body.classList.add("dialog_body"); app.gui.main.append(app.gui.library.root); // pre-populate grid with emptys for (var x = 0; x < 16; x++) { var name = "pec"+x; var thisPec = document.createElement("span"); app.gui[name] = thisPec; thisPec.classList.add("pecSlot"); thisPec.id = name; clearPec(x); app.gui.view.appendChild(thisPec); } // Create our initial board app.boards = []; app.boards.push(new pecBoard()); app.currentBoard = app.boards[0]; repopBoards(0); repopGrid(app.currentBoard); // Populate Library app.library = []; app.library.push(new pec("No","images/cards_conversation_no.svg")); app.library.push(new pec("Up","")); app.library.push(new pec("More","")); app.library.push(new pec("Drink","images/cards_food_thirsty.svg")); app.library.push(new pec("Food","images/cards_food_hungry.svg")); // add more here app.library.forEach((p,i)=>{ var newPec = document.createElement("span"); newPec.classList.add("libSlot"); newPec.innerText = p.word; newPec.id = "lPec"+i; newPec.addEventListener("click", useThisPec); app.gui.library.body.appendChild(newPec); });