/*
 * Copyright 2013 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

var HeatGrid = function(el) {
  this.el = $(el);

  var frac = function(minval, maxval, fraction) {
    return minval + fraction * (maxval - minval);
  };

  var gradient = function(mincolor, zerocolor, maxcolor,
                          ofs) {
    if (ofs == 0) {
      return zerocolor;
    } else if (ofs < 0) {
      return [frac(zerocolor[0], mincolor[0], -ofs / 2),
              frac(zerocolor[1], mincolor[1], -ofs / 2),
              frac(zerocolor[2], mincolor[2], -ofs / 2)];
    } else if (ofs > 0) {
      return [frac(zerocolor[0], maxcolor[0], ofs / 2),
              frac(zerocolor[1], maxcolor[1], ofs / 2),
              frac(zerocolor[2], maxcolor[2], ofs / 2)];
    }
  };

  this.draw = function(grid) {
    console.debug('heatgrid.draw', grid);
    this.el.html('<div id="heatgrid" tabindex=0><canvas></canvas>' +
                 '<div id="heatgrid-popover"></div>' +
                 '<div id="heatgrid-highlight"></div></div>');
    var heatgrid = this.el.find('#heatgrid');
    heatgrid.css({
      position: 'relative',
      overflow: 'scroll',
      width: '100%',
      height: '100%'
    });
    var popover = this.el.find('#heatgrid-popover');
    popover.css({
      position: 'absolute',
      background: '#aaa',
      border: '1px dotted black',
      'white-space': 'pre'
    });
    var highlight = this.el.find('#heatgrid-highlight');
    highlight.css({
      position: 'absolute',
          //background: 'rgba(255,192,192,16)',
      width: '3px',
      height: '3px',
      margin: '0',
      padding: '0',
      border: '1px solid red'
    });
    var canvas = this.el.find('canvas');
    var xmult = parseInt(1000 / grid.headers.length);
    if (xmult < 1) xmult = 1;
    var xsize = grid.headers.length * xmult;
    var ysize = grid.data.length;
    canvas.attr({width: xsize, height: ysize});
    canvas.css({
      background: '#fff',
      width: '100%',
      height: ysize
    });
    console.debug('heatgrid canvas size is: x y =', xsize, ysize);
    var ctx = canvas[0].getContext('2d');

    if (!grid.data.length || !grid.data[0].length) {
      return;
    }

    var lastPos = { x: 0, y: 0 };
    var movefunc = function(x, y) {
      if (x >= grid.headers.length) x = grid.headers.length - 1;
      if (y >= grid.data.length) y = grid.data.length - 1;
      if (x < 0) x = 0;
      if (y < 0) y = 0;
      lastPos.x = x;
      lastPos.y = y;
      var info = [];
      for (var i = 0; i < grid.headers.length; i++) {
        if (grid.types[i] != 'number') {
          info.push(grid.data[y][i]);
        } else {
          break;
        }
      }
      info.push(grid.headers[x]);
      info.push('value=' + grid.data[y][x]);

      var cx = x / grid.headers.length * canvas.width();
      var cy = y / grid.data.length * canvas.height();
      highlight.css({left: cx - 2, top: cy - 2});
      if (cx < canvas.width() / 2) {
        popover.css({
          left: cx + 30,
          right: 'auto'
        });
      } else {
        popover.css({
          left: 'auto',
          right: heatgrid[0].clientWidth - cx + 10
        });
      }
      if (cy < canvas.height() / 2) {
        popover.css({
          top: cy + 10,
          bottom: 'auto'
        });
      } else {
        popover.css({
          top: 'auto',
          bottom: heatgrid[0].clientHeight - cy + 10
        });
      }
      popover.text(info.join('\n'));
    };
    heatgrid.mousemove(function(ev) {
      var pos = canvas.position();
      var offX = ev.pageX - pos.left - 1;
      var offY = ev.pageY - pos.top - 1;
      var x = parseInt(offX / canvas.width() * grid.headers.length);
      var y = parseInt(offY / canvas.height() * grid.data.length);
      movefunc(x, y);
    });
    heatgrid.keydown(function(ev) {
      if (ev.which == 38) { // up
        movefunc(lastPos.x, lastPos.y - 1);
      } else if (ev.which == 40) { // down
        movefunc(lastPos.x, lastPos.y + 1);
      } else if (ev.which == 37) { // left
        movefunc(lastPos.x - 1, lastPos.y);
      } else if (ev.which == 39) { // right
        movefunc(lastPos.x + 1, lastPos.y);
      } else {
        return true; // propagate event forward
      }
      ev.stopPropagation();
      return false;
    });
    heatgrid.mouseleave(function() {
      popover.hide();
    });
    heatgrid.mouseenter(function() {
      heatgrid.focus(); // so that keyboard bindings work
      popover.show();
    });

    var total = 0, count = 0;
    for (var y = 0; y < grid.data.length; y++) {
      for (var x = 0; x < grid.data[y].length; x++) {
        if (grid.types[x] != 'number') continue;
        var cell = parseFloat(grid.data[y][x]);
        if (!isNaN(cell)) {
          total += cell;
          count++;
        }
      }
    }
    var avg = total / count;

    var tdiff = 0;
    for (var y = 0; y < grid.data.length; y++) {
      for (var x = 0; x < grid.data[y].length; x++) {
        if (grid.types[x] != 'number') continue;
        var cell = parseFloat(grid.data[y][x]);
        if (!isNaN(cell)) {
          tdiff += (cell - avg) * (cell - avg);
        }
      }
    }
    var stddev = Math.sqrt(tdiff / count);
    console.debug('total,count,mean,stddev = ', total, count, avg, stddev);

    var img = ctx.createImageData(xsize, ysize);
    for (var y = 0; y < grid.data.length; y++) {
      for (var x = 0; x < grid.data[y].length; x++) {
        if (grid.types[x] != 'number') continue;
        var cell = parseFloat(grid.data[y][x]);
        if (isNaN(cell)) continue;
        var ofs = stddev ? (cell - avg) / stddev : 3;
        var color = gradient([192, 192, 192],
                             [192, 192, 255],
                             [0, 0, 255], ofs);
        if (!color) continue;
        var pix = (y * xsize + x * xmult) * 4;
        for (var i = 0; i < xmult; i++) {
          img.data[pix + 0] = color[0];
          img.data[pix + 1] = color[1];
          img.data[pix + 2] = color[2];
          img.data[pix + 3] = 255;
          pix += 4;
        }
      }
    }
    ctx.putImageData(img, 0, 0);
  };
};
