hyperion/assets/webconfig/js/app/controllers/AppController.js

535 lines
20 KiB
JavaScript

/*global define */
define([
'lib/stapes', 'views/MainView', 'models/Settings', 'views/SettingsView', 'views/EffectsView', 'views/TransformView', 'data/ServerControl', 'api/Socket', 'api/Network'
], function (Stapes, MainView, Settings, SettingsView, EffectsView, TransformView, ServerControl, Socket, Network) {
'use strict';
var network = new Network();
return Stapes.subclass(/** @lends AppController.prototype */{
/**
* @type MainView
*/
mainView: null,
/**
* @type SettingsView
*/
settingsView: null,
/**
* @type EffectsView
*/
effectsView: null,
/**
* @type TransformView
*/
transformView: null,
/**
* @type Settings
*/
settings: null,
/**
* @type ServerControl
*/
serverControl: null,
color: {
r: 25,
g: 25,
b: 25
},
effects: [],
transform: {},
selectedServer: null,
/**
* @class AppController
* @constructs
*/
constructor: function () {
this.mainView = new MainView();
this.settingsView = new SettingsView();
this.effectsView = new EffectsView();
this.transformView = new TransformView();
this.settings = new Settings();
this.bindEventHandlers();
this.mainView.setColor(this.color);
if (!network.canDetectLocalAddress()) {
this.settingsView.enableDetectButton(false);
}
},
/**
* Do initialization
*/
init: function () {
this.settings.load();
},
/**
* @private
*/
bindEventHandlers: function () {
this.settings.on({
'loaded': function () {
var i;
for (i = 0; i < this.settings.servers.length; i++) {
if (this.settings.servers[i].selected) {
this.selectedServer = this.settings.servers[i];
break;
}
}
this.settingsView.fillServerList(this.settings.servers);
if (!this.selectedServer) {
this.gotoArea('settings');
} else {
this.connectToServer(this.selectedServer);
}
},
'error': function (message) {
this.showError(message);
},
'serverAdded': function (server) {
var i;
for (i = 0; i < this.settings.servers.length; i++) {
if (this.settings.servers[i].selected) {
this.selectedServer = this.settings.servers[i];
this.connectToServer(server);
break;
}
}
this.settingsView.fillServerList(this.settings.servers);
},
'serverChanged': function (server) {
var i;
for (i = 0; i < this.settings.servers.length; i++) {
if (this.settings.servers[i].selected) {
this.selectedServer = this.settings.servers[i];
this.connectToServer(server);
break;
}
}
this.settingsView.fillServerList(this.settings.servers);
this.connectToServer(server);
},
'serverRemoved': function () {
var i, removedSelected = true;
this.settingsView.fillServerList(this.settings.servers);
for (i = 0; i < this.settings.servers.length; i++) {
if (this.settings.servers[i].selected) {
removedSelected = false;
break;
}
}
if (removedSelected) {
this.selectedServer = null;
if (this.serverControl) {
this.serverControl.disconnect();
}
this.effectsView.clear();
this.transformView.clear();
}
}
}, this);
this.mainView.on({
'barClick': function (id) {
if (id !== 'settings') {
if (!this.selectedServer) {
this.showError('No server selected');
} else if (!this.serverControl) {
this.connectToServer(this.selectedServer);
}
}
this.gotoArea(id);
},
'colorChange': function (color) {
this.color = color;
if (!this.selectedServer) {
this.showError('No server selected');
} else if (!this.serverControl) {
this.connectToServer(this.selectedServer, function () {
this.serverControl.setColor(color, this.selectedServer.duration);
}.bind(this));
} else {
this.serverControl.setColor(color, this.selectedServer.duration);
}
},
'clear': function () {
if (!this.selectedServer) {
this.showError('No server selected');
} else if (!this.serverControl) {
this.connectToServer(this.selectedServer, function () {
this.serverControl.clear();
}.bind(this));
} else {
this.serverControl.clear();
}
},
'clearall': function () {
if (!this.selectedServer) {
this.showError('No server selected');
} else if (!this.serverControl) {
this.connectToServer(this.selectedServer, function () {
this.serverControl.clearall();
this.mainView.setColor({r: 0, g: 0, b: 0});
}.bind(this));
} else {
this.serverControl.clearall();
this.mainView.setColor({r: 0, g: 0, b: 0});
}
}
}, this);
this.settingsView.on({
'serverAdded': function (server) {
if (server.address && server.port) {
server.priority = server.priority || 50;
this.settings.addServer(server);
this.lockSettingsView(false);
} else {
this.showError('Invalid server data');
}
},
'serverAddCanceled': function () {
this.lockSettingsView(false);
this.settingsView.fillServerList(this.settings.servers);
},
'serverEditCanceled': function () {
this.lockSettingsView(false);
this.settingsView.fillServerList(this.settings.servers);
},
'serverSelected': function (index) {
this.lockSettingsView(false);
this.settings.setSelectedServer(index);
},
'serverRemoved': function (index) {
this.settings.removeServer(index);
},
'serverChanged': function (data) {
if (data.server.address && data.server.port) {
data.server.priority = data.server.priority || 50;
this.settings.updateServer(data.index, data.server);
this.lockSettingsView(false);
} else {
this.showError('Invalid server data');
}
},
'editServer': function (index) {
var server = this.settings.servers[index];
this.settingsView.editServer({index: index, server: server});
},
'durationChanged': function (value) {
this.settings.duration = value;
this.settings.save();
},
'detect': function () {
this.lockSettingsView(true);
this.settingsView.showWaiting(true);
this.searchForServer(function (server) {
this.settings.addServer(server);
}.bind(this), function () {
this.lockSettingsView(false);
this.settingsView.showWaiting(false);
}.bind(this));
}
}, this);
this.effectsView.on({
'effectSelected': function (effectId) {
if (!this.serverControl) {
this.connectToServer(this.selectedServer, function () {
this.serverControl.runEffect(this.effects[parseInt(effectId)]);
}.bind(this));
} else {
this.serverControl.runEffect(this.effects[parseInt(effectId)]);
}
}
}, this);
this.transformView.on({
'gamma': function (data) {
if (data.r) {
this.transform.gamma[0] = data.r;
} else if (data.g) {
this.transform.gamma[1] = data.g;
} else if (data.b) {
this.transform.gamma[2] = data.b;
}
if (this.serverControl) {
this.serverControl.setTransform(this.transform);
}
},
'whitelevel': function (data) {
if (data.r) {
this.transform.whitelevel[0] = data.r;
} else if (data.g) {
this.transform.whitelevel[1] = data.g;
} else if (data.b) {
this.transform.whitelevel[2] = data.b;
}
if (this.serverControl) {
this.serverControl.setTransform(this.transform);
}
},
'blacklevel': function (data) {
if (data.r) {
this.transform.blacklevel[0] = data.r;
} else if (data.g) {
this.transform.blacklevel[1] = data.g;
} else if (data.b) {
this.transform.blacklevel[2] = data.b;
}
if (this.serverControl) {
this.serverControl.setTransform(this.transform);
}
},
'threshold': function (data) {
if (data.r) {
this.transform.threshold[0] = data.r;
} else if (data.g) {
this.transform.threshold[1] = data.g;
} else if (data.b) {
this.transform.threshold[2] = data.b;
}
if (this.serverControl) {
this.serverControl.setTransform(this.transform);
}
},
'hsv': function (data) {
if (data.valueGain) {
this.transform.valueGain = data.valueGain;
} else if (data.saturationGain) {
this.transform.saturationGain = data.saturationGain;
}
if (this.serverControl) {
this.serverControl.setTransform(this.transform);
}
}
}, this);
},
/**
* @private
* @param id
*/
gotoArea: function (id) {
this.mainView.scrollToArea(id);
},
/**
* @private
* @param server
*/
connectToServer: function (server, onConnected) {
if (this.serverControl) {
if (this.serverControl.isConnecting()) {
return;
}
this.serverControl.off();
this.serverControl.disconnect();
this.transformView.clear();
this.effectsView.clear();
}
this.serverControl = new ServerControl(server, Socket);
this.serverControl.on({
connected: function () {
this.serverControl.getServerInfo();
},
serverInfo: function (info) {
var index;
if (!this.selectedServer.name || this.selectedServer.name.length === 0) {
this.selectedServer.name = info.hostname;
index = this.settings.indexOfServer(this.selectedServer);
this.settings.updateServer(index, this.selectedServer);
this.settingsView.fillServerList(this.settings.servers);
}
this.effects = info.effects;
this.transform = info.transform[0];
this.updateView();
this.showStatus('Connected to ' + this.selectedServer.name);
if (onConnected) {
onConnected();
}
},
error: function (message) {
this.serverControl = null;
this.showError(message);
}
}, this);
this.serverControl.connect();
},
/**
* @private
*/
updateView: function () {
var i, effects = [];
if (this.effects) {
for (i = 0; i < this.effects.length; i++) {
effects.push({id: i, name: this.effects[i].name});
}
}
this.effectsView.clear();
this.effectsView.fillList(effects);
this.transformView.clear();
this.transformView.fillList(this.transform);
},
/**
* Shows the error text
* @param {string} error - Error message
*/
showError: function (error) {
this.mainView.showError(error);
},
/**
* Shows a message
* @param {string} message - Text to show
*/
showStatus: function (message) {
this.mainView.showStatus(message);
},
/**
* @private
* @param lock
*/
lockSettingsView: function (lock) {
if (network.canDetectLocalAddress()) {
this.settingsView.enableDetectButton(!lock);
}
this.settingsView.lockList(lock);
},
/**
* @private
* @param onFound
* @param onEnd
*/
searchForServer: function (onFound, onEnd) {
network.getLocalInterfaces(function (ips) {
if (ips.length === 0) {
onEnd();
return;
}
function checkInterface (localInterfaceAddress, ciOnFinished) {
var index, ipParts, addr;
index = 1;
ipParts = localInterfaceAddress.split('.');
ipParts[3] = index;
addr = ipParts.join('.');
function checkAddressRange (startAddress, count, carOnFinished) {
var ipParts, i, addr, cbCounter = 0, last;
function checkAddress (address, port, caOnFinished) {
var server = new ServerControl({'address': address, 'port': port}, Socket);
server.on({
'error': function () {
server.disconnect();
caOnFinished();
},
'connected': function () {
server.getServerInfo();
},
'serverInfo': function (result) {
var serverInfo = {
'address': address,
'port': port,
'priority': 50
};
server.disconnect();
if (result.hostname) {
serverInfo.name = result.hostname;
}
caOnFinished(serverInfo);
}
});
server.connect();
}
function checkAddressDoneCb (serverInfo) {
var ipParts, nextAddr;
if (serverInfo && onFound) {
onFound(serverInfo);
}
cbCounter++;
if (cbCounter === count) {
ipParts = startAddress.split('.');
ipParts[3] = parseInt(ipParts[3]) + count;
nextAddr = ipParts.join('.');
carOnFinished(nextAddr);
}
}
ipParts = startAddress.split('.');
last = parseInt(ipParts[3]);
for (i = 0; i < count; i++) {
ipParts[3] = last + i;
addr = ipParts.join('.');
checkAddress(addr, 19444, checkAddressDoneCb);
}
}
function checkAddressRangeCb (nextAddr) {
var ipParts, count = 64, lastPart;
ipParts = nextAddr.split('.');
lastPart = parseInt(ipParts[3]);
if (lastPart === 255) {
ciOnFinished();
return;
} else if (lastPart + 64 > 254) {
count = 255 - lastPart;
}
checkAddressRange(nextAddr, count, checkAddressRangeCb);
}
// do search in chunks because the dispatcher used in the ios socket plugin can handle only 64 threads
checkAddressRange(addr, 64, checkAddressRangeCb);
}
function checkInterfaceCb () {
if (ips.length === 0) {
onEnd();
} else {
checkInterface(ips.pop(), checkInterfaceCb);
}
}
checkInterface(ips.pop(), checkInterfaceCb);
}.bind(this), function (error) {
this.showError(error);
}.bind(this));
}
});
});