/******************************************************************************
* Sheet implementation
* ***************************************************************************/
/**
* Constructs a sheet
* @param context {object} a context object
* @class
* @classdesc A Sheet is an operationnal configuration in an application. It
* contains many things: multiple sets of {@link ARCS.Invocation}
* performed at different times
* and a set of {@link ARCS.Connection}. Sheets have two high level operations:
* activation and deactivation.
*/
ARCS.Sheet = function (context) {
//var context = ctx;
var preconnections = [], postconnections = [], cleanups = [], connections = [],
invokePreconnections, invokePostconnections, invokeCleanups,
connect, disconnect, getComponentName,
preCount = 0, postCount = 0, cleanCount = 0, connCount = 0;
invokePreconnections = function () {
var i;
for (i = 0; i < preconnections.length; i++) {
preconnections[i].invoke();
}
};
invokePostconnections = function () {
var i;
for (i = 0; i < postconnections.length; i++) {
postconnections[i].invoke();
}
};
invokeCleanups = function () {
var i;
for (i = 0; i < cleanups.length; i++) {
cleanups[i].invoke();
}
};
connect = function () {
var i;
for (i = 0; i < connections.length; i++) {
connections[i].connect();
}
};
disconnect = function () {
var i;
for (i = 0; i < connections.length; i++) {
connections[i].disconnect();
}
};
this.setContext = function (ctx) {
context = ctx;
};
/**
* Activates this sheet. Pre-connection invocations are peformed, then
* connections are established and post-connection invocations are finally
* performed.
*/
this.activate = function () {
invokePreconnections();
connect();
invokePostconnections();
};
/**
* Deactivates this sheet. Connections are removed and then cleanup invocations
* are performed.
*/
this.deactivate = function () {
disconnect();
invokeCleanups();
};
this.addPreConnection = function (obj) {
var pre = ARCS.Invocation.cast(obj, context);
pre.id = preCount++;
preconnections.push(pre);
return pre.id;
};
this.addPostConnection = function (obj) {
var post = ARCS.Invocation.cast(obj, context);
post.id = postCount++;
postconnections.push(post);
return post.id;
};
this.addCleanup = function (obj) {
var cleanup = ARCS.Invocation.cast(obj, context);
cleanup.id = cleanCount++;
cleanups.push(cleanup);
return cleanup.id;
};
this.addConnection = function (obj) {
var connection = ARCS.Connection.cast(obj, context);
connection.id = connCount++;
connections.push(connection);
return connection.id;
};
var removeItem = function(id, tab) {
var i = tab.length;
while ( i-- && tab[i].id !== id );
if (i >= 0) {
tab.splice(i,1);
} else {
console.warn("Could not remove data with id", id);
}
};
this.removePreConnection = function (id) {
removeItem(id, preconnections);
};
this.removePostConnection = function (id) {
removeItem(id, postconnections);
};
this.removeCleanup = function (id) {
removeItem(id, cleanups);
};
var changeItem = function(id, value, tab) {
var i = tab.length;
while ( i-- && tab[i].id !== id );
if (i >= 0) {
tab[i].value = value;
}
};
this.changePreConnection = function (id, value) {
changeItem(id, value, preconnections);
};
this.changePostConnection = function (id, value) {
changeItem(id, value, postconnections);
};
this.changeCleanup = function (id, value) {
changeItem(id, value, cleanups);
};
this.removeConnection = function (id) {
removeItem(id, connections);
};
var swapItems = function (id1, id2, tab) {
var item;
var i = tab.length, j = tab.length;
while( i-- && tab[i].id !== id1 ) ;
while( j-- && tab[j].id !== id2 ) ;
if (i >= 0 && j >= 0) {
item = tab[i];
tab[i] = tab[j];
tab[j] = item;
tab[i].id = id1;
tab[j].id = id2;
}
};
this.swapConnections = function (id1, id2) {
swapItems(id1, id2, connections);
};
this.swapCleanups = function (id1, id2) {
swapItems(id1, id2, cleanups);
};
this.swapPreConnections = function (id1, id2) {
swapItems(id1, id2, preconnections);
};
this.swapPostConnections = function (id1, id2) {
swapItems(id1, id2, postconnections);
};
/**
* Imports a structure object describing the content of a sheet.
* @param object {object} structured object describing sheet's content.
*/
this.import = function (object) {
var i = 0, castInvocation = ARCS.Invocation.cast, castConnection = ARCS.Connection.cast;
for (i = 0; i < object.preconnections.length; i++) {
preconnections.push(castInvocation(object.preconnections[i], context));
}
for (i = 0; i < object.postconnections.length; i++) {
postconnections.push(castInvocation(object.postconnections[i], context));
}
for (i = 0; i < object.cleanups.length; i++) {
cleanups.push(castInvocation(object.cleanups[i], context));
}
for (i = 0; i < object.connections.length; i++) {
connections.push(castConnection(object.connections[i], context));
}
};
var revertInvocation = function (obj) {
return {
destination: context.getComponentName(obj.getDestination()),
slot: obj.getSlot(),
value: obj.getValue()
};
};
var revertConnection = function (obj) {
return {
source: context.getComponentName(obj.getSource()),
signal: obj.getSignal(),
destination: context.getComponentName(obj.getDestination()),
slot: obj.getSlot()
};
};
this.toJSON = function () {
var preconns = [];
var postconns = [];
var conns = [];
var cleans = [];
var i;
for (i = 0; i < connections.length; i++) {
conns.push(revertConnection(connections[i]))
}
for (i = 0; i < preconnections.length; i++) {
preconns.push(revertInvocation(preconnections[i]))
}
for (i = 0; i < postconnections.length; i++) {
postconns.push(revertInvocation(postconnections[i]))
}
for (i = 0; i < cleanups.length; i++) {
cleans.push(revertInvocation(cleanups[i]))
}
return {
preconnections : preconns,
postconnections : postconns,
connections: conns,
cleanups: cleans
};
};
};