/* globals $,$SERVICE_URL,SERVICES */

var setTileHealth = function(tile, health) {
  tile.removeClass('tile-ok tile-error');
  if (health === 'ok') {
    tile.addClass('tile-ok');
  } else if (health === 'error') {
    tile.addClass('tile-error');
  }
};

var updateCommit = function(element, data) {
  ['author', 'committed', 'message'].forEach(function (attr) {
    element.children('.' + attr).text(data[attr]);
  });
};

var updateItems = function(pane, items, selector, updater) {
  var elements = pane.children(selector);
  items.slice(0, 4).forEach(function (item, index) {
    updater(elements.eq(index), item);
  });
};

var updateOutcome = function(element, data) {
  element.removeClass('passed failed crashed cancelled working');
  element.addClass(data.outcome);
  ['author', 'elapsed', 'message', 'outcome'].forEach(function (attr) {
    element.children('.' + attr).text(data[attr]);
  });
};

var processPayload = function (payload) {
  for (var key in payload) {
    if (payload.hasOwnProperty(key)) {
      var data = payload[key];
      var tile = $('#' + key);
      var pane = tile.children('.pane').first();
      var serviceHandler = SERVICES[data.service_name];

      setTileHealth(tile, data.health || 'neutral');
      tile.find('.service-caption > .project-name').first().text(data.name);

      if (serviceHandler && data) {
        serviceHandler(pane, data);
      }
    }
  }
};

var updateServices = function() {
  $.getJSON($SERVICE_URL, function (payload) {
    if (payload) {
      console.info('received', payload);
      processPayload(payload);
    }
  });
};

/**
* bundleService puts tiles of the same kind into a wrapper element and animates the transition.
* bundleService as well as bundleServices could be nicely encapsulated in a jquery plugin.
*/
var bundleService = function (serviceSelector, interval) {
  console.log('bundle ', serviceSelector);
  var active = 0;
  var stacked = [];
  var wrapper = bundle(serviceSelector);

  function bundle(selector) {
    var tiles = $(selector).remove();
    var wrapper = $('<div class="tiles-stack"></div>');

    tiles.each(function (index, obj) {
      stacked[index] = $(obj);
      stacked[index].append('<div class="tiles-count">' + (index + 1) + ' of ' + tiles.length+ '</div>');
      wrapper.append(stacked[index]);
    });
    $('.dashboard').append(wrapper);

    return wrapper;
  }

  function updateStacked() {
    if (stacked.length === 0) return;
    var currentActive = active++ % stacked.length;
    wrapper.children().hide();

    stacked[currentActive]
      .show()
      .effect('shake', {distance: 10, times: 3});
  }

  updateStacked();
  setInterval(updateStacked, interval)
};

/**
* bundleServices goes over all tiles and finds tiles of the same kind > 1
* The order ot the tiles changes at the moment, tiles with more than one tile
* are appended to the end.
*/
function bundleServices() {
  var serviceTiles = $('.service-tile');
  var cssClassTotals = {};

  serviceTiles.each(function (index, obj) {
    $(obj).attr('class').match(/.*-tile/)[0].split(/\s+/).forEach(function (cssClass) {
      if (cssClass === 'service-tile') { return; }
      if (!cssClassTotals[cssClass]) { cssClassTotals[cssClass] = 0; }
      cssClassTotals[cssClass] += 1;
    });
  });

  for (var cssClass in cssClassTotals) {
    if (cssClassTotals.hasOwnProperty(cssClass)) {
      if (cssClassTotals[cssClass] > 1) {
        var cssSelector = '.' + cssClass;
        bundleService(cssSelector, 10000);
      }
    }
  }
}

$(document).ready(function () {
  bundleServices();
  updateServices();
  setInterval(updateServices, 60000);
});

@@ -32,19 +32,24 @@
 CES */%0A%0A
-var
+function
  setTile
@@ -54,27 +54,16 @@
 leHealth
- = function
 (tile, h
@@ -237,30 +237,34 @@
 ror');%0A  %7D%0A%7D
-;
 %0A%0A
-var
+function
  updateCommi
@@ -264,27 +264,16 @@
 teCommit
- = function
 (element
@@ -399,30 +399,34 @@
 r%5D);%0A  %7D);%0A%7D
-;
 %0A%0A
-var
+function
  updateItems
@@ -425,27 +425,16 @@
 ateItems
- = function
 (pane, i
@@ -601,22 +601,26 @@
 %0A  %7D);%0A%7D
-;
 %0A%0A
-var
+function
  updateO
@@ -625,27 +625,16 @@
 eOutcome
- = function
 (element
@@ -873,22 +873,26 @@
 %0A  %7D);%0A%7D
-;
 %0A%0A
-var
+function
  process
@@ -898,28 +898,16 @@
 sPayload
- = function 
 (payload
@@ -1372,14 +1372,18 @@
  %7D%0A%7D
-;
 %0A%0A
-var
+function
  upd
@@ -1393,27 +1393,16 @@
 Services
- = function
 () %7B%0A  $
@@ -1549,17 +1549,16 @@
 %0A  %7D);%0A%7D
-;
 %0A%0A/**%0A* 
@@ -1745,19 +1745,24 @@
 gin.%0A*/%0A
-var
+function
  bundleS
@@ -1771,20 +1771,8 @@
 vice
- = function 
 (ser
@@ -1895,34 +1895,8 @@
 pper
- = bundle(serviceSelector)
 ;%0A%0A 
@@ -2304,16 +2304,54 @@
 r;%0A  %7D%0A%0A
+  wrapper = bundle(serviceSelector);%0A%0A
   functi
@@ -2400,24 +2400,26 @@
 h === 0)
+ %7B
  return;
 %0A    var
@@ -2410,16 +2410,18 @@
  return;
+ %7D
 %0A    var
@@ -2653,11 +2653,11 @@
 val)
+;
 %0A%7D
-;
 %0A%0A/*

Improve JS styling and layout