var produceEvent = document.getElementById('produce-event');
var pending = document.getElementById('pending');
var inProgress = document.getElementById('in-progress');
var done = document.getElementById('done');

var inProgressCount = 0;

var events$ = Rx.Observable.fromEvent(produceEvent, 'click')
  .do(({timeStamp}) => updatePanelAppend(pending, Math.floor(timeStamp*1000)));

var inProgress$ = events$;

var done$ = inProgress$
  .flatMap(({timeStamp}) => 
                            Rx.Observable.defer(() => {
                              updatePanelAppend(inProgress, Math.floor(timeStamp*1000));
                              removeFromPanel(pending, Math.floor(timeStamp*1000));
                              return expensiveComputation(getRandomInt(1, 5) * 1000, Math.floor(timeStamp*1000));
                           }), 1);

done$.subscribe((timeStamp) => {
  updatePanelAppend(done, timeStamp);
  removeFromPanel(inProgress, timeStamp);
});

function updatePanelAppend(panelEl, newContent) {
  var newDiv = document.createElement('div');
  newDiv.id = '_' + newContent;
  newDiv.textContent = newContent + ',';
  panelEl.appendChild(newDiv);
}

function removeFromPanel(panelEl, timeStamp) {
  var el = panelEl.querySelector('#_' + timeStamp);
  panelEl.removeChild(el);
}

/**
* Simulate an expensive function that returns a promise
**/
function expensiveComputation(time, result) {
  console.log('expensiveComputation for:' + result);
  if (!time) {
    time = 1000;
  }  
  return Q.delay(time).then(()=> result);    
}

function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}