// Copyright 2014 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

function D3BlobTreeMap(mapWidth, mapHeight, levelsToShow) {
  this._mapContainer = undefined;
  this._mapWidth = mapWidth;
  this._mapHeight = mapHeight;
  this.boxPadding = {'l': 5, 'r': 5, 't': 20, 'b': 5};
  this.infobox = undefined;
  this._maskContainer = undefined;
  this._highlightContainer = undefined;
  // Transition in this order:
  // 1. Exiting items go away.
  // 2. Updated items move.
  // 3. New items enter.
  this._exitDuration=500;
  this._updateDuration=500;
  this._enterDuration=500;
  this._firstTransition=true;
  this._layout = undefined;
  this._currentRoot = undefined;
  this._currentNodes = undefined;
  this._treeData = undefined;
  this._maxLevelsToShow = levelsToShow;
  this._currentMaxDepth = this._maxLevelsToShow;
}

/**
 * Make a number pretty, with comma separators.
 */
D3BlobTreeMap._pretty = function(num) {
  var asString = String(num);
  var result = '';
  var counter = 0;
  for (var x = asString.length - 1; x >= 0; x--) {
    counter++;
    if (counter === 4) {
      result = ',' + result;
      counter = 1;
    }
    result = asString.charAt(x) + result;
  }
  return result;
}

/**
 * Express a number in terms of KiB, MiB, GiB, etc.
 * Note that these are powers of 2, not of 10.
 */
D3BlobTreeMap._byteify = function(num) {
  var suffix;
  if (num >= 1024) {
    if (num >= 1024 * 1024 * 1024) {
      suffix = 'GiB';
      num = num / (1024 * 1024 * 1024);
    } else if (num >= 1024 * 1024) {
      suffix = 'MiB';
      num = num / (1024 * 1024);
    } else if (num >= 1024) {
      suffix = 'KiB'
      num = num / 1024;
    }
    return num.toFixed(2) + ' ' + suffix;
  }
  return num + ' B';
}

D3BlobTreeMap._BLOB_TYPE_DESCRIPTIONS = {
  'dart': 'Shared Dart',
  '?': 'Shared Unrecognized',
  'unique': 'Unique',
  'uniDart': 'Unique Dart',
};
D3BlobTreeMap._BLOB_TYPES = [];
for (var blob_type in D3BlobTreeMap._BLOB_TYPE_DESCRIPTIONS) {
  D3BlobTreeMap._BLOB_TYPES.push(blob_type);
}

/**
 * Given a blob type code, look up and return a human-readable description
 * of that blob type. If the blob type does not match one of the known
 * types, the unrecognized description (corresponding to blob type '?') is
 * returned instead of null or undefined.
 */
D3BlobTreeMap._getblobDescription = function(type) {
  var result = D3BlobTreeMap._BLOB_TYPE_DESCRIPTIONS[type];
  if (result === undefined) {
    result = D3BlobTreeMap._BLOB_TYPE_DESCRIPTIONS['?'];
  }
  return result;
}

D3BlobTreeMap._colorArray = [
  'rgb(148,116,204)',  // Shared Dart - Deep Purple 300
  'rgb(255,213,79)',  // Unique - Amber 300
  'rgb(77,208,225)',  // Shared Other - Cyan 300
  'rgb(161,136,127)', // Unique Dart - Brown 300
];

D3BlobTreeMap._initColorMap = function() {
  var map = {};
  var numColors = D3BlobTreeMap._colorArray.length;
  var count = 0;
  for (var key in D3BlobTreeMap._BLOB_TYPE_DESCRIPTIONS) {
    var index = count++ % numColors;
    map[key] = d3.rgb(D3BlobTreeMap._colorArray[index]);
  }
  D3BlobTreeMap._colorMap = map;
}
D3BlobTreeMap._initColorMap();

D3BlobTreeMap.getColorForType = function(type) {
  var result = D3BlobTreeMap._colorMap[type];
  if (result === undefined) return d3.rgb('rgb(255,255,255)');
  return result;
}

D3BlobTreeMap.prototype.init = function() {
  this.infobox = this._createInfoBox();
  this._mapContainer = d3.select('body').append('div')
      .style('position', 'relative')
      .style('width', this._mapWidth)
      .style('height', this._mapHeight)
      .style('padding', 0)
      .style('margin', 0)
      .style('box-shadow', '5px 5px 5px #888');
  this._layout = this._createTreeMapLayout();
  this._setData(tree_data); // TODO: Don't use global 'tree_data'
}

/**
 * Sets the data displayed by the treemap and lays out the map.
 */
D3BlobTreeMap.prototype._setData = function(data) {
  this._treeData = data;
  console.time('_crunchStats');
  this._crunchStats(data);
  console.timeEnd('_crunchStats');
  this._currentRoot = this._treeData;
  this._currentNodes = this._layout.nodes(this._currentRoot);
  this._currentMaxDepth = this._maxLevelsToShow;
  this._doLayout();
}

/**
 * Recursively traverses the entire tree starting from the specified node,
 * computing statistics and recording metadata as it goes. Call this method
 * only once per imported tree.
 */
D3BlobTreeMap.prototype._crunchStats = function(node) {
  var stack = [];
  stack.idCounter = 0;
  this._crunchStatsHelper(stack, node);
}

/**
 * Invoke the specified visitor function on all data elements currently shown
 * in the treemap including any and all of their children, starting at the
 * currently-displayed root and descending recursively. The function will be
 * passed the datum element representing each node. No traversal guarantees
 * are made.
 */
D3BlobTreeMap.prototype.visitFromDisplayedRoot = function(visitor) {
  this._visit(this._currentRoot, visitor);
}

/**
 * Helper function for visit functions.
 */
D3BlobTreeMap.prototype._visit = function(datum, visitor) {
  visitor.call(this, datum);
  if (datum.children) for (var i = 0; i < datum.children.length; i++) {
    this._visit(datum.children[i], visitor);
  }
}

D3BlobTreeMap.prototype._crunchStatsHelper = function(stack, node) {
  // Only overwrite the node ID if it isn't already set.
  // This allows stats to be crunched multiple times on subsets of data
  // without breaking the data-to-ID bindings. New nodes get new IDs.
  if (node.id === undefined) node.id = stack.idCounter++;
  if (node.children === undefined) {
    // Leaf node (blob); accumulate stats.
    for (var i = 0; i < stack.length; i++) {
      var ancestor = stack[i];
      if (!ancestor.blob_stats) ancestor.blob_stats = {};
      if (ancestor.blob_stats[node.t] === undefined) {
        // New blob type we haven't seen before, just record.
        ancestor.blob_stats[node.t] = {'count': 1,
                                         'size': node.value};
      } else {
        // Existing blob type, increment.
        ancestor.blob_stats[node.t].count++;
        ancestor.blob_stats[node.t].size += node.value;
      }
    }
  } else for (var i = 0; i < node.children.length; i++) {
    stack.push(node);
    this._crunchStatsHelper(stack, node.children[i]);
    stack.pop();
  }
}

D3BlobTreeMap.prototype._createTreeMapLayout = function() {
  var result = d3.layout.treemap()
      .padding([this.boxPadding.t, this.boxPadding.r,
                this.boxPadding.b, this.boxPadding.l])
      .size([this._mapWidth, this._mapHeight]);
  return result;
}

D3BlobTreeMap.prototype.resize = function(width, height) {
  this._mapWidth = width;
  this._mapHeight = height;
  this._mapContainer.style('width', width).style('height', height);
  this._layout.size([this._mapWidth, this._mapHeight]);
  this._currentNodes = this._layout.nodes(this._currentRoot);
  this._doLayout();
}

D3BlobTreeMap.prototype._zoomDatum = function(datum) {
  if (this._currentRoot === datum) return; // already here
  this._hideHighlight(datum);
  this._hideInfoBox(datum);
  this._currentRoot = datum;
  this._currentNodes = this._layout.nodes(this._currentRoot);
  this._currentMaxDepth = this._currentRoot.depth + this._maxLevelsToShow;
  console.log('zooming into datum ' + this._currentRoot.n);
  this._doLayout();
}

D3BlobTreeMap.prototype.setMaxLevels = function(levelsToShow) {
  this._maxLevelsToShow = levelsToShow;
  this._currentNodes = this._layout.nodes(this._currentRoot);
  this._currentMaxDepth = this._currentRoot.depth + this._maxLevelsToShow;
  console.log('setting max levels to show: ' + this._maxLevelsToShow);
  this._doLayout();
}

/**
 * Clone the specified tree, returning an independent copy of the data.
 * Only the original attributes expected to exist prior to invoking
 * _crunchStatsHelper are retained, with the exception of the 'id' attribute
 * (which must be retained for proper transitions).
 * If the optional filter parameter is provided, it will be called with 'this'
 * set to this treemap instance and passed the 'datum' object as an argument.
 * When specified, the copy will retain only the data for which the filter
 * function returns true.
 */
D3BlobTreeMap.prototype._clone = function(datum, filter) {
  var trackingStats = false;
  if (this.__cloneState === undefined) {
    console.time('_clone');
    trackingStats = true;
    this.__cloneState = {'accepted': 0, 'rejected': 0,
                         'forced': 0, 'pruned': 0};
  }

  // Must go depth-first. All parents of children that are accepted by the
  // filter must be preserved!
  var copy = {'n': datum.n, 'k': datum.k};
  var childAccepted = false;
  if (datum.children !== undefined) {
    for (var i = 0; i < datum.children.length; i++) {
      var copiedChild = this._clone(datum.children[i], filter);
      if (copiedChild !== undefined) {
        childAccepted = true; // parent must also be accepted.
        if (copy.children === undefined) copy.children = [];
        copy.children.push(copiedChild);
      }
    }
  }

  // Ignore nodes that don't match the filter, when present.
  var accept = false;
  if (childAccepted) {
    // Parent of an accepted child must also be accepted.
    this.__cloneState.forced++;
    accept = true;
  } else if (filter !== undefined && filter.call(this, datum) !== true) {
    this.__cloneState.rejected++;
  } else if (datum.children === undefined) {
    // Accept leaf nodes that passed the filter
    this.__cloneState.accepted++;
    accept = true;
  } else {
    // Non-leaf node. If no children are accepted, prune it.
    this.__cloneState.pruned++;
  }

  if (accept) {
    if (datum.id !== undefined) copy.id = datum.id;
    if (datum.lastPathElement !== undefined) {
      copy.lastPathElement = datum.lastPathElement;
    }
    if (datum.t !== undefined) copy.t = datum.t;
    if (datum.value !== undefined && datum.children === undefined) {
      copy.value = datum.value;
    }
  } else {
    // Discard the copy we were going to return
    copy = undefined;
  }

  if (trackingStats === true) {
    // We are the fist call in the recursive chain.
    console.timeEnd('_clone');
    var totalAccepted = this.__cloneState.accepted +
                        this.__cloneState.forced;
    console.log(
        totalAccepted + ' nodes retained (' +
        this.__cloneState.forced + ' forced by accepted children, ' +
        this.__cloneState.accepted + ' accepted on their own merits), ' +
        this.__cloneState.rejected + ' nodes (and their children) ' +
                                     'filtered out,' +
        this.__cloneState.pruned + ' nodes pruned because because no ' +
                                   'children remained.');
    delete this.__cloneState;
  }
  return copy;
}

D3BlobTreeMap.prototype.filter = function(filter) {
  // Ensure we have a copy of the original root.
  if (this._backupTree === undefined) this._backupTree = this._treeData;
  this._mapContainer.selectAll('div').remove();
  this._setData(this._clone(this._backupTree, filter));
}

D3BlobTreeMap.prototype._doLayout = function() {
  console.time('_doLayout');
  this._handleInodes();
  this._handleLeaves();
  this._firstTransition = false;
  console.timeEnd('_doLayout');
}

D3BlobTreeMap.prototype._highlightElement = function(datum, selection) {
  this._showHighlight(datum, selection);
}

D3BlobTreeMap.prototype._unhighlightElement = function(datum, selection) {
  this._hideHighlight(datum, selection);
}

D3BlobTreeMap.prototype._handleInodes = function() {
  console.time('_handleInodes');
  var thisTreeMap = this;
  var inodes = this._currentNodes.filter(function(datum){
    return (datum.depth <= thisTreeMap._currentMaxDepth) &&
            datum.children !== undefined;
  });
  var cellsEnter = this._mapContainer.selectAll('div.inode')
      .data(inodes, function(datum) { return datum.id; })
      .enter()
      .append('div').attr('class', 'inode').attr('id', function(datum){
          return 'node-' + datum.id;});


  // Define enter/update/exit for inodes
  cellsEnter
      .append('div')
      .attr('class', 'rect inode_rect_entering')
      .style('z-index', function(datum) { return datum.id * 2; })
      .style('position', 'absolute')
      .style('left', function(datum) { return datum.x; })
      .style('top', function(datum){ return datum.y; })
      .style('width', function(datum){ return datum.dx; })
      .style('height', function(datum){ return datum.dy; })
      .style('opacity', '0')
      .style('border', '1px solid black')
      .style('background-image', function(datum) {
        return thisTreeMap._makeblobBucketBackgroundImage.call(
               thisTreeMap, datum);
      })
      .style('background-color', function(datum) {
        if (datum.t === undefined) return 'rgb(220,220,220)';
        return D3BlobTreeMap.getColorForType(datum.t).toString();
      })
      .on('mouseover', function(datum){
        thisTreeMap._highlightElement.call(
            thisTreeMap, datum, d3.select(this));
        thisTreeMap._showInfoBox.call(thisTreeMap, datum);
      })
      .on('mouseout', function(datum){
        thisTreeMap._unhighlightElement.call(
            thisTreeMap, datum, d3.select(this));
        thisTreeMap._hideInfoBox.call(thisTreeMap, datum);
      })
      .on('mousemove', function(){
          thisTreeMap._moveInfoBox.call(thisTreeMap, event);
      })
      .on('dblclick', function(datum){
        if (datum !== thisTreeMap._currentRoot) {
          // Zoom into the selection
          thisTreeMap._zoomDatum(datum);
        } else if (datum.parent) {
          console.log('event.shiftKey=' + event.shiftKey);
          if (event.shiftKey === true) {
            // Back to root
            thisTreeMap._zoomDatum(thisTreeMap._treeData);
          } else {
            // Zoom out of the selection
            thisTreeMap._zoomDatum(datum.parent);
          }
        }
      });
  cellsEnter
      .append('div')
      .attr('class', 'label inode_label_entering')
      .style('z-index', function(datum) { return (datum.id * 2) + 1; })
      .style('position', 'absolute')
      .style('left', function(datum){ return datum.x; })
      .style('top', function(datum){ return datum.y; })
      .style('width', function(datum) { return datum.dx; })
      .style('height', function(datum) { return thisTreeMap.boxPadding.t; })
      .style('opacity', '0')
      .style('pointer-events', 'none')
      .style('-webkit-user-select', 'none')
      .style('overflow', 'hidden') // required for ellipsis
      .style('white-space', 'nowrap') // required for ellipsis
      .style('text-overflow', 'ellipsis')
      .style('text-align', 'center')
      .style('vertical-align', 'top')
      .style('visibility', function(datum) {
        return (datum.dx < 15 || datum.dy < 15) ? 'hidden' : 'visible';
      })
      .text(function(datum) {
        var sizeish = ' [' + D3BlobTreeMap._byteify(datum.value) + ']'
        var text;
        if (datum === thisTreeMap._currentRoot) {
          // The top-most level should always show the complete path
          text = thisTreeMap.pathFor(datum);
        } else {
          // Anything that isn't a bucket or a leaf (blob) or the
          // current root should just show its name.
          text = datum.n;
        }
        return text + sizeish;
      }
  );

  // Complicated transition logic:
  // For nodes that are entering, we want to fade them in in-place AFTER
  // any adjusting nodes have resized and moved around. That way, new nodes
  // seamlessly appear in the right spot after their containers have resized
  // and moved around.
  // To do this we do some trickery:
  // 1. Define a '_entering' class on the entering elements
  // 2. Use this to select only the entering elements and apply the opacity
  //    transition.
  // 3. Use the same transition to drop the '_entering' suffix, so that they
  //    will correctly update in later zoom/resize/whatever operations.
  // 4. The update transition is achieved by selecting the elements without
  //    the '_entering_' suffix and applying movement and resizing transition
  //    effects.
  this._mapContainer.selectAll('div.inode_rect_entering').transition()
      .duration(thisTreeMap._enterDuration).delay(
          this._firstTransition ? 0 : thisTreeMap._exitDuration +
              thisTreeMap._updateDuration)
      .attr('class', 'rect inode_rect')
      .style('opacity', '1')
  this._mapContainer.selectAll('div.inode_label_entering').transition()
      .duration(thisTreeMap._enterDuration).delay(
          this._firstTransition ? 0 : thisTreeMap._exitDuration +
              thisTreeMap._updateDuration)
      .attr('class', 'label inode_label')
      .style('opacity', '1')
  this._mapContainer.selectAll('div.inode_rect').transition()
      .duration(thisTreeMap._updateDuration).delay(thisTreeMap._exitDuration)
      .style('opacity', '1')
      .style('background-image', function(datum) {
        return thisTreeMap._makeblobBucketBackgroundImage.call(
            thisTreeMap, datum);
      })
      .style('left', function(datum) { return datum.x; })
      .style('top', function(datum){ return datum.y; })
      .style('width', function(datum){ return datum.dx; })
      .style('height', function(datum){ return datum.dy; });
  this._mapContainer.selectAll('div.inode_label').transition()
      .duration(thisTreeMap._updateDuration).delay(thisTreeMap._exitDuration)
      .style('opacity', '1')
      .style('visibility', function(datum) {
        return (datum.dx < 15 || datum.dy < 15) ? 'hidden' : 'visible';
      })
      .style('left', function(datum){ return datum.x; })
      .style('top', function(datum){ return datum.y; })
      .style('width', function(datum) { return datum.dx; })
      .style('height', function(datum) { return thisTreeMap.boxPadding.t; })
      .text(function(datum) {
        var sizeish = ' [' + D3BlobTreeMap._byteify(datum.value) + ']'
        var text;
        if (datum === thisTreeMap._currentRoot) {
          // The top-most level should always show the complete path
          text = thisTreeMap.pathFor(datum);
        } else {
          // Anything that isn't a bucket or a leaf (blob) or the
          // current root should just show its name.
          text = datum.n;
        }
        return text + sizeish;
      });
  var exit = this._mapContainer.selectAll('div.inode')
      .data(inodes, function(datum) { return 'inode-' + datum.id; })
      .exit();
  exit.selectAll('div.inode_rect').transition().duration(
      thisTreeMap._exitDuration).style('opacity', 0);
  exit.selectAll('div.inode_label').transition().duration(
      thisTreeMap._exitDuration).style('opacity', 0);
  exit.transition().delay(thisTreeMap._exitDuration + 1).remove();

  console.log(inodes.length + ' inodes layed out.');
  console.timeEnd('_handleInodes');
}

D3BlobTreeMap.prototype._handleLeaves = function() {
  console.time('_handleLeaves');
  var color_fn = d3.scale.category10();
  var thisTreeMap = this;
  var leaves = this._currentNodes.filter(function(datum){
    return (datum.depth <= thisTreeMap._currentMaxDepth) &&
        datum.children === undefined; });
  var cellsEnter = this._mapContainer.selectAll('div.leaf')
      .data(leaves, function(datum) { return datum.id; })
      .enter()
      .append('div').attr('class', 'leaf').attr('id', function(datum){
        return 'node-' + datum.id;
      });

  // Define enter/update/exit for leaves
  cellsEnter
      .append('div')
      .attr('class', 'rect leaf_rect_entering')
      .style('z-index', function(datum) { return datum.id * 2; })
      .style('position', 'absolute')
      .style('left', function(datum){ return datum.x; })
      .style('top', function(datum){ return datum.y; })
      .style('width', function(datum){ return datum.dx; })
      .style('height', function(datum){ return datum.dy; })
      .style('opacity', '0')
      .style('background-color', function(datum) {
        if (datum.t === undefined) return 'rgb(220,220,220)';
        return D3BlobTreeMap.getColorForType(datum.t)
            .darker(0.3).toString();
      })
      .style('border', '1px solid black')
      .on('mouseover', function(datum){
        thisTreeMap._highlightElement.call(
            thisTreeMap, datum, d3.select(this));
        thisTreeMap._showInfoBox.call(thisTreeMap, datum);
      })
      .on('mouseout', function(datum){
        thisTreeMap._unhighlightElement.call(
            thisTreeMap, datum, d3.select(this));
        thisTreeMap._hideInfoBox.call(thisTreeMap, datum);
      })
      .on('mousemove', function(){ thisTreeMap._moveInfoBox.call(
        thisTreeMap, event);
      });
  cellsEnter
      .append('div')
      .attr('class', 'label leaf_label_entering')
      .style('z-index', function(datum) { return (datum.id * 2) + 1; })
      .style('position', 'absolute')
      .style('left', function(datum){ return datum.x; })
      .style('top', function(datum){ return datum.y; })
      .style('width', function(datum) { return datum.dx; })
      .style('height', function(datum) { return datum.dy; })
      .style('opacity', '0')
      .style('pointer-events', 'none')
      .style('-webkit-user-select', 'none')
      .style('overflow', 'hidden') // required for ellipsis
      .style('white-space', 'nowrap') // required for ellipsis
      .style('text-overflow', 'ellipsis')
      .style('text-align', 'center')
      .style('vertical-align', 'middle')
      .style('visibility', function(datum) {
        return (datum.dx < 15 || datum.dy < 15) ? 'hidden' : 'visible';
      })
      .text(function(datum) { return datum.n; });

  // Complicated transition logic: See note in _handleInodes()
  this._mapContainer.selectAll('div.leaf_rect_entering').transition()
      .duration(thisTreeMap._enterDuration).delay(
          this._firstTransition ? 0 : thisTreeMap._exitDuration +
              thisTreeMap._updateDuration)
      .attr('class', 'rect leaf_rect')
      .style('opacity', '1')
  this._mapContainer.selectAll('div.leaf_label_entering').transition()
      .duration(thisTreeMap._enterDuration).delay(
          this._firstTransition ? 0 : thisTreeMap._exitDuration +
              thisTreeMap._updateDuration)
      .attr('class', 'label leaf_label')
      .style('opacity', '1')
  this._mapContainer.selectAll('div.leaf_rect').transition()
      .duration(thisTreeMap._updateDuration).delay(thisTreeMap._exitDuration)
      .style('opacity', '1')
      .style('left', function(datum){ return datum.x; })
      .style('top', function(datum){ return datum.y; })
      .style('width', function(datum){ return datum.dx; })
      .style('height', function(datum){ return datum.dy; });
  this._mapContainer.selectAll('div.leaf_label').transition()
      .duration(thisTreeMap._updateDuration).delay(thisTreeMap._exitDuration)
      .style('opacity', '1')
      .style('visibility', function(datum) {
          return (datum.dx < 15 || datum.dy < 15) ? 'hidden' : 'visible';
      })
      .style('left', function(datum){ return datum.x; })
      .style('top', function(datum){ return datum.y; })
      .style('width', function(datum) { return datum.dx; })
      .style('height', function(datum) { return datum.dy; });
  var exit = this._mapContainer.selectAll('div.leaf')
      .data(leaves, function(datum) { return 'leaf-' + datum.id; })
      .exit();
  exit.selectAll('div.leaf_rect').transition()
      .duration(thisTreeMap._exitDuration)
      .style('opacity', 0);
  exit.selectAll('div.leaf_label').transition()
      .duration(thisTreeMap._exitDuration)
      .style('opacity', 0);
  exit.transition().delay(thisTreeMap._exitDuration + 1).remove();

  console.log(leaves.length + ' leaves layed out.');
  console.timeEnd('_handleLeaves');
}

D3BlobTreeMap.prototype._makeblobBucketBackgroundImage = function(datum) {
  if (!(datum.t === undefined && datum.depth == this._currentMaxDepth)) {
    return 'none';
  }
  var text = '';
  var lastStop = 0;
  for (var x = 0; x < D3BlobTreeMap._BLOB_TYPES.length; x++) {
    blob_type = D3BlobTreeMap._BLOB_TYPES[x];
    var stats = datum.blob_stats[blob_type];
    if (stats !== undefined) {
      if (text.length !== 0) {
        text += ', ';
      }
      var percent = 100 * (stats.size / datum.value);
      var nowStop = lastStop + percent;
      var tempcolor = D3BlobTreeMap.getColorForType(blob_type);
      var color = d3.rgb(tempcolor).toString();
      text += color + ' ' + lastStop + '%, ' + color + ' ' +
          nowStop + '%';
      lastStop = nowStop;
    }
  }
  return 'linear-gradient(' + (datum.dx > datum.dy ? 'to right' :
                               'to bottom') + ', ' + text + ')';
}

D3BlobTreeMap.prototype.pathFor = function(datum) {
  if (datum.__path) return datum.__path;
  parts=[];
  node = datum;
  while (node) {
    if (node.k === 'p') { // path node
      if(node.n !== '/') parts.unshift(node.n);
    }
    node = node.parent;
  }
  datum.__path = '/' + parts.join('/');
  return datum.__path;
}

D3BlobTreeMap.prototype._createHighlight = function(datum, selection) {
  var x = parseInt(selection.style('left'));
  var y = parseInt(selection.style('top'));
  var w = parseInt(selection.style('width'));
  var h = parseInt(selection.style('height'));
  datum.highlight = this._mapContainer.append('div')
      .attr('id', 'h-' + datum.id)
      .attr('class', 'highlight')
      .style('pointer-events', 'none')
      .style('-webkit-user-select', 'none')
      .style('z-index', '999999')
      .style('position', 'absolute')
      .style('top', y-2)
      .style('left', x-2)
      .style('width', w+4)
      .style('height', h+4)
      .style('margin', 0)
      .style('padding', 0)
      .style('border', '4px outset rgba(250,40,200,0.9)')
      .style('box-sizing', 'border-box')
      .style('opacity', 0.0);
}

D3BlobTreeMap.prototype._showHighlight = function(datum, selection) {
  if (datum === this._currentRoot) return;
  if (datum.highlight === undefined) {
    this._createHighlight(datum, selection);
  }
  datum.highlight.transition().duration(200).style('opacity', 1.0);
}

D3BlobTreeMap.prototype._hideHighlight = function(datum, selection) {
  if (datum.highlight === undefined) return;
  datum.highlight.transition().duration(750)
      .style('opacity', 0)
      .each('end', function(){
        if (datum.highlight) datum.highlight.remove();
        delete datum.highlight;
      });
}

D3BlobTreeMap.prototype._createInfoBox = function() {
  return d3.select('body')
      .append('div')
      .attr('id', 'infobox')
      .style('z-index', '2147483647') // (2^31) - 1: Hopefully safe :)
      .style('position', 'absolute')
      .style('visibility', 'hidden')
      .style('background-color', 'rgba(255,255,255, 0.9)')
      .style('border', '1px solid black')
      .style('padding', '10px')
      .style('-webkit-user-select', 'none')
      .style('box-shadow', '3px 3px rgba(70,70,70,0.5)')
      .style('border-radius', '10px')
      .style('white-space', 'nowrap');
}

D3BlobTreeMap.prototype._showInfoBox = function(datum) {
  this.infobox.text('');
  var numBlobs = 0;
  var sizeish = D3BlobTreeMap._pretty(datum.value) + ' bytes (' +
      D3BlobTreeMap._byteify(datum.value) + ')';
  if (datum.k === 'p') { // path
    if (datum.blob_stats) { // can be empty if filters are applied
      for (var x = 0; x < D3BlobTreeMap._BLOB_TYPES.length; x++) {
        blob_type = D3BlobTreeMap._BLOB_TYPES[x];
        var stats = datum.blob_stats[blob_type];
        if (stats !== undefined) numBlobs += stats.count;
      }
    }
  } else if (datum.k === 's') { // blob
    numBlobs = 1;
  }

  if (datum.k === 'p' && !datum.lastPathElement) {
    this.infobox.append('div').text('Package: ' + this.pathFor(datum))
    this.infobox.append('div').text('Size: ' + sizeish);
  } else {
    if (datum.k === 'p') { // path
      this.infobox.append('div').text('File: ' + this.pathFor(datum))
      this.infobox.append('div').text('Size: ' + sizeish);
    } else if (datum.k === 's') { // blob
      this.infobox.append('div').text('blob: ' + datum.n);
      this.infobox.append('div').text('Type: ' +
          D3BlobTreeMap._getblobDescription(datum.t));
      this.infobox.append('div').text('Size (proportional): ' + sizeish);
      this.infobox.append('div').text('Reference count: ' + datum.c);
      this.infobox.append('div').text('Location: ' + this.pathFor(datum))
    }
  }
  if (datum.k === 'p') {
    this.infobox.append('div')
        .text('Number of blobs: ' + D3BlobTreeMap._pretty(numBlobs));
    if (datum.blob_stats) { // can be empty if filters are applied
      var table = this.infobox.append('table')
          .attr('border', 1).append('tbody');
      var header = table.append('tr');
      header.append('th').text('Type');
      header.append('th').text('Count');
      header.append('th')
          .style('white-space', 'nowrap')
          .text('Total Size (Bytes)');
      for (var x = 0; x < D3BlobTreeMap._BLOB_TYPES.length; x++) {
        blob_type = D3BlobTreeMap._BLOB_TYPES[x];
        var stats = datum.blob_stats[blob_type];
        if (stats !== undefined) {
          var tr = table.append('tr');
          tr.append('td')
              .style('white-space', 'nowrap')
              .text(D3BlobTreeMap._getblobDescription(
                  blob_type));
          tr.append('td').text(D3BlobTreeMap._pretty(stats.count));
          tr.append('td').text(D3BlobTreeMap._pretty(stats.size));
        }
      }
    }
  }
  this.infobox.style('visibility', 'visible');
}

D3BlobTreeMap.prototype._hideInfoBox = function(datum) {
  this.infobox.style('visibility', 'hidden');
}

D3BlobTreeMap.prototype._moveInfoBox = function(event) {
  var element = document.getElementById('infobox');
  var w = element.offsetWidth;
  var h = element.offsetHeight;
  var offsetLeft = 10;
  var offsetTop = 10;

  var rightLimit = window.innerWidth;
  var rightEdge = event.pageX + offsetLeft + w;
  if (rightEdge > rightLimit) {
    // Too close to screen edge, reflect around the cursor
    offsetLeft = -1 * (w + offsetLeft);
  }

  var bottomLimit = window.innerHeight;
  var bottomEdge = event.pageY + offsetTop + h;
  if (bottomEdge > bottomLimit) {
    // Too close ot screen edge, reflect around the cursor
    offsetTop = -1 * (h + offsetTop);
  }

  this.infobox.style('top', (event.pageY + offsetTop) + 'px')
      .style('left', (event.pageX + offsetLeft) + 'px');
}

D3BlobTreeMap.prototype.biggestblobs = function(maxRecords) {
  var result = undefined;
  var smallest = undefined;
  var sortFunction = function(a,b) {
    var result = b.value - a.value;
    if (result !== 0) return result; // sort by size
    var pathA = treemap.pathFor(a); // sort by path
    var pathB = treemap.pathFor(b);
    if (pathA > pathB) return 1;
    if (pathB > pathA) return -1;
    return a.n - b.n; // sort by blob name
  };
  this.visitFromDisplayedRoot(function(datum) {
    if (datum.children) return; // ignore non-leaves
    if (!result) { // first element
      result = [datum];
      smallest = datum.value;
      return;
    }
    if (result.length < maxRecords) { // filling the array
      result.push(datum);
      return;
    }
    if (datum.value > smallest) { // array is already full
      result.push(datum);
      result.sort(sortFunction);
      result.pop(); // get rid of smallest element
      smallest = result[maxRecords - 1].value; // new threshold for entry
    }
  });
  result.sort(sortFunction);
  return result;
}

D3BlobTreeMap.prototype.biggestPaths = function(maxRecords) {
  var result = undefined;
  var smallest = undefined;
  var sortFunction = function(a,b) {
    var result = b.value - a.value;
    if (result !== 0) return result; // sort by size
    var pathA = treemap.pathFor(a); // sort by path
    var pathB = treemap.pathFor(b);
    if (pathA > pathB) return 1;
    if (pathB > pathA) return -1;
    console.log('warning, multiple entries for the same path: ' + pathA);
    return 0; // should be impossible
  };
  this.visitFromDisplayedRoot(function(datum) {
    if (!datum.lastPathElement) return; // ignore non-files
    if (!result) { // first element
      result = [datum];
      smallest = datum.value;
      return;
    }
    if (result.length < maxRecords) { // filling the array
      result.push(datum);
      return;
    }
    if (datum.value > smallest) { // array is already full
      result.push(datum);
      result.sort(sortFunction);
      result.pop(); // get rid of smallest element
      smallest = result[maxRecords - 1].value; // new threshold for entry
    }
  });
  result.sort(sortFunction);
  return result;
}
