var app = new Object(); app.ctx = new Object(); app.log = function(msg) { var element = document.getElementById('messages-container'); var p = document.createElement("P"); p.innerHTML = msg; element.insertAdjacentElement('afterbegin', p); }; app.debug = function(msg) { if (app.ctx.debug) console.log(msg); }; app.show_call_card = function(call_card) { // show call card var element = document.getElementById('call_card'); var len = call_card.length; var count = 0; element.innerHTML = ''; while (count < (len - 1)) { element.innerHTML += call_card[count]; element.innerHTML += '___'; ++count; } element.innerHTML += call_card[len - 1]; element.hidden = false; }; app.create_user_entry = function(username) { var table = document.getElementById('player_info'); var row = document.createElement('tr'); var cell_select = document.createElement('td'); var cell_name = document.createElement('td'); var cellText = document.createTextNode(username); var cell_score = document.createElement('td'); var cell_round = document.createElement('td'); cell_select.setAttribute('id', username + '_select'); cell_select.setAttribute('class', 'unselected'); cell_name.setAttribute('id', username); cell_score.setAttribute('id', username + '_score'); cell_round.setAttribute('id', username + '_round'); cell_name.appendChild(cellText); row.appendChild(cell_select); row.appendChild(cell_name); row.appendChild(cell_score); row.appendChild(cell_round); table.appendChild(row); }; app.remove_user_entry = function(username) { var cell = document.getElementById(username); cell.parentElement.parentElement.removeChild(cell.parentElement); }; app.start_game = function(name_element) { app.debug(name_element); var e = document.getElementById(name_element); var name = e.value; app.debug(name); var request = {'type': 'New Game', 'player': name}; app.debug('start game'); send(app.ctx.ws, request); }; app.join_game = function(name_element, game_id_element) { var name = document.getElementById(name_element); var game_id = document.getElementById(game_id_element); var request = {'type': 'Join Game', 'player': name.value, 'game_id': game_id.value.toUpperCase()}; app.debug('join game'); send(app.ctx.ws, request); }; app.load_custom_decks = function(deck_id_element) { hide('default_deck'); show(deck_id_element); }; app.start_default_game = function(name_element) { var request = {'type': 'Add Deck', 'game_id': app.ctx.game_id, 'deck_id': 'BWJ79'}; send(app.ctx.ws, request); request['deck_id'] = '4R4DK'; send(app.ctx.ws, request); request['type'] = 'Start Game'; request['num_blanks'] = '50'; request['use_response_cards'] = true; send(app.ctx.ws, request); }; app.add_deck = function(deck_id_element) { var deck_id = document.getElementById(deck_id_element); var request = {'type': 'Add Deck', 'game_id': app.ctx.game_id, 'deck_id': deck_id.value}; app.debug("adding deck " + deck_id.value + " to game " + app.ctx.game_id); send(app.ctx.ws, request); deck_id.value = ""; }; app.start_playing = function() { var e = document.getElementById('blank_response_cards') var qty_blanks = e.value; e = document.getElementById('use_response_cards'); var use_response_cards = e.checked; var request = {'type': 'Start Game', 'game_id': app.ctx.game_id, 'num_blanks': qty_blanks, 'use_response_cards': use_response_cards}; app.debug("start playing game"); send(app.ctx.ws, request); }; app.submit_response = function(game_id_element) { app.debug("submit response cards " + app.ctx.selected_response_cards); var element = document.getElementById("call_card"); var call_card = element.innerHTML; var num_responses_needed = (call_card.match(/___/g) || []).length; var num_selected_responses = app.ctx.selected_response_cards.length; if (num_selected_responses != num_responses_needed) { app.log("This call card needs " + num_responses_needed + " responses."); app.log("You have selected " + num_selected_responses + "."); } else { var responses = []; var count = 0; app.ctx.my_response = []; while (count < app.ctx.selected_response_cards.length) { var id = app.ctx.selected_response_cards[count]; var e = document.getElementById(id + '-writein'); // alert(e); if (e != null) { app.debug("card " + id + " was a write in"); app.ctx.my_response.push(e.value); responses.push([id,e.value]); //alert(e.value); } else { app.ctx.my_response.push(document.getElementById(id).innerHTML); responses.push(id); //alert(document.getElementById(id).innerHTML); } ++count; } var request = {'type': 'Submit Response', 'game_id': app.ctx.game_id, 'value': responses}; // app.ctx.my_response = request['value']; // alert(app.ctx.my_response); app.debug("submitting selected response: "); app.debug(request); send(app.ctx.ws, request); // hide selected cards. var count = 0; while (count < app.ctx.selected_response_cards.length) { var id = app.ctx.selected_response_cards[count]; hide(id); ++count; }; // hide submit button. hide("submit_response"); } }; app.end_play_round = function(game_id_element) { app.debug("ending play round"); var request = {'type': 'End Play Round', 'game_id': app.ctx.game_id}; send(app.ctx.ws, request); hide("submit_response"); }; app.end_scoring_round = function(game_id_element) { app.debug("ending scoring round"); var request = {'type': 'End Scoring Round', 'game_id': app.ctx.game_id}; send(app.ctx.ws, request); hide('end_scoring_round'); app.debug('Removing scoring round elements'); var elem = document.getElementById('score_round'); while (elem.hasChildNodes()) { elem.removeChild(elem.lastChild); } hide('score_round'); // hide('score_response'); }; app.handle_response = function(response) { if ("type" in response) { app.debug("Response was " + JSON.stringify(response)); var type = response['type']; switch(type) { case 'error': app.log(response['value']); break; case 'Error': app.log(response['value']); break; case 'New Game': hide("start_game"); show("setup_game"); //show("decks"); show("default_deck"); //show("start_playing_button_container"); app.ctx.host_id = response['host']; app.ctx.player_id = response['player']; app.debug('host: ' + response['host']); app.create_user_entry(response['host']); app.ctx.game_id = response['game']; element = document.getElementById('setup_game_id'); element.innerHTML = '

Tell your friends to join game ' + app.ctx.game_id + '

'; break; case 'Join Game': hide("start_game"); show("setup_game"); app.ctx.host_id = response['host']; app.ctx.player_id = response['player']; app.create_user_entry(response['host']); var players = response['players']; var count = 0; var total = players.length; while (count < total) { app.create_user_entry(players[count]); ++count; } // app.create_user_entry(response['player']); app.ctx.game_id = response['game']; element = document.getElementById('setup_game_id'); element.innerHTML = '

Tell your friends to join game ' + app.ctx.game_id + '

'; app.show_call_card(response['call_card']); break; case 'Players Update': // update table player rows app.debug('players: ' + response['value']); var players = response['value']; var count = 0; var total = players.length; while (count < total) { var player = document.getElementById(players[count]); if (player == null) app.create_user_entry(players[count]); ++count; } break; case 'Add Deck': var element = document.getElementById('active_decks'); element.innerHTML = '

Decks

' + response['value']; break; case 'Start Play Round': hide("decks"); hide("default_deck"); hide("start_playing_button_container"); hide('end_scoring_round'); var elements = document.getElementsByClassName('selected'); var count = 0; while (count < elements.length) { var element = elements[count]; element.removeAttribute('class'); element.setAttribute('class', 'unselected'); ++count; } var element = document.getElementById(response['reader'] + '_select'); // element.style.fontWeight = 'bold'; element.setAttribute('class', 'selected'); // update scores // show scores // show round number var element = document.getElementById('round'); element.innerHTML = "

Round " + response['round'] + "

"; app.show_call_card(response['call_card']); // show end play round button to host if (app.ctx.host_id == app.ctx.player_id) show("end_play_round"); app.ctx.selected_response_cards = []; show("start_round"); if (response['reader'] == app.ctx.player_id) overlay_on(); //alert(response['reader']); //app.ctx.player_id; //show("submit_response"); break; case 'Response Cards': // show response cards var response_cards = response['value']; var len = response_cards.length; var count = 0; var element = document.getElementById('response_cards'); while (count < len) { var node = document.createElement("P"); node.innerHTML = response_cards[count]; node.className = 'response-card'; node.id = 'response-card-' + count; if (node.addEventListener) { node.addEventListener("click", function(event) { var e = event.target || event.srcElement; if (e.style.backgroundColor != 'lightgray') { // select card // if e is a blank, show a write in field on click if (e.className == 'response-card') { if (e.innerHTML == '') { app.debug("blank card selected"); var writein = document.createElement('textarea'); writein.className = 'writein'; writein.id = e.id + '-writein'; writein.setAttribute('autofocus', 'true'); e.appendChild(writein); } app.ctx.selected_response_cards.push(e.id); e.style.backgroundColor = 'lightgray'; } } else { // unselect card var index = app.ctx.selected_response_cards.indexOf(e.id); app.ctx.selected_response_cards.splice(index, 1); e.style.backgroundColor = 'white'; } }); } else if (node.attachEvent) { node.attachEvent("onclick", function() { var e = event.target || event.srcElement; if (e.style.backgroundColor != 'lightgray') { app.ctx.selected_response_cards.push(e.id); e.style.backgroundColor = 'lightgray'; } else { var index = app.ctx.selected_response_cards.indexOf(e.id); app.ctx.selected_response_cards.splice(index, 1); e.style.backgroundColor = 'white'; } }); } element.appendChild(node); ++count; } show('submit_response'); break; case 'Start Scoring Round': // hide response cards var e = document.getElementById('response_cards'); while (e.firstChild) { e.removeChild(e.firstChild); } hide('end_play_round'); // show end scoring round button to host. if (app.ctx.host_id == app.ctx.player_id) show("end_scoring_round"); // show player responses to choose from and submit button e = document.getElementById('score_round'); var form = document.createElement('form'); form.id = 'scoring_form'; var legend = document.createElement('legend'); var legend_txt = document.createTextNode('Choose the best response'); legend.appendChild(legend_txt); var submit = document.createElement('button'); submit.innerText = 'Submit'; submit.id = 'score_response'; submit.onclick = function() { var f = document.getElementById('scoring_form'); var elements = document.getElementsByName('scoring'); var num_elements = elements.length; var count = 0; var selected_value = false; while (count < num_elements) { if (elements[count].checked) selected_value = elements[count].value; ++count; } if (selected_value != false) { app.debug('You selected ' + selected_value); response = {'type': 'Scoring Response', 'game_id': app.ctx.game_id, 'value': selected_value}; send(app.ctx.ws, response); //app.debug('Removing scoring round elements'); //var elem = document.getElementById('score_round'); //while (elem.hasChildNodes()) { // elem.removeChild(elem.lastChild); //} // hide('score_round'); hide('score_response'); } else app.log('You need to select a response'); }; var responses = response['value']; var len = responses.length; var count = 0; while (count < len) { var response = responses[count]; //alert(response); //alert(app.ctx.my_response); var in_element = document.createElement('INPUT'); in_element.setAttribute('type', 'radio'); in_element.name = 'scoring'; in_element.id = 'scoring-radiobutton-' + count; in_element.value = response; //responses[count]; var label_element = document.createElement('label'); if (response.toString() == app.ctx.my_response.toString()) { in_element.disabled = true; var label_element = document.createElement('label'); // label_element.style.color = '#B0B2B3'; label_element.style.color = '#929495'; } var response_string = ''; if (response.length > 1) { var index = 0; while (index < response.length) { response_string += response[index] + ' / ' ++index; } var rs_len = response_string.length; rs_len -= 3; response_string = response_string.substr(0, rs_len); } else response_string = response; label_element.innerHTML = ' ' + response_string + '

'; label_element.setAttribute('for', 'scoring-radiobutton-' + count); form.appendChild(in_element); form.appendChild(label_element); ++count; } e.appendChild(legend); e.appendChild(form); e.appendChild(submit); show('score_round'); // if (response['reader'] == app.ctx.player_id) // overlay_on(); break; case 'Scores': var total_scores = response['total']; var round_scores = response['round']; var round_responses = response['responses']; var keys = Object.keys(total_scores); var len = keys.length; var count = 0; // clear all round score table entries var table = document.getElementById('player_info'); var row_count = 0; var num_rows = table.rows.length; while (row_count < num_rows) { var row = table.rows[row_count]; var cell_count = 0; var num_cells = table.rows[row_count].cells.length; while (cell_count < num_cells) { var cell = table.rows[row_count].cells[cell_count]; if (cell.id.includes('_round')) { cell.innerHTML = ''; app.debug("cell is blank"); } ++cell_count; } ++row_count; } len = keys.length; count = 0; while (count < len) { var key = keys[count]; var value = total_scores[key]; app.debug('key:' + key + ' value:' + value); var element = document.getElementById(key + '_score'); // element.innerHTML = value + " Last round response: " + round_responses[key]; element.innerHTML = value; ++count; } keys = Object.keys(round_scores); len = keys.length; count = 0; while (count < len) { var key = keys[count]; var value = round_scores[key]; app.debug('key:' + key + ' value:' + value); var element = document.getElementById(key + '_round'); element.innerHTML = value; ++count; } keys = Object.keys(round_responses) len = keys.length; count = 0; while (count < len) { var key = keys[count]; var value = round_responses[key]; app.log('Last round, ' + key + ' responded with ' + value); ++count; } var elem = document.getElementById('score_round'); while (elem.hasChildNodes()) { elem.removeChild(elem.lastChild); } hide('score_round'); // hide('score_response'); break; case 'Score Response Received': app.log(response['value'] + ' picked a response.'); break; case 'Response Submitted': app.log(response['value'] + ' submitted a resposne.'); break; case 'Disconnect': app.remove_user_entry(response['value']); } } else app.debug("Unknown response " + response); }; function main(debug=false, host=document.location.host) { app.ctx.debug = debug; app.ctx.host = host; if (document.location.protocol == 'http:') app.ctx.ws_url = "ws://"; else app.ctx.ws_url = "wss://"; app.ctx.ws_url += app.ctx.host + "/cards/rpc/"; app.ctx.ws = connect(app.ctx.ws_url, app.log, app.handle_response); app.debug("App has started."); show("start_game"); };