// Generated by CoffeeScript 1.4.0
(function() {
  var color, correct_x, correct_y, data, enter_labels, enter_labels_g, enter_pipedons, height, iso_layout, isometric, parallelepipedon, path_generator, pipedons, svg, treemap, vis, width, zoom, zoomable_layer;

  svg = d3.select('svg');

  width = svg.node().getBoundingClientRect().width;

  height = svg.node().getBoundingClientRect().height;

  zoomable_layer = svg.append('g');

  zoom = d3.behavior.zoom().scaleExtent([1, 10]).on('zoom', function() {
    return zoomable_layer.attr({
      transform: "translate(" + (zoom.translate()) + ")scale(" + (zoom.scale()) + ")"
    });
  });

  svg.call(zoom);

  vis = zoomable_layer.append('g').attr({
    "class": 'vis',
    transform: "translate(" + (width / 2) + "," + (height / 3) + ")"
  });

  isometric = function(_3d_p) {
    return [-Math.sqrt(3) / 2 * _3d_p[0] + Math.sqrt(3) / 2 * _3d_p[1], +0.5 * _3d_p[0] + 0.5 * _3d_p[1] - _3d_p[2]];
  };

  parallelepipedon = function(d) {
    var fb, ft, mlb, mlt, mrb, mrt, nb, nt;
    if (!(d.x != null)) {
      d.x = 0;
    }
    if (!(d.y != null)) {
      d.y = 0;
    }
    if (!(d.h != null)) {
      d.h = 0;
    }
    if (!(d.dx != null)) {
      d.dx = 10;
    }
    if (!(d.dy != null)) {
      d.dy = 10;
    }
    if (!(d.dh != null)) {
      d.dh = 10;
    }
    fb = isometric([d.x, d.y, d.h], mlb = isometric([d.x + d.dx, d.y, d.h], nb = isometric([d.x + d.dx, d.y + d.dy, d.h], mrb = isometric([d.x, d.y + d.dy, d.h], ft = isometric([d.x, d.y, d.h + d.dh], mlt = isometric([d.x + d.dx, d.y, d.h + d.dh], nt = isometric([d.x + d.dx, d.y + d.dy, d.h + d.dh], mrt = isometric([d.x, d.y + d.dy, d.h + d.dh]))))))));
    d.iso = {
      face_bottom: [fb, mrb, nb, mlb],
      face_left: [mlb, mlt, nt, nb],
      face_right: [nt, mrt, mrb, nb],
      face_top: [ft, mrt, nt, mlt],
      outline: [ft, mrt, mrb, nb, mlb, mlt],
      fb: fb,
      mlb: mlb,
      nb: nb,
      mrb: mrb,
      ft: ft,
      mlt: mlt,
      nt: nt,
      mrt: mrt
    };
    return d;
  };

  iso_layout = function(data, shape, scale) {
    if (!(scale != null)) {
      scale = 1;
    }
    data.forEach(function(d) {
      return shape(d, scale);
    });
    return data.sort(function(a, b) {
      return b.dh - a.dh;
    });
  };

  path_generator = function(d) {
    return 'M' + d.map(function(p) {
      return p.join(' ');
    }).join('L') + 'z';
  };

  treemap = d3.layout.treemap().size([300, 300]).value(function(d) {
    return d.area;
  }).sort(function(a, b) {
    return a.dh - b.dh;
  }).ratio(4).round(false);

  color = d3.scale.category20c();

  correct_x = d3.scale.linear().domain([0, width]).range([0, width * 1.05]);

  correct_y = d3.scale.linear().domain([0, height]).range([0, height * 3 / 4]);

  data = d3.range(30).map(function() {
    return {
      word: randstring["new"](),
      area: Math.random(),
      dh: Math.random() * 150
    };
  });

  data = treemap.nodes({
    children: data
  }).filter(function(n) {
    return n.depth === 1;
  });

  iso_layout(data, parallelepipedon);

  data.forEach(function(d, i) {
    return d.template_color = d3.hcl(color(i));
  });

  pipedons = vis.selectAll('.pipedon').data(data);

  enter_pipedons = pipedons.enter().append('g').attr({
    "class": 'pipedon'
  });

  enter_pipedons.append('path').attr({
    "class": 'iso face bottom',
    d: function(d) {
      return path_generator(d.iso.face_bottom);
    }
  });

  enter_pipedons.append('path').attr({
    "class": 'iso face left',
    d: function(d) {
      return path_generator(d.iso.face_left);
    },
    fill: function(d) {
      return d.template_color;
    }
  });

  enter_pipedons.append('path').attr({
    "class": 'iso face right',
    d: function(d) {
      return path_generator(d.iso.face_right);
    },
    fill: function(d) {
      return d3.hcl(d.template_color.h, d.template_color.c, d.template_color.l - 12);
    }
  });

  enter_pipedons.append('path').attr({
    "class": 'iso face top',
    d: function(d) {
      return path_generator(d.iso.face_top);
    },
    fill: function(d) {
      return d3.hcl(d.template_color.h, d.template_color.c, d.template_color.l + 12);
    }
  });

  enter_labels_g = enter_pipedons.append('g');

  enter_labels = enter_labels_g.append('svg').attr({
    "class": 'label'
  });

  enter_labels.append('text').text(function(d) {
    return d.word.toUpperCase();
  }).attr({
    dy: '.35em'
  }).each(function(node) {
    var bbox, bbox_aspect, node_bbox, node_bbox_aspect, rotate;
    bbox = this.getBBox();
    bbox_aspect = bbox.width / bbox.height;
    node_bbox = {
      width: node.dx,
      height: node.dy
    };
    node_bbox_aspect = node_bbox.width / node_bbox.height;
    rotate = bbox_aspect >= 1 && node_bbox_aspect < 1 || bbox_aspect < 1 && node_bbox_aspect >= 1;
    node.label_bbox = {
      x: bbox.x + (bbox.width - correct_x(bbox.width)) / 2,
      y: bbox.y + (bbox.height - correct_y(bbox.height)) / 2,
      width: correct_x(bbox.width),
      height: correct_y(bbox.height)
    };
    if (rotate) {
      node.label_bbox = {
        x: node.label_bbox.y,
        y: node.label_bbox.x,
        width: node.label_bbox.height,
        height: node.label_bbox.width
      };
      return d3.select(this).attr('transform', 'rotate(90) translate(0,1)');
    }
  });

  enter_labels.each(function(d) {
    d.iso_x = isometric([d.x + d.dx / 2, d.y + d.dy / 2, d.h + d.dh])[0] - d.dx / 2;
    return d.iso_y = isometric([d.x + d.dx / 2, d.y + d.dy / 2, d.h + d.dh])[1] - d.dy / 2;
  });

  enter_labels.attr({
    x: function(d) {
      return d.iso_x;
    },
    y: function(d) {
      return d.iso_y;
    },
    width: function(node) {
      return node.dx;
    },
    height: function(node) {
      return node.dy;
    },
    viewBox: function(node) {
      return "" + node.label_bbox.x + " " + node.label_bbox.y + " " + node.label_bbox.width + " " + node.label_bbox.height;
    },
    preserveAspectRatio: 'none',
    fill: function(d) {
      return d3.hcl(d.template_color.h, d.template_color.c, d.template_color.l - 12);
    }
  });

  enter_labels_g.attr({
    transform: function(d) {
      return "translate(" + (d.iso_x + d.dx / 2) + "," + (d.iso_y + d.dy / 2) + ") scale(1, " + (1 / Math.sqrt(3)) + ") rotate(-45) translate(" + (-(d.iso_x + d.dx / 2)) + "," + (-(d.iso_y + d.dy / 2)) + ")";
    }
  });

  enter_pipedons.append('path').attr({
    "class": 'iso outline',
    d: function(d) {
      return path_generator(d.iso.outline);
    }
  });

}).call(this);