const socketio = require('socket.io');
const utils = require('./utils');
const eth = require('./eth');

const web3 = eth.web3;
const SpiceMembers = eth.contracts.SpiceMembers;
const SpiceHours = eth.contracts.SpiceHours;

const pendingTransactions = {};

function handleTransaction(io, name, tx) {
  if (!name) return; // No name, send nothing

  const timeout = 240000;
  const start = new Date().getTime();

  if (!tx.blockNumber) {
    io.emit(name + '/pending', JSON.stringify(tx));
    pendingTransactions[tx.hash] = tx;
  }

  function sendAfterReceipt() {
    web3.eth.getTransactionReceipt(tx.hash, (err, receipt) => {
      if (err) return io.emit('error', err.message);

      if (receipt) {
        delete pendingTransactions[tx.hash];
        web3.eth.getTransaction(tx.hash, (err, tx) => {
          if (err) return io.emit('error', err.message);
          io.emit(name + '/tx', JSON.stringify(tx));
          io.emit(name + '/receipt', JSON.stringify(receipt));
        });
      } else if (timeout > 0 && new Date().getTime() - start > timeout) {
        io.emit('error', `Transaction ${tx.hash} wasn't processed in ${timeout / 1000} seconds`);
      } else {
        setTimeout(sendAfterReceipt, 200);
      }
    });
  }

  sendAfterReceipt();
}

function attachTransactions(io, addresses) {
  const pendingFilter = web3.eth.filter('pending');
  pendingFilter.watch((err, txid) =>
    web3.eth.getTransaction(txid, (err, tx) => {
      handleTransaction(io, addresses[tx.to], tx);
    })
  );
  return pendingFilter;
}

function attachEvent(io, name, event, proc) {
  const eventFilter = event();
  eventFilter.watch((err, event) => {
    if (err) return io.emit('error', err.message);
    if (proc) event = proc(event);
    io.emit(name + '/event', JSON.stringify(event));
  });
  return eventFilter;
}

function processEvent(event) {
  const args = event.args;
  if (args) {
    if (args.info) args.info = utils.decryptInfo(args.info);
    args.description = utils.bytes32ToStr(args.description);
  }
  return event;
}

function attach(io) {
  const addresses = {
    [SpiceMembers.address]: 'members',
    [SpiceHours.address]: 'hours'
  };
  attachTransactions(io, addresses);

  const hours = SpiceHours.deployed();
  attachEvent(io, 'hours', hours.MarkHours, processEvent);
  attachEvent(io, 'hours', hours.ProcessPayroll, processEvent);
}

exports.pending = pendingTransactions;
exports.attach = attach;

@@ -213,16 +213,61 @@
 ceHours;
+%0Aconst SpiceRates = eth.contracts.SpiceRates;
 %0A%0Aconst 
@@ -340,55 +340,8 @@
 ) %7B%0A
-  if (!name) return; // No name, send nothing%0A%0A
   co
@@ -358,13 +358,8 @@
 t = 
-24000
 0;%0A 
@@ -1263,267 +1263,522 @@
 ion 
-attachTransactions(io, addresses) %7B%0A  const pendingFilter = web3.eth.filter('pending');%0A  pendingFilter.watch((err, txid) =%3E%0A    web3.eth.getTransaction(txid, (err, tx) =%3E %7B%0A      handleTransaction(io, addresses%5Btx.to%5D, tx);%0A    %7D)%0A  );%0A  return pendingFilter
+findContract(contracts, address) %7B%0A  return Object.keys(contracts)%0A    .map(name =%3E %5Bname, contracts%5Bname%5D%5D)%0A    .find((%5Bname, contract%5D) =%3E (address == contract.address));%0A%7D%0A%0Afunction attachTransactions(io, contracts) %7B%0A  const pendingFilter = web3.eth.filter('pending');%0A  pendingFilter.watch((err, txid) =%3E%0A    web3.eth.getTransaction(txid, (err, tx) =%3E %7B%0A      const contractInfo = findContract(contracts, tx.to);%0A      if (contractInfo) %7B%0A        handleTransaction(io, contractInfo%5B0%5D, tx);%0A      %7D%0A    %7D)%0A  )
 ;%0A%7D%0A
@@ -1794,24 +1794,25 @@
  attachEvent
+s
 (io, name, e
@@ -1815,16 +1815,22 @@
 e, event
+Filter
 , proc) 
@@ -1835,39 +1835,8 @@
 ) %7B%0A
-  const eventFilter = event();%0A
   ev
@@ -2018,30 +2018,8 @@
 %7D);%0A
-  return eventFilter;%0A
 %7D%0A%0Af
@@ -2264,24 +2264,24 @@
   const 
-addresse
+contract
 s = %7B%0A  
@@ -2286,48 +2286,42 @@
     
-%5BSpiceMembers.address%5D: 'm
+members: SpiceM
 embers
-'
 ,%0A    
-%5B
+hours: 
 Spic
@@ -2330,26 +2330,31 @@
 ours
-.address%5D: 'hours'
+,%0A    rates: SpiceRates
 %0A  %7D
@@ -2384,16 +2384,16 @@
 io, 
-addresse
+contract
 s);%0A
@@ -2437,32 +2437,33 @@
 );%0A  attachEvent
+s
 (io, 'hours', ho
@@ -2470,17 +2470,19 @@
 urs.
-MarkHours
+allEvents()
 , pr
@@ -2493,16 +2493,56 @@
 sEvent);
+%0A%0A  const rates = SpiceRates.deployed();
 %0A  attac
@@ -2551,42 +2551,40 @@
 vent
+s
 (io, '
-hours', hours.ProcessPayroll
+rates', rates.allEvents()
 , pr

Modify eventapi transaction handling, should rewrite event handling.