/*jslint browser: true */
(function () {
  'use strict';

  var canvas = document.getElementById('Hex'),
      ctx = canvas.getContext('2d');

  var Vec2 = function (x, y) {
    this.x = x;
    this.y = y;
  };

  var Vec2Math = {
    add: function (v1, v2) {
      return new Vec2(v1.x + v2.x, v1.y + v2.y);
    },
    dot: function (v1, v2) {
      return v1.x * v2.x + v1.y * v2.y;
    },
    scale: function (a, v) {
      return new Vec2(a * v.x, a * v.y);
    },
    fromAngle: function (phi) {
      return new Vec2(Math.cos(phi), Math.sin(phi));
    },
    deg2rad: function (deg) {
      return (deg % 360) * Math.PI / 180.0
    }
  };

  var pointOnCircle = function(center, radius, angle) {
    return Vec2Math.add(center,
                        Vec2Math.scale(radius, Vec2Math.fromAngle(angle)));
  };

  var Hex = function (center, radius, rotation) {
    this.center = center;
    this.radius = radius;
    this.rotation = Vec2Math.deg2rad((rotation || 0) % 60);
    this.width = 2 * this.radius * Math.cos(this.rotation);
    this.height =
        2 * this.radius * Math.sin(Vec2Math.deg2rad(60) + this.rotation);
  };

  Hex.prototype.draw = function (ctx) {
    ctx.beginPath();
    var p = pointOnCircle(this.center, this.radius, this.rotation);
    ctx.moveTo(p.x, p.y);
    for (var i = 1; i <= 6; i++) {
      p = pointOnCircle(this.center, this.radius,
                        this.rotation + Vec2Math.deg2rad(i * 60));
      ctx.lineTo(p.x, p.y);
    }
    ctx.stroke();
  };

  Hex.prototype.drawBounds = function (ctx) {
    ctx.beginPath();
    ctx.arc(this.center.x, this.center.y, this.radius, 0, Math.PI * 2, false);
    ctx.strokeStyle = '#FF0000';
    ctx.stroke();

    var w2 = this.width / 2,
        h2 = this.height / 2;
    ctx.strokeStyle = '#00FF00';
    ctx.strokeRect(this.center.x - w2, this.center.y - h2, this.width,
                   this.height);

    ctx.strokeStyle = '#000000';
    ctx.lineWidth = 1.0;
  };

  var drawGrid = function (ctx, spacing) {
    var s = spacing || 10;
    var nx = canvas.width / s,
        ny = canvas.height / s;
    ctx.beginPath();
    for (var i = 0; i < nx; i++) {
      ctx.moveTo(i * s, 0);
      ctx.lineTo(i * s, canvas.height);
    }
    for (var i = 0; i < ny; i++) {
      ctx.moveTo(0, i * s);
      ctx.lineTo(canvas.width, i * s);
    }
    ctx.lineWidth = 0.5;
    ctx.strokeStyle = '#CCCCCC';
    ctx.stroke();

    ctx.strokeStyle = '#000000';
    ctx.lineWidth = 1.0;
  };

  drawGrid(ctx);

  var h1 = new Hex(new Vec2(100, 100), 100, 0);
  h1.draw(ctx);
  h1.drawBounds(ctx);
  
  var h2 = new Hex(new Vec2(300, 300), 100, 30);
  h2.draw(ctx);
  h2.drawBounds(ctx);

  var h3 = new Hex(new Vec2(100, 300), 100, 15);
  h3.draw(ctx);
  h3.drawBounds(ctx);
}());

@@ -1474,30 +1474,162 @@
   %7D%0A    ctx.
-stroke
+closePath();%0A    // Just testing%0A    ctx.fillStyle =%0A        'hsla(' + Math.floor(Math.random() * 360) + ', 60%25, 50%25, 0.75)';%0A    ctx.fill
 ();%0A  %7D;%0A%0A  
@@ -2081,24 +2081,702 @@
  1.0;%0A  %7D;%0A%0A
+  var HexGrid = function (radius, nx, ny) %7B%0A    this.seedHex = new Hex(new Vec2(0, 0), radius, 60);%0A    var sx = this.seedHex.width,%0A        sy = this.seedHex.height;%0A    this.hexes = %5B%5D;%0A    for (var y = 0; y %3C ny; y+=1) %7B%0A      for (var x = 0; x %3C nx; x+=2) %7B%0A        this.hexes.push(new Hex(new Vec2(x * 0.75 * sx, y * sy), radius, 60));%0A        this.hexes.push(%0A            new Hex(new Vec2((x + 1) * 0.75 * sx, y * sy + sy / 2), radius, 60));%0A      %7D%0A    %7D%0A  %7D;%0A%0A  HexGrid.prototype.draw = function (ctx) %7B%0A    var lineWidth = ctx.lineWidth;%0A    ctx.lineWidth = 0.5;%0A    this.hexes.forEach(function (hex) %7B%0A      hex.draw(ctx);%0A    %7D);%0A    ctx.lineWidth = lineWidth;%0A  %7D;%0A%0A
   var drawGr
@@ -3300,17 +3300,17 @@
 %0A  var h
-1
+g
  = new H
@@ -3315,220 +3315,32 @@
  Hex
-(new Vec2(100, 100), 100, 0);%0A  h1.draw(ctx);%0A  h1.drawBounds(ctx);%0A  %0A  var h2 = new Hex(new Vec2(300, 300), 100, 30);%0A  h2.draw(ctx);%0A  h2.drawBounds(ctx);%0A%0A  var h3 = new Hex(new Vec2(100, 300), 100, 15
+Grid(30, 100, 100
 );%0A  h
-3
+g
 .dra
@@ -3351,30 +3351,8 @@
 x);%0A
-  h3.drawBounds(ctx);%0A
 %7D())

Add crude hexagonal grid with random fillings.