const SCENES = { Init:{ load() { LOAD_STACK(SCENES.Offline); CONTEXT.Scene = SCENES.Browse; RECONNECT(); return true; }, }, Offline:{ load() { UI.nav([ UI.button("Reconnect", () => { RECONNECT(); }) ], []); return true; }, reconnect() { LOAD(CONTEXT.Scene); } }, 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.Browse); } 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; } } } } }, disconnect() { LOAD_STACK(SCENES.Offline); }, }, 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.Browse); } break; case Status.Error: { submit.removeAttribute("disabled"); document.getElementById("handle").setAttribute("class", "error"); document.getElementById("secret").setAttribute("class", "error"); submit.setAttribute("class", "error"); } } } }, disconnect() { LOAD_STACK(SCENES.Offline); }, }, Browse:{ load() { CONTEXT.Data = { page:0, records:[], }; UI.mainmenu(); 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, 2, false, false); }, message(code, data) { switch(code) { case OpCode.SessionList: { let table = document.getElementById("content"); UI.clear(table); if(data !== null) { table.appendChild(UI.session_table(data.records)); } } break; case OpCode.SessionCreate: case OpCode.SessionJoin: { if(data.status == Status.Ok) { LOAD(SCENES.Game, data); } } break; } }, disconnect() { LOAD_STACK(SCENES.Offline); }, }, Continue:{ load() { if(CONTEXT.Auth === null) return false; CONTEXT.Data = { page:0, records:[], }; UI.mainmenu(); 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, 2, true, false); }, message(code, data) { switch(code) { case OpCode.SessionList: { let table = document.getElementById("content"); UI.clear(table); if(data !== null) { table.appendChild(UI.session_table(data.records)); } } break; case OpCode.SessionCreate: case OpCode.SessionJoin: { if(data.status == Status.Ok) { LOAD(SCENES.Game, data); } } break; } }, disconnect() { LOAD_STACK(SCENES.Offline); }, }, Join:{ load() { if(CONTEXT.Auth === null) return false; CONTEXT.Data = { page:0, records:[], }; UI.mainmenu(); 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, 1, false, false); }, message(code, data) { switch(code) { case OpCode.SessionList: { let table = document.getElementById("content"); UI.clear(table); if(data !== null) { table.appendChild(UI.session_table_join(data.records)); } } break; case OpCode.SessionCreate: case OpCode.SessionJoin: { if(data.status == Status.Ok) { LOAD(SCENES.Game, data); } } break; } }, disconnect() { LOAD_STACK(SCENES.Offline); }, }, Live:{ load() { CONTEXT.Data = { page:0, records:[], }; UI.mainmenu(); 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, 2, false, true); }, message(code, data) { switch(code) { case OpCode.SessionList: { let table = document.getElementById("content"); UI.clear(table); if(data !== null) { table.appendChild(UI.session_table(data.records)); } } break; case OpCode.SessionCreate: case OpCode.SessionJoin: { if(data.status == Status.Ok) { LOAD(SCENES.Game, data); } } break; } }, disconnect() { LOAD_STACK(SCENES.Offline); }, }, History:{ load() { CONTEXT.Data = { page:0, records:[], }; 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)); } } }, disconnect() { LOAD_STACK(SCENES.Offline); }, }, Guide:{ load() { UI.mainmenu(); UI.mainnav([], []); return true; }, refresh() { }, }, About:{ load() { UI.mainmenu(); UI.mainnav([], []); return true; }, refresh() { }, }, Game:{ load(data) { let buttons_bottom = [ ]; if(data.mode != 2) { buttons_bottom.push(UI.button("Retire", () => { })); } buttons_bottom.push(UI.button("Back", () => { LOAD(SCENES.Browse) })); UI.nav([ UI.button("Rotate", () => { INTERFACE.rotate(); }), UI.button("Mirror", () => { INTERFACE.mirror(); }), ], buttons_bottom); let canvas = document.createElement("canvas"); canvas.setAttribute("id", "game"); MAIN.appendChild(canvas); INTERFACE.init(data, true); return true; }, unload() { INTERFACE.uninit(); }, message(code, data) { switch(code) { case OpCode.GameState: { if(data.status == Status.Ok) { INTERFACE.message(code, data); } else { LOAD(SCENES.Browse); } } break; case OpCode.GamePlay: { INTERFACE.message(code, data); } break; } }, disconnect() { LOAD_STACK(SCENES.Offline); }, }, GamePractice:{ load(data) { let buttons_bottom = [ ]; buttons_bottom.push(UI.button("Reset", () => { INTERFACE.reset(); })); buttons_bottom.push(UI.button("Back", () => { LOAD(SCENES.Browse) })); UI.nav([ UI.button("Rotate", () => { INTERFACE.rotate(); }), UI.button("Mirror", () => { INTERFACE.mirror(); }), ], buttons_bottom); let canvas = document.createElement("canvas"); canvas.setAttribute("id", "game"); MAIN.appendChild(canvas); INTERFACE.init(data, false); return true; }, unload() { INTERFACE.uninit(); }, }, }; function LOAD(scene, data=null) { UNLOAD(); UI.rebuild(); SCENE = scene; CONTEXT.Scene = SCENE; CONTEXT.Data = null; if(!SCENE.load(data)) { LOAD(SCENES.Browse); } } function UNLOAD() { if(SCENE !== null && SCENE.unload !== undefined) { SCENE.unload(); } } function LOAD_STACK(scene, data=null) { UNLOAD(); UI.rebuild(); SCENE = scene; CONTEXT.Data = null; if(!SCENE.load(data)) { LOAD(SCENES.Browse); } }