define(["sugar-web/activity/activity", "sugar-web/graphics/radiobuttonsgroup", "sugar-web/graphics/presencepalette", "sugar-web/env", "sugar-web/graphics/icon", "sugar-web/datastore", "webL10n", "humane"], function (activity, radioButtonsGroup, presencepalette, env, icon, datastore, webL10n, humane) { var app; var presence=null; var isHost=false; var numberofplayers=0; var opponentuser=null; var levelRadio; var xoLogo = ']>'; var generateXOLogoWithColor = function(color) { var coloredLogo = xoLogo; coloredLogo = coloredLogo.replace("#010101", color.stroke) coloredLogo = coloredLogo.replace("#FFFFFF", color.fill) return "data:image/svg+xml;base64," + btoa(coloredLogo); } env.getEnvironment(function(err, environment) { currentenv=environment; // Set current language to Sugarizer var defaultLanguage = (typeof chrome != 'undefined' && chrome.app && chrome.app.runtime) ? chrome.i18n.getUILanguage() : navigator.language; var language = environment.user ? environment.user.language : defaultLanguage; webL10n.language.code = language; // Shared instances if (environment.sharedId) { console.log("Shared instance"); document.getElementById("level-easy-button").classList.remove('active'); document.getElementById("level-medium-button").classList.remove('active'); document.getElementById("level-hard-button").classList.remove('active'); document.getElementById("level-easy-button").setAttribute('disabled', 'disabled'); document.getElementById("level-easy-button").setAttribute('title', 'Not available in multiplayer'); document.getElementById("level-medium-button").setAttribute('disabled', 'disabled'); document.getElementById("level-medium-button").setAttribute('title', 'Not available in multiplayer'); document.getElementById("level-hard-button").setAttribute('disabled', 'disabled'); document.getElementById("level-hard-button").setAttribute('title', 'Not available in multiplayer'); document.getElementById("switch-player-button").setAttribute('disabled', 'disabled'); document.getElementById("switch-player-button").setAttribute('title', 'Only Host can do it'); document.getElementById("new-game-button").setAttribute('disabled', 'disabled'); document.getElementById("new-game-button").setAttribute('title', 'Only Host can do it'); presence = activity.getPresenceObject(function(error, network) { network.listSharedActivityUsers(environment.sharedId, function(users) { for (var i = 0 ; i < users.length ;i++) { if (users[i].networkId != network.getUserInfo().networkId) { opponentuser = users[i]; break; } } }); network.onDataReceived(enyo.bind(app, "onNetworkDataReceived")); network.onSharedActivityUserChanged(enyo.bind(app, "onNetworkUserChanged")); }); } }); // Manipulate the DOM only when it is ready. requirejs(['domReady!'], function (doc) { // Initialize the Sugar activity. activity.setup(); // Initialize buttons document.getElementById("new-game-button").onclick = function() { app.doRenew(); }; levelRadio = new radioButtonsGroup.RadioButtonsGroup([ document.getElementById("level-easy-button"), document.getElementById("level-medium-button"), document.getElementById("level-hard-button")] ); document.getElementById("switch-player-button").onclick = function() { app.switchPlayer(); if (presence) { presence.sendMessage(presence.getSharedInfo().id, { user: presence.getUserInfo(), action: "update", content: 0 }); } if(isHost) document.getElementById("switch-player-button").disabled = true; }; // Initialize the game app = new LOLGameApp({activity: activity}); app.load(); app.renderInto(document.getElementById("canvas")); // Link presence palette var palette = new presencepalette.PresencePalette(document.getElementById("network-button"), undefined); palette.addEventListener('shared', function() { palette.popDown(); console.log("Want to share"); presence = activity.getPresenceObject(function(error, network) { if (error) { console.log("Sharing error"); return; } network.createSharedActivity('org.olpc-france.LOLActivity', function(groupId) { console.log("Activity shared"); document.getElementById("level-easy-button").classList.remove('active'); document.getElementById("level-medium-button").classList.remove('active'); document.getElementById("level-hard-button").classList.remove('active'); document.getElementById("level-easy-button").setAttribute('disabled', 'disabled'); document.getElementById("level-easy-button").setAttribute('title', 'Not available in multiplayer'); document.getElementById("level-medium-button").setAttribute('disabled', 'disabled'); document.getElementById("level-medium-button").setAttribute('title', 'Not available in multiplayer'); document.getElementById("level-hard-button").setAttribute('disabled', 'disabled'); document.getElementById("level-hard-button").setAttribute('title', 'Not available in multiplayer'); isHost=true; app.drawBoard(); }); network.onDataReceived(enyo.bind(app, "onNetworkDataReceived")); network.onSharedActivityUserChanged(enyo.bind(app, "onNetworkUserChanged")); }); }); }); // Main app class enyo.kind({ name: "LOLGameApp", kind: enyo.Control, published: {size: 13, level: 1, count: 13, activity: null}, components: [ {classes: "playboard", components:[ {name: "player", classes: "player-image"}, {name: "box", classes: "lol-box", components: [ ]}, {name: "computer", classes: "computer-image"} ]}, {name: "playbutton", kind: "Image", src: "icons/play.png", classes: "play", ontap: "doPlay", showing: false}, {name: "endaudio", kind: "HTML5.Audio", preload: "auto", autobuffer: true, controlsbar: false}, {name: "endmessage", content: "", showing: false, classes: "end-message"} ], // Constructor create: function() { this.inherited(arguments); this.init(); }, // Init game init: function() { // Init game context this.game = new LOLGame(this.count); if (this.count > 0) this.player = this.game.getPlayer(); this.count = this.size; this.selectedCount = 0; // Initialize level document.getElementById("level-easy-button").classList.remove('active'); document.getElementById("level-medium-button").classList.remove('active'); document.getElementById("level-hard-button").classList.remove('active'); if (!presence) { if (this.level == 1) document.getElementById("level-easy-button").classList.add('active'); else if (this.level == 2) document.getElementById("level-medium-button").classList.add('active'); else if (this.level == 3) document.getElementById("level-hard-button").classList.add('active'); } }, // Render rendered: function() { this.inherited(arguments); // Draw board this.drawBoard(); }, // Redraw the board drawBoard: function() { // Clean board this.selectedCount = 0; var items = []; enyo.forEach(this.$.box.getControls(), function(item) { items.push(item); }); for (var i = 0 ; i < items.length ; i++) { items[i].destroy(); } // Redraw board for (var i = 0 ; i < this.game.getLength(); i++) { this.$.box.createComponent( { kind: "LOLItem", ontap: "selectItem" }, { owner: this } ).render(); } this.showCurrentPlayer(); document.getElementById("switch-player-button").disabled = (this.game.getLength() != this.size); // Test end condition if (this.game.endOfGame()) { if (!presence) { this.$.endmessage.addClass(this.game.getPlayer() != this.player ? "end-message-win" : "end-message-lost"); this.$.endmessage.removeClass(this.game.getPlayer() != this.player ? "end-message-lost" : "end-message-win"); } else { this.$.player.addClass("empty-image"); this.$.computer.addClass("empty-image"); this.$.computer.removeClass("oponent-image"); this.$.endmessage.removeClass("end-message-lost"); this.$.endmessage.addClass(this.game.getPlayer() != this.player ? "end-message-win" : "player-lost"); this.$.endmessage.removeClass(this.game.getPlayer() != this.player ? "player-lost" : "end-message-win"); } this.$.endaudio.setSrc(this.game.getPlayer() != this.player ? "audio/applause.ogg" : "audio/disappointed.ogg"); this.$.endaudio.play(); this.$.endmessage.show(); } this.$.endmessage.setShowing(this.game.endOfGame()); // Play for computer if (this.game.getPlayer() != this.player && !this.game.endOfGame()) { if (presence) { this.oponentPlay(); } else { this.computerPlay(); } } }, Stop: function() { var stopEvent = document.createEvent("CustomEvent"); stopEvent.initCustomEvent('activityStop', false, false, { 'cancelable': true }); var result = window.dispatchEvent(stopEvent); if (result) { activity.close(); } }, onNetworkDataReceived: function(msg) { if (presence.getUserInfo().networkId === msg.user.networkId) { return; } switch(msg.action){ case 'init': console.log("init"); this.game = new LOLGame(msg.content); this.game.reverse(); app.drawBoard(); opponentuser=msg.user; break; case 'update': console.log("update"); if (msg.content > 0) { this.doOpponent(msg.content); } else { this.game.reverse(); app.drawBoard(); } break; case 'exit': console.log("already two players"); if(msg.content == presence.getUserInfo().networkId){ app.Stop(); } break; } }, onNetworkUserChanged: function(msg) { var html = ""; humane.log(html + webL10n.get((msg.move == 1 ? "PlayerJoin":"PlayerLeave"),{user: msg.user.name})); console.log("User "+msg.user.name+" "+(msg.move == 1 ? "join": "leave")); if (msg.move != 1) return; if (isHost) { if (numberofplayers==0) { presence.sendMessage(presence.getSharedInfo().id, { user: presence.getUserInfo(), action: 'init', content: this.game.getLength() }); numberofplayers++; opponentuser = msg.user; } else { presence.sendMessage(presence.getSharedInfo().id, { user: presence.getUserInfo(), action: 'exit', content: msg.user.networkId }); } } }, // Get current level getLevel: function() { var buttons = ["level-easy-button","level-medium-button","level-hard-button"]; console.log(buttons.indexOf(levelRadio.getActive().id)+1); return buttons.indexOf(levelRadio.getActive().id)+1; }, // Show the current player turn showCurrentPlayer: function() { if (this.player == this.game.getPlayer() && !this.game.endOfGame()) { this.$.player.removeClass("empty-image"); if (this.$.player.hasNode()) icon.colorize(this.$.player.hasNode(), currentenv.user.colorvalue, function() {}); } else this.$.player.addClass("empty-image"); if (this.player != this.game.getPlayer() && !this.game.endOfGame()) this.$.computer.removeClass("empty-image"); else this.$.computer.addClass("empty-image"); }, // Select an item selectItem: function(item) { if (this.player != this.game.getPlayer()) return; var value = item.getSelected(); if (this.selectedCount == 3 && !value) { this.$.playbutton.show(); return; } this.selectedCount = !value ? this.selectedCount + 1 : this.selectedCount - 1; item.setSelected(!value); if (this.selectedCount > 0) this.$.playbutton.show(); else this.$.playbutton.hide(); }, // Switch player switchPlayer: function() { this.game.reverse(); this.player = this.player % 2; this.drawBoard(); }, // Play for the player doPlay: function() { if (this.player != this.game.getPlayer()) return; if (this.selectedCount == 0) return; this.save(this.game.play(this.selectedCount)); if (presence) { presence.sendMessage(presence.getSharedInfo().id, { user: presence.getUserInfo(), action: "update", content: this.selectedCount }); } this.drawBoard(); this.$.playbutton.hide(); }, oponentPlay: function() { if (this.player == this.game.getPlayer() && !this.game.endOfGame()) { this.$.player.removeClass("empty-image"); icon.colorize(this.$.player.hasNode(), currentenv.user.colorvalue, function() {}); } else { this.$.player.addClass("empty-image"); } if (this.player != this.game.getPlayer() && !this.game.endOfGame()){ this.$.computer.removeClass("empty-image"); this.$.computer.addClass("oponent-image"); if (opponentuser) icon.colorize(this.$.computer.hasNode(), opponentuser.colorvalue, function() {}) }else this.$.computer.addClass("empty-image"); }, // Let's computer play computerPlay: function() { if (this.player == this.game.getPlayer()) return; this.selectedCount = 0; this.step = 0; this.timer = window.setInterval(enyo.bind(this, "doComputer"), 400+50*this.getLevel()); }, // Play for the computer doComputer: function() { // First, think to the shot and select item if (this.step == 0) { this.step++; var shot = this.game.think(this.getLevel()); var context = this; enyo.forEach(this.$.box.getControls(), function(item) { if (context.selectedCount < shot) { item.setSelected(true); context.selectedCount++; } }); this.step++; } // Then play else if (this.step == 2) { window.clearInterval(this.timer); this.save(this.game.play(this.selectedCount)); this.drawBoard(); } }, // Play opponent doOpponent: function(shot) { var that = this; enyo.forEach(this.$.box.getControls(), function(item) { if (that.selectedCount < shot) { item.setSelected(true); that.selectedCount++; } }); window.setTimeout(function() { that.game.play(shot); that.drawBoard(); }, 400); }, // Start a new game doRenew: function() { this.level = this.getLevel(); this.game = new LOLGame(this.count); this.init(); this.drawBoard(); if (presence&&isHost) { presence.sendMessage(presence.getSharedInfo().id, { user: presence.getUserInfo(), action: 'init', content: this.game.getLength() }); } }, // Load game from datastore load: function() { var datastoreObject = this.activity.getDatastoreObject(); var currentthis = this; datastoreObject.loadAsText(function (error, metadata, data) { var data = JSON.parse(data); if (data == null) return; currentthis.size = data.size; currentthis.count = data.count; currentthis.level = data.level; currentthis.player = data.player; currentthis.init(); }); }, // Save game in datastore save: function(count) { var datastoreObject = this.activity.getDatastoreObject(); var jsonData = JSON.stringify({size: this.size, count: count, level: this.getLevel(), player: this.game.getPlayer()}); datastoreObject.setDataAsText(jsonData); datastoreObject.save(function() {}); } }); // Class for an item enyo.kind({ name: "LOLItem", kind: enyo.Control, classes: "lol-item", published: { selected: false }, // Constructor create: function() { this.inherited(arguments); this.selectedChanged(); }, // Selection changed selectedChanged: function() { var className = "lol-item-selected"; if (this.selected) { this.addClass(className); this.applyStyle("background-color", currentenv.user.colorvalue.stroke); } else { this.removeClass(className); this.applyStyle("background-color", currentenv.user.colorvalue.fill); } }, }); });