1 var nowUtil = require('./nowUtil').nowUtil;
  2 
  3 exports.initialize = function (nowjs) {
  4   function multicall(group, fqn, args) {
  5     var user, func;
  6     for (var i = 0, k = Object.keys(group.users), l = k.length; i < l; i++) {
  7       user = group.users[k[i]];
  8       if (group.excludes[user.user.clientId]) {
  9         continue;
 10       }
 11       func = user.get(fqn);
 12       user = nowUtil.clone(user, {fqn: fqn});
 13 
 14       // Call the function with group.now and group.user
 15       if (typeof func === 'function') {
 16         func.apply(user, args);
 17       } else {
 18         // err
 19       }
 20     }
 21   }
 22 
 23   function replaceVar(group, fqn, val) {
 24     var exclusive = false;
 25     for (var j in group.excludes) {
 26       if (group.excludes[j]) {
 27         exclusive = true;
 28         break;
 29       }
 30     }
 31     var users = Object.keys(group.users);
 32     var i = 0, ll = users.length;
 33     var toSend = {},
 34     flattenedVal = {},
 35     fqns,
 36     user;
 37 
 38     // Setup: generate flattenedVal and toSend.
 39     if (val && typeof val === 'object') {
 40       flattenedVal = nowUtil.flatten(val, fqn);
 41       fqns = Object.keys(flattenedVal);
 42       // Iterate through all leaves.
 43       for (i = 0, ll = fqns.length; i < ll; i++) {
 44         toSend[fqns[i]] = nowUtil.getValOrFqn(flattenedVal[fqns[i]], fqns[i]);
 45       }
 46     } else {
 47       // val is not an object.
 48       fqns = [fqn];
 49       toSend[fqn] = nowUtil.getValOrFqn(val, fqn);
 50       flattenedVal[fqn] = val;
 51     }
 52 
 53     var ff = fqns.length, k;
 54     if (exclusive) {
 55       for (i = 0, ll = users.length; i < ll; i++) {
 56         user = group.users[users[i]];
 57         if (group.excludes[user.user.clientId]) {
 58           continue;
 59         }
 60         // Clear the user's scopeTable entry before setting the new
 61         // value.
 62         user.deleteVar(fqn);
 63         user.socket.emit('rv', toSend);
 64 
 65         if (ff === 0) {
 66           group.scopeTable.set(fqn, []);
 67         }
 68 
 69         for (k = 0; k < ff; k++) {
 70           // Set values for individual users.
 71           user.scopeTable.set(fqns[k], flattenedVal[fqns[k]]);
 72         }
 73       }
 74       return;
 75     } else {
 76       // Not an exclusive group.
 77       group.deleteVar(fqn);
 78       for (k = 0; k < ff; k++) {
 79         // Set values for the group.
 80         group.scopeTable.set(fqns[k], flattenedVal[fqns[k]]);
 81       }
 82       if (ff === 0) {
 83         group.scopeTable.set(fqn, []);
 84         toSend[fqn] = {};
 85       }
 86       // Invalidate the value in the group's users' scopeTables
 87       for (i = 0, ll = users.length; i < ll; i++) {
 88         user = group.users[users[i]];
 89         user.scopeTable.deleteVar(fqn);
 90         user.socket.emit('rv', toSend);
 91       }
 92     }
 93 
 94     // If e is `everyone`, invalidate the values in the lesser groups
 95     if (group.isSuperGroup) {
 96       var groups = Object.keys(nowjs.groups);
 97       if (groups[0] === 'everyone') {
 98         for (i = 1, ll = groups.length; i < ll; i++) {
 99           // everyone is guaranteed to be the first group in keys.
100           group = nowjs.groups[groups[i]];
101           group.scopeTable.deleteVar(fqn);
102         }
103       } else {
104         // stupid people, using numbers as group names...
105         for (i = 0, ll = groups.length; i < ll; i++) {
106           if (groups[i] !== 'everyone') {
107             group = nowjs.groups[groups[i]];
108             group.scopeTable.deleteVar(fqn);
109           }
110         }
111       }
112     }
113   }
114 
115   function deleteVar(group, fqn) {
116     var keys = Object.keys(group.users);
117     var user;
118     for (var i = 0, ll = keys.length; i < ll; i++) {
119       user = group.users[keys[i]];
120       // Only send to users who haven't overwritten the value at the
121       // provided fqn.
122       if (user.scopeTable[fqn] === undefined) {
123         user.socket.emit('del', fqn);
124       }
125     }
126     group.scopeTable.deleteVar(fqn);
127   }
128 
129 
130   nowjs.on('multicall', function (e, args) {
131     multicall(e, e.fqn, args);
132   });
133 
134   nowjs.on('grouprv', function (e) {
135     replaceVar(e, e.fqn, e.val);
136   });
137 
138   nowjs.on('groupdel', function (e) {
139     deleteVar(e, e.fqn);
140   });
141 
142   nowjs.on('removegroup', function (arg) {
143     var name = arg;
144     //if (nowUtil.hasProperty(this.groups, name) || true) {
145       var self = this;
146       // Get the actual group
147       group = this.getGroup(name);
148       group.getUsers(function(users){
149         users.map(function(user){
150           group.removeUser(user);  
151         });
152       });
153       // Finally, delete the group itself.
154       delete this.groups[name];
155     
156   });
157 };
158