const UI = { text(value) { return document.createTextNode(value); }, button(text, callback, select=false) { let button = document.createElement("button"); button.innerText = text; if(select) { button.setAttribute("class", "selected"); } if(callback !== null) { button.addEventListener("click", callback); } return button; }, textbox(id, placeholder) { let input = document.createElement("input"); input.setAttribute("type", "text"); if(id !== null) { input.setAttribute("id", id); } input.setAttribute("placeholder", placeholder); return input; }, password(id) { let input = document.createElement("input"); input.setAttribute("type", "password"); if(id !== null) { input.setAttribute("id", id); } return input; }, label(name, id) { let label = document.createElement("label"); label.setAttribute("for", id); label.innerText = name; return label; }, span(children, attr_class) { let span = document.createElement("span"); if(attr_class !== undefined) { span.setAttribute("class", attr_class); } for(child of children) { span.appendChild(child); } return span; }, div(children, attr_class) { let div = document.createElement("div"); if(attr_class !== undefined) { div.setAttribute("class", attr_class); } for(child of children) { div.appendChild(child); } return div; }, table_content(header, rows) { let tbody = document.createElement("tbody"); if(header !== null) { let row = document.createElement("tr"); for(head of header) { let cell = document.createElement("th"); cell.innerText = head; row.appendChild(cell); } tbody.appendChild(row); } for(row of rows) { let tr = document.createElement("tr"); for(node of row) { let cell = document.createElement("td"); if(Array.isArray(node)) { for(item of node) { cell.appendChild(item); } } else { cell.appendChild(node); } tr.appendChild(cell); } tbody.appendChild(tr); } return tbody; }, table(header, rows) { let table = document.createElement("table"); table.appendChild(this.table_content(header, rows)); return table; }, mainnav(left_children, right_children) { let header = document.createElement("nav"); let left = document.createElement("section"); for(child of left_children) { left.appendChild(child); } let right = document.createElement("section"); for(child of right_children) { right.appendChild(child); } header.appendChild(left); header.appendChild(right); MAIN.appendChild(header); }, mainnav_std(left_children, right_children) { let header = document.createElement("nav"); let left = document.createElement("section"); if(CONTEXT.Auth === null) { left.appendChild(UI.button("Register", () => { LOAD_STACK(SCENES.Register); })); left.appendChild(UI.button("Log In", () => { LOAD_STACK(SCENES.Authenticate); })); } else { left.appendChild(UI.button("Contest", () => { MESSAGE_SESSION_START(); })); left.appendChild(UI.button("Challenge", () => { })); } for(child of left_children) { left.appendChild(child); } let right = document.createElement("section"); for(child of right_children) { right.appendChild(child); } header.appendChild(left); header.appendChild(right); MAIN.appendChild(header); }, nav(top, bottom) { let section = document.createElement("section"); for(node of top) { section.appendChild(node); } MENU.appendChild(section); section = document.createElement("section"); for(node of bottom) { section.appendChild(node); } MENU.appendChild(section); }, mainmenu(page) { if(SOCKET !== null) { let top = [ ]; let bottom = [ ]; top.push(UI.button("Browse", () => { LOAD(SCENES.Browse); }, page == "browse")); if(CONTEXT.Auth !== null) { top.push(UI.button("Continue", () => { LOAD(SCENES.Continue); }, page == "continue")); top.push(UI.button("Join", () => { LOAD(SCENES.Join); }, page == "join")); } top.push(UI.button("Live", () => { LOAD(SCENES.Live); }, page == "live")); top.push(UI.button("History", () => { LOAD(SCENES.History); }, page == "history")); top.push(UI.button("Practice", () => { LOAD(SCENES.GamePractice); }, page == "practice")); top.push(UI.button("Guide", () => { LOAD(SCENES.Guide); }, page == "guide")); top.push(UI.button("About", () => { LOAD(SCENES.About); }, page == "about")); if(CONTEXT.Auth !== null) { bottom.push(UI.button("Logout", () => { MESSAGE_COMPOSE([ PACK.u16(OpCode.Deauthenticate), ]); CONTEXT.Auth = null; LOAD(SCENE); })); } UI.nav(top, bottom); } }, session_table(records) { let rows = [ ]; for(let r = 0; r < records.length; ++r) { let buttons = [ ]; let join_callback = function() { MESSAGE_SESSION_JOIN(this.token, true); }; join_callback = join_callback.bind({token: records[r].token}); let spectate_callback = function() { MESSAGE_SESSION_JOIN(this.token, false); }; spectate_callback = spectate_callback.bind({token: records[r].token}); if(records[r].player) { buttons.push(UI.button("Resume", join_callback)); } else { if(CONTEXT.Auth !== null && (records[r].dawn == "" || records[r].dusk == "")) { buttons.push(UI.button("Join", join_callback)); } buttons.push(UI.button("Spectate", spectate_callback)); } let dawn = UI.text(records[r].dawn); if(records[r].dawn == "") { dawn = UI.span([UI.text("Vacant")], "text-system"); } let dusk = UI.text(records[r].dusk); if(records[r].dusk == "") { dusk = UI.span([UI.text("Vacant")], "text-system"); } rows.push([ dawn, dusk, UI.text(records[r].turn), UI.text(records[r].viewers), buttons, ]); } let tbody = UI.table_content( [ "Dawn", "Dusk", "Turn", "Spectators", "" ], rows, ); return tbody; }, session_table_join(records) { let rows = [ ]; for(let r = 0; r < records.length; ++r) { let buttons = [ ]; let join_callback = function() { MESSAGE_SESSION_JOIN(this.token, true); }; join_callback = join_callback.bind({token: records[r].token}); if(records[r].player) { buttons.push(UI.button("View", join_callback)); } else { buttons.push(UI.button("Join", join_callback)); } let host = UI.text(records[r].dawn); if(records[r].dawn == "") { dawn = UI.span([UI.text("Vacant")], "text-system"); } rows.push([ host, buttons, ]); } let tbody = UI.table_content( [ "Host", "" ], rows, ); return tbody; }, session_table_history(records) { let rows = [ ]; for(let r = 0; r < records.length; ++r) { let buttons = [ ]; let view_callback = function() { MESSAGE_COMPOSE([ PACK.u16(OpCode.GameHistory), this.token, ]); }; view_callback = view_callback.bind({token: records[r].token}); buttons.push(UI.button("View", view_callback)); let dawn = UI.text(records[r].dawn); if(records[r].dawn == "") { dawn = UI.span([UI.text("Vacant")], "text-system"); } let dusk = UI.text(records[r].dusk); if(records[r].dusk == "") { dusk = UI.span([UI.text("Vacant")], "text-system"); } rows.push([ dawn, dusk, UI.text(records[r].turn), buttons, ]); } let tbody = UI.table_content( [ "Dawn", "Dusk", "Turn", "" ], rows, ); return tbody; }, clear(dom) { while(dom.lastChild !== null) { dom.removeChild(document.body.lastChild); } }, rebuild() { this.clear(document.body); MENU = document.createElement("nav"); let title = document.createElement("header"); title.innerText = "Omen"; MENU.appendChild(title); MAIN = document.createElement("main"); document.body.appendChild(MENU); document.body.appendChild(MAIN); }, };