const SCENES = { Init:{ load() { LOAD_STACK(SCENES.Offline); CONTEXT.Scene = SCENES.Online; RECONNECT(); return true; }, }, Offline:{ load() { UI.nav([ UI.button("Reconnect", () => { RECONNECT(); }) ], []); return true; }, }, Register:{ load() { if(CONTEXT.Auth !== null) return false; UI.mainmenu(); UI.mainnav([], []); let container = document.createElement("section"); let form = document.createElement("div"); form.appendChild(UI.table(null, [ [ UI.label("Handle", "handle"), UI.textbox("handle", "") ], [ UI.label("Secret", "secret"), UI.password("secret") ], [ UI.label("Code", "code"), UI.password("code") ], ])); let button = UI.button("Register", (event) => { let handle = document.getElementById("handle"); let secret = document.getElementById("secret"); let code = document.getElementById("code"); handle.removeAttribute("class"); secret.removeAttribute("class"); code.removeAttribute("class"); event.target.removeAttribute("class"); if(handle.value.length > 0 && secret.value.length > 0 && code.value.length > 0) { event.target.setAttribute("disabled", ""); let enc = new TextEncoder(); let enc_handle = enc.encode(handle.value); let enc_secret = enc.encode(secret.value); let enc_code = enc.encode(code.value); MESSAGE_COMPOSE([ PACK.u16(OpCode.Register), PACK.u16(enc_handle.length), enc_handle, PACK.u16(enc_secret.length), enc_secret, PACK.u16(enc_code.length), enc_code, ]); } else { if(handle.value.length == 0) { handle.setAttribute("class", "error"); } if(secret.value.length == 0) { secret.setAttribute("class", "error"); } if(code.value.length == 0) { code.setAttribute("class", "error"); } } }); button.setAttribute("id", "submit"); form.appendChild(button); container.appendChild(form); MAIN.appendChild(container); MAIN.setAttribute("class", "form"); return true; }, message(code, data) { if(code == OpCode.Register && data !== null) { let submit = document.getElementById("submit"); switch(data.status) { case Status.Ok: { CONTEXT.Auth = data; LOAD(SCENES.Online); } break; default: { submit.removeAttribute("disabled"); switch(data.status) { case Status.BadHandle: { document.getElementById("handle").setAttribute("class", "error"); submit.setAttribute("class", "error"); } break; case Status.BadSecret: { document.getElementById("secret").setAttribute("class", "error"); submit.setAttribute("class", "error"); } break; case Status.BadCode: { document.getElementById("code").setAttribute("class", "error"); submit.setAttribute("class", "error"); } break; } } } } }, }, Authenticate:{ load() { if(CONTEXT.Auth !== null) return false; UI.mainmenu(); UI.mainnav([], []); let container = document.createElement("section"); let form = document.createElement("div"); form.appendChild(UI.table(null, [ [ UI.label("Handle", "handle"), UI.textbox("handle", "") ], [ UI.label("Secret", "secret"), UI.password("secret") ], ])); let button = UI.button("Login", (event) => { let handle = document.getElementById("handle"); let secret = document.getElementById("secret"); handle.removeAttribute("class"); secret.removeAttribute("class"); event.target.removeAttribute("class"); if(handle.value.length > 0 && secret.value.length > 0) { event.target.setAttribute("disabled", ""); let enc = new TextEncoder(); let enc_handle = enc.encode(handle.value); let enc_secret = enc.encode(secret.value); MESSAGE_COMPOSE([ PACK.u16(OpCode.Authenticate), PACK.u16(enc_handle.length), enc_handle, PACK.u16(enc_secret.length), enc_secret, ]); } else { if(handle.value.length == 0) { handle.setAttribute("class", "error"); } if(secret.value.length == 0) { secret.setAttribute("class", "error"); } } }); button.setAttribute("id", "submit"); form.appendChild(button); container.appendChild(form); MAIN.appendChild(container); MAIN.setAttribute("class", "form"); return true; }, message(code, data) { if(code == OpCode.Authenticate && data !== null) { let submit = document.getElementById("submit"); switch(data.status) { case Status.Ok: { CONTEXT.Auth = data; LOAD(SCENES.Online); } break; case Status.Error: { submit.removeAttribute("disabled"); document.getElementById("handle").setAttribute("class", "error"); document.getElementById("secret").setAttribute("class", "error"); submit.setAttribute("class", "error"); } } } }, }, Online:{ load() { UI.mainmenu(); CONTEXT.data = { page:0, records:[], }; let left_buttons = [ ]; if(CONTEXT.Auth !== null) { left_buttons.push(UI.button("Start", () => { MESSAGE_SESSION_START(); })); } UI.mainnav( left_buttons, [ UI.div([UI.text("0 - 0 of 0")]), UI.button("◀", null), UI.button("▶", null), UI.button("Refresh", null), ] ); let table = document.createElement("table"); table.setAttribute("id", "content"); table.setAttribute("class", "list"); MAIN.appendChild(table); SCENE.refresh(); return true; }, refresh() { MESSAGE_SESSION_LIST(0, 0, false, false); }, message(code, data) { if(code == OpCode.SessionList) { let table = document.getElementById("content"); UI.clear(table); if(data !== null) { table.appendChild(UI.session_table(data.records)); } } } }, Continue:{ load() { if(CONTEXT.Auth === null) return false; UI.mainmenu(); let left_buttons = [ ]; if(CONTEXT.Auth !== null) { left_buttons.push(UI.button("Start", null)); } UI.mainnav( left_buttons, [ UI.div([UI.text("0 - 0 of 0")]), UI.button("◀", null), UI.button("▶", null), ] ); let table = document.createElement("table"); table.setAttribute("id", "content"); MAIN.appendChild(table); MAIN.setAttribute("class", "list"); SCENE.refresh(); return true; }, refresh() { }, message(code, data) { if(code == OpCode.SessionList) { let table = document.getElementById("content"); UI.clear(table); if(data !== null) { table.appendChild(UI.session_table(data.records)); } } } }, Join:{ load() { if(CONTEXT.Auth === null) return false; UI.mainmenu(); let left_buttons = [ ]; if(CONTEXT.Auth !== null) { left_buttons.push(UI.button("Start", null)); } UI.mainnav( left_buttons, [ UI.div([UI.text("0 - 0 of 0")]), UI.button("◀", null), UI.button("▶", null), ] ); let table = document.createElement("table"); table.setAttribute("id", "content"); MAIN.appendChild(table); MAIN.setAttribute("class", "list"); SCENE.refresh(); return true; }, refresh() { }, message(code, data) { if(code == OpCode.SessionList) { let table = document.getElementById("content"); UI.clear(table); if(data !== null) { table.appendChild(UI.session_table(data.records)); } } } }, Live:{ load() { UI.mainmenu(); let left_buttons = [ ]; if(CONTEXT.Auth !== null) { left_buttons.push(UI.button("Start", null)); } UI.mainnav( left_buttons, [ UI.div([UI.text("0 - 0 of 0")]), UI.button("◀", null), UI.button("▶", null), ] ); let table = document.createElement("table"); table.setAttribute("id", "content"); MAIN.appendChild(table); MAIN.setAttribute("class", "list"); SCENE.refresh(); return true; }, refresh() { }, message(code, data) { if(code == OpCode.SessionList) { let table = document.getElementById("content"); UI.clear(table); if(data !== null) { table.appendChild(UI.session_table(data.records)); } } } }, History:{ load() { UI.mainmenu(); UI.mainnav( [ ], [ UI.div([UI.text("0 - 0 of 0")]), UI.button("◀", null), UI.button("▶", null), ] ); let table = document.createElement("table"); table.setAttribute("id", "content"); MAIN.appendChild(table); MAIN.setAttribute("class", "list"); SCENE.refresh(); return true; }, refresh() { }, message(code, data) { if(code == OpCode.SessionList) { let table = document.getElementById("content"); UI.clear(table); if(data !== null) { table.appendChild(UI.session_table(data.records)); } } } }, Guide:{ load() { UI.mainmenu(); UI.mainnav([], []); return true; }, refresh() { }, }, About:{ load() { UI.mainmenu(); UI.mainnav([], []); return true; }, refresh() { }, }, Game:{ load() { UI.nav([ UI.button("Rotate", () => { }), ], [ UI.button("Back", () => { LOAD(SCENES.Online) }), UI.button("Retire", () => { }), ]); let canvas = document.createElement("canvas"); canvas.setAttribute("id", "game"); MAIN.appendChild(canvas); INTERFACE.init(); return true; }, unload() { INTERFACE.uninit(); MESSAGE_COMPOSE([ PACK.u16(OpCode.SessionLeave), ]); }, message(code, data) { if(code == OpCode.GameState || code == OpCode.GamePlay) { INTERFACE.message(code, data); } }, }, }; function LOAD(scene) { UNLOAD(); UI.rebuild(); SCENE = scene; CONTEXT.Scene = SCENE; if(!SCENE.load()) { LOAD(SCENES.Online); } } function UNLOAD() { if(SCENE !== null && SCENE.unload !== undefined) { SCENE.unload(); } } function LOAD_STACK(scene) { UNLOAD(); UI.rebuild(); SCENE = scene; if(!SCENE.load()) { LOAD(SCENES.Online); } }