var h = 700; 
var w = 700;

var svg = d3.select("#map")
           .append("svg")
           .attr("height", h)
           .attr("width", w);

var basemap = svg.append("g")
                .attr("id", "basemap");

var projection = d3.geo.mercator()
                  .center([-79.986174, 40.442920])
                  .scale([150000])
                  .translate([310, 290]);

// basemap
d3.json("/data/pgh_neighborhoods.geojson", function(json) {

   var path = d3.geo.path()
                .projection(projection);

   basemap.selectAll("path")
          .data(json.features)
          .enter()
          .append("path")
          .attr("d", path) 
          .attr("stroke", "grey")
          .attr("fill", "#b3b3b3");
});

// define hexbins
var hexbin = d3.hexbin()
              .size([w, h])
              .radius(4);

var hex = svg.append("g")
            .attr("id", "hexbins");

// first of two scales for linear hexagon fill - ref[1]
var fill_scale1 = d3.scale.linear()
                   .domain(d3.range(0, 1, 1 / (viridis_colors.length - 1)))
                   .range(viridis_colors);

// crash data
d3.csv("/data/pgh_bike_crashes_coords_2004_2014.csv", function(data) {
            
   // convert lat/lng to numeric
   data.forEach(function(d) {
        d.lat = +d.lat;
        d.lng = +d.lng;
   });

   points = [];

   // x,y maps to lng,lat - ref[2]
   data.forEach(function(d) {
       d.lat = +d.lat;
       d.lng = +d.lng;
       var x = projection([d.lng, d.lat])[0];
       var y = projection([d.lng, d.lat])[1];
       points.push([x, y]);
   });

   // bin coords
   var bins = hexbin(points);     
   var bins_n = [];             // points per hexbin
   bins.forEach(function(d) {
       bins_n.push(d.length); 
   });

   // second of two scales for linear hexagon fill - ref[1]
   var extent = d3.extent(bins_n);
   var fill_scale2 = d3.scale.linear()
                       .domain([extent[0], extent[1]])
                       .range([0,1]);

   hex.selectAll(".hexagon")
        .data(hexbin(points)) 
        .enter()
        .append("path")
        .attr("class", function(d) {
            return "hexagon bin_" + d.length;
        })
        .attr("d", hexbin.hexagon())
        .attr("transform", function(d) { 
                return "translate(" + d.x + "," + d.y + ")"; 
        })
        .style("fill", function(d) {
                return fill_scale1(fill_scale2(d.length));
        });

   // legend
   svg.append("g")
      .attr("class", "legendQuant")
      .attr("transform", "translate(20,20)");

   var legend_hex = "m0,-12l10.392304845413264,5.999999999999998l0,12l-10.392304845413257,6.000000000000003l-10.392304845413268,-5.999999999999995l-7.105427357601002e-15,-11.999999999999996l10.392304845413253,-6.000000000000008z";
       
   var legend = d3.legend.color()
                  .scale(fill_scale1)
                  .cells(7)
                  .shape("path", legend_hex)
                  .orient("horizontal")
                  .shapePadding(8)
                  .labelOffset(10)
                  .title("Number of Bike Accidents")
                  .on("cellclick", function(d) {

                      d3.selectAll(".hexagon")
                        .style("opacity", "1");

                      var n_bin = Math.ceil(fill_scale2.invert(d))

                      d3.selectAll(".hexagon:not(.bin_" + n_bin)
                          .style("opacity", "0");
                  });

   svg.select(".legendQuant")
        .call(legend);

   // re-map legend text from fill_scale1 (0-1) to binned data (min - max) 
   d3.selectAll(".label")
       .text(function () {
           label = d3.select(this).text();
           return Math.round(fill_scale2.invert(label));
       });

   // tweak position of legend title
   d3.select(".legendTitle")
       .attr("transform", "translate(1, 6)");

   // new cursor pointer for legend hexs and reset button
   d3.selectAll(".swatch, #buttonBackground")
       .on("mouseover", function() {

           d3.select(this)
           .style("cursor", "pointer");

       });

   // cursor unresponsive to legend text 
   d3.selectAll(".label")
       .on("mouseover", function() {
       
           d3.select(this)
             .style("cursor", "default");

       });
});


// reset button - credit ref[3]  
var b_buttonColor = "#3399ff";

var b_width= 110/2, b_height=45/2,
   b_fontSize = 1.38*b_height/3,
   b_x0 = 20, b_y0 = 95,
   b_x0Text = b_x0 + b_width/2, b_y0Text = b_y0 + 0.66*b_height,
   b_text = "Reset";

var reset = svg.append("g")
              .attr("id", "reset");

reset.append("rect")          
  .attr("id","buttonBackground")
  .attr("width", b_width + "px")
  .attr("height", b_height + "px")
  .style("fill", b_buttonColor)
  .attr("x", b_x0)
  .attr("y", b_y0)
  .attr("ry", b_height/10)
  .attr("r", 30)
  .on("click", function() {

      d3.selectAll(".hexagon")
        .style("opacity", "1");

  });

reset.append("text")
  .attr("id","buttonText")
  .attr("x", b_x0Text)
  .attr("y", b_y0Text)
  .style("text-anchor", "middle")
  .style("fill", "#ffffff")
  .style("stroke", "none")
  .style("font-family", "Arial, sans-serif")
  .style("font-size", b_fontSize + "px")
  .style("pointer-events", "none")
  .text(b_text);

/*REFERENCES*/
/*ref[1]: http://stackoverflow.com/questions/17671252/d3-create-a-continous-color-scale-with-many-strings-inputs-for-the-range-and-dy*/
/*ref[2]: http://gis.stackexchange.com/questions/99769/why-some-coordinate-systems-define-x-axis-as-northings-and-some-as-easting/99781#99781*/
/*ref[3]: http://bl.ocks.org/pbogden/7487564 */