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);
}
},
});
});