not able to select a hexagon in a grid
<p>I have been looking at my code for hours now , but still I can't figure out what's wrong with it exactly. </p>

<p>I have created a very simple version of hexagon grid system. Where I'd like to select any hexagon inside the grid. All the hexagons are being displayed correctly, it's just that when I click on the grid , an incorrect hexagon gets selected. It behaves, as if the mouse position was not correct, or 
perhaps it may be the hexagons that have incorrect position data (?).
But how come they're positioned correctly? </p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>////////// [ Hexagon ] ////////////////////
function Hexagon( options ){ 
 if( options !== "undefined" ){
  this.attributes = {
   type : options.type || 0, //// 0 is cell , 1 player /// Default : 0 ////
   id: options.id,
   color : this.getColor(),
   coords: [], //// [ r, q ] /// row / col ///
   points: [],
   pos: options.pos,
   size: options.size
  };
  
  this.states = {
   selected: false
  };
  
  //// make short-cuts to frequently used attributes ////
  this.pos = this.attributes.pos;
  this.coords = this.attributes.coords;
  this.size = this.attributes.size;
  this.points = this.attributes.points;
  
  ///// caclulate top_left, bottom and center points ////
  this.TopLeftPoint = [ this.pos[0], this.pos[1] ];
  this.BottomRightPoint = [ this.pos[0] + this.size.w, this.pos[1] + this.size.h ];
  this.MidPoint = [ this.pos[0] + (this.size.w / 2), this.pos[1] + (this.size.h / 2) ];
  
  ///////// generate points ///////
  this.generate(); 
 }
}

Hexagon.prototype = {
 constructor : Hexagon,
 changeState: function( st_name, st_value ){
  if( this.checkState( st_name ) ) {
   this.states[st_name] = st_value;
  }
 },
 checkState: function( st_name ){
  if( typeof this.states[st_name] !== "undefined" ) {
   return  this.states[st_name];
  }
  return false;
 },
 isInHexBounds : function( p ){  /*Point*/
  if(this.TopLeftPoint[0] &lt; p[0] &amp;&amp; this.TopLeftPoint[1] &lt; p[1] &amp;&amp; p[0] &lt; this.BottomRightPoint[0] &amp;&amp; p[1] &lt; this.BottomRightPoint[0]){
   return true;
  }
  return false;
 },
 contains: function( p ) {
  var isIn = false;
  if( this.isInHexBounds( p ) ){
   var i, j = 0;
   for (i = 0, j = this.points.length - 1; i &lt; this.points.length; j = i++){
    var iP = this.points[i];
    var jP = this.points[j];
    if (
     ( ((iP[1] &lt;= p[1]) &amp;&amp; (p[1] &lt; jP[1])) || ((jP[1] &lt;= p[1]) &amp;&amp; (p[1] &lt; iP[1]))) &amp;&amp; (p[0] &lt; (jP[0] - iP[0]) * (p[1] - iP[1]) / (jP[1] - iP[1]) + iP[0])
    ){
     isIn = !isIn;
    }
   }
  }
  return isIn;
 },
 getColor: function( ){
  switch( this.type ){
   case 0: 
    return "blue";
   case 1: 
    return "red";
   default:
    return "yellow";
  }
 },
 trigger: function( e_name ){
  this.events[ e_name ].call(this);
 },
 events: {
  "select" : function(){
   if( ! this.checkState( "selected" ) ){
    this.changeState("selected", true);
    //console.log( this.coords )
    this.type = 1;
   }
  }
 },
 setType: function( type ){
  this.attributes.type = type;
 },
 generate: function(){///// generate hexagon points //////
  var x1 = (this.size.w - this.size.s)/2;
  var y1 =  (this.size.h / 2);
  this.points.push( 
   [ x1 + this.pos[0], this.pos[1] ],
   [ x1 + this.size.s + this.pos[0], this.pos[1] ],
   [ this.size.w + this.pos[0], y1 + this.pos[1] ],
   [ x1 + this.size.s + this.pos[0], this.size.h + this.pos[1] ],
   [ x1 + this.pos[0], this.size.h + this.pos[1] ],
   [ this.pos[0], y1 + this.pos[1] ]
  );
 },
 draw : function( ctx ){
  if( this.type &gt; 0 ){
   ctx.globalAlpha = 0.5;
   ctx.fillStyle = this.color;
   ctx.fill();
   ctx.globalAlpha = 1.0;
  }else{
   ctx.strokeStyle = "grey";
  }
  
  //ctx.rect( this.BottomRightPoint[0],this.BottomRightPoint[1],4,4);
  //ctx.stroke();
  
  ctx.lineWidth = 1;
  ctx.beginPath();
  ctx.moveTo( this.points[0][0], this.points[0][1] );
  for( var c=1; c &lt; this.points.length; c++ ){
   ctx.lineTo( this.points[c][0], this.points[c][1] );
  }
  ctx.closePath();
  ctx.stroke();
  
  this.draw_coords( ctx );
 },
 draw_coords: function( ctx ){
  ctx.font="10px Georgia";
  ctx.textAlign = "center";
  ctx.textBaseline = 'middle';
  ctx.fillStyle = "blue";
  ctx.fillText(this.coords[0]+" , "+this.coords[1], this.MidPoint[0], this.MidPoint[1]);
 }
}


///////// [ Grid ] /////////////////////
function Grid( options ){
 if(typeof options !== "undefined"){
  this.size = {
   width: options.size[0],
   height: options.size[1]
  };
  
  //this.mouse_pos = [];
  
  this.pos = options.pos; //// position within the canvas /// [ x , y ] ////
  this.ctx = options.ctx;
  this.ctx_pos = options.ctx_pos; //// position of canvas element /// [ left, top] ///
  this.hex_size = this.calculate_hex_size( options.hex_def );
  this.hexagons = []; //// [ row, col ] /////  just a temporary array  ////
  this.grid2D = []; ///// includes all hexagons to be drawn ///
 }
 this.generate();
 this.animate();
 this.enable_mouse_events();
}

Grid.prototype = {
 constructor : Grid,
 
 generate : function(){
  var hex_pos_x = 0.0, hex_pos_y = 0.0, row = 0, col = 0, offset = 0.0, h = null, h_id = 0; 
  while( (hex_pos_y + this.hex_size.h) &lt;= this.size.height ){
   col = 0; //// reset col 
   offset = 0.0; //// reset offset 
   
   if( (row % 2) == 1){
    offset = ( ( this.hex_size.w - this.hex_size.s ) /2 ) + this.hex_size.s ;
    col = 1;
   }
   
   hex_pos_x = offset;
   
   while( (hex_pos_x  + this.hex_size.w) &lt;= this.size.width ){
    h =  new Hexagon( { pos : [ hex_pos_x, hex_pos_y ], size: this.hex_size , id: row+""+col,  type: 0 }); 
    h.coords[0] = col; //// set coord X ///
    
    this.grid2D.push( h );
    if( ! this.hexagons[col] ){
     this.hexagons[col] = [];
    }
    this.hexagons[col].push( h );
  
    col += 2;
    hex_pos_x += (this.hex_size.w + this.hex_size.s);
   }
   
   row++;
   
   hex_pos_y += (this.hex_size.h / 2);
  }
  
  ////finally go through our list of hexagons by their x co-ordinate to assign the y co-ordinate
  var coordX = 0, coordY = 0, h_l =  this.hexagons.length, hex_arr = [];
  for(  ; coordX &lt;  h_l; coordX++ ){
   hex_arr =  this.hexagons[ coordX ];
   coordY =  Math.floor( (coordX / 2 ) + (coordX % 2) );
   for( var h = 0, size = hex_arr.length; h &lt; size; h++ ){
    hex_arr[h].coords[1] = coordY++;
   }
  }
 },
 
 getHexAt: function( p ){ //// point [ x, y ]
  for ( var h = 0, h_l = this.grid2D.length; h &lt; h_l; h++ ){
   if ( this.grid2D[h].contains( p ) ){
    return this.grid2D[h];
   }
  }
  return null;
 },
 
 animate: function(){
  var self = this;
  window.requestAnimationFrame( function(){
   self.animate();
  });
  self.draw();
 },

 draw : function( ){
  this.ctx.clearRect(0, 0, this.size.width, this.size.height);
  for( var h = 0, h_l = this.grid2D.length; h &lt; h_l; h++ ){
   this.grid2D[h].draw( this.ctx );
  }
 },

 calculate_hex_size : function( hex_def ){
  return {
   w: hex_def.radius * 2,
   m: hex_def.margin,
   h: (Math.sqrt(3) / 2) * ( hex_def.radius * 2),
   r: hex_def.radius,
   s: hex_def.radius
  }
 },
 
 enable_mouse_events: function(){
  var self = this;
  var mouse_pos = [];
  var cur_hex = null;
  window.addEventListener( 'mousemove', function(e){
   mouse_pos  =  [ ( e.clientX - self.ctx_pos[0] ), ( e.clientY - self.ctx_pos[1] )];
   //self.mouse_pos = mouse_pos;
  });
  
  window.addEventListener( 'mousedown', function(e){
   if( mouse_pos.length &gt; 0 ){
    cur_hex = self.getHexAt( mouse_pos );
    if( cur_hex != null ){
     cur_hex.trigger("select");
    }
   }
  });
 }
}

 var c_el = document.getElementById("myCanvas");
 var ctx = c_el.getContext("2d");
 var nGrid = new Grid({
  /// size : [ c_el.width, c_el.height ], /// [rows / cols ] //// 20 px x 10 px///
  size : [ 70 , 70 ], 
  pos: [ 20, 20 ], /// [X, Y] ////
  hex_def: {
   radius: 20,
   margin: 0
  },
  ctx : ctx,
  ctx_pos: [ c_el.getBoundingClientRect().left, c_el.getBoundingClientRect().top ]
 });</code></pre>
<pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;body  stye="width: 100%; height: 100%" &gt;
 &lt;canvas id="myCanvas" width="750px" height="405px" style="margin:0; padding:0; border:1px solid #d3d3d3;"&gt;&lt;/canvas&gt;
&lt;/body&gt;</code></pre>
</div>
</div>
</p>