var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  hasProp = {}.hasOwnProperty;

import {
  XYGlyph,
  XYGlyphView
} from "./xy_glyph";

import * as p from "core/properties";

import {
  max,
  concat
} from "core/util/array";

export var ImageRGBAView = (function(superClass) {
  extend(ImageRGBAView, superClass);

  function ImageRGBAView() {
    return ImageRGBAView.__super__.constructor.apply(this, arguments);
  }

  ImageRGBAView.prototype._set_data = function(source, arg) {
    var buf, buf8, canvas, color, ctx, flat, i, image_data, j, k, l, m, ref, ref1, ref2, results, shape;
    if ((this.image_data == null) || this.image_data.length !== this._image.length) {
      this.image_data = new Array(this._image.length);
    }
    if ((this._width == null) || this._width.length !== this._image.length) {
      this._width = new Array(this._image.length);
    }
    if ((this._height == null) || this._height.length !== this._image.length) {
      this._height = new Array(this._image.length);
    }
    results = [];
    for (i = k = 0, ref = this._image.length; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) {
      if (arg != null) {
        if (i !== arg) {
          continue;
        }
      }
      shape = [];
      if (this._image_shape != null) {
        shape = this._image_shape[i];
      }
      if (this._rows != null) {
        this._height[i] = this._rows[i];
        this._width[i] = this._cols[i];
        if (shape.length > 0) {
          buf = this._image[i].buffer;
        } else {
          flat = this._image[i];
          buf = new ArrayBuffer(flat.length * 4);
          color = new Uint32Array(buf);
          for (j = l = 0, ref1 = flat.length; 0 <= ref1 ? l < ref1 : l > ref1; j = 0 <= ref1 ? ++l : --l) {
            color[j] = flat[j];
          }
        }
      } else if (shape.length > 0) {
        buf = this._image[i].buffer;
        this._height[i] = shape[0];
        this._width[i] = shape[1];
      } else {
        flat = concat(this._image[i]);
        buf = new ArrayBuffer(flat.length * 4);
        color = new Uint32Array(buf);
        for (j = m = 0, ref2 = flat.length; 0 <= ref2 ? m < ref2 : m > ref2; j = 0 <= ref2 ? ++m : --m) {
          color[j] = flat[j];
        }
        this._height[i] = this._image[i].length;
        this._width[i] = this._image[i][0].length;
      }
      if ((this.image_data[i] != null) && this.image_data[i].width === this._width[i] && this.image_data[i].height === this._height[i]) {
        canvas = this.image_data[i];
      } else {
        canvas = document.createElement('canvas');
        canvas.width = this._width[i];
        canvas.height = this._height[i];
      }
      ctx = canvas.getContext('2d');
      image_data = ctx.getImageData(0, 0, this._width[i], this._height[i]);
      buf8 = new Uint8Array(buf);
      image_data.data.set(buf8);
      ctx.putImageData(image_data, 0, 0);
      this.image_data[i] = canvas;
      this.max_dw = 0;
      if (this._dw.units === "data") {
        this.max_dw = max(this._dw);
      }
      this.max_dh = 0;
      if (this._dh.units === "data") {
        results.push(this.max_dh = max(this._dh));
      } else {
        results.push(void 0);
      }
    }
    return results;
  };

  ImageRGBAView.prototype._map_data = function() {
    switch (this.model.properties.dw.units) {
      case "data":
        this.sw = this.sdist(this.renderer.xmapper, this._x, this._dw, 'edge', this.model.dilate);
        break;
      case "screen":
        this.sw = this._dw;
    }
    switch (this.model.properties.dh.units) {
      case "data":
        return this.sh = this.sdist(this.renderer.ymapper, this._y, this._dh, 'edge', this.model.dilate);
      case "screen":
        return this.sh = this._dh;
    }
  };

  ImageRGBAView.prototype._render = function(ctx, indices, arg1) {
    var i, image_data, k, len, old_smoothing, sh, sw, sx, sy, y_offset;
    image_data = arg1.image_data, sx = arg1.sx, sy = arg1.sy, sw = arg1.sw, sh = arg1.sh;
    old_smoothing = ctx.getImageSmoothingEnabled();
    ctx.setImageSmoothingEnabled(false);
    for (k = 0, len = indices.length; k < len; k++) {
      i = indices[k];
      if (isNaN(sx[i] + sy[i] + sw[i] + sh[i])) {
        continue;
      }
      y_offset = sy[i];
      ctx.translate(0, y_offset);
      ctx.scale(1, -1);
      ctx.translate(0, -y_offset);
      ctx.drawImage(image_data[i], sx[i] | 0, sy[i] | 0, sw[i], sh[i]);
      ctx.translate(0, y_offset);
      ctx.scale(1, -1);
      ctx.translate(0, -y_offset);
    }
    return ctx.setImageSmoothingEnabled(old_smoothing);
  };

  ImageRGBAView.prototype.bounds = function() {
    var bbox;
    bbox = this.index.bbox;
    bbox.maxX += this.max_dw;
    bbox.maxY += this.max_dh;
    return bbox;
  };

  return ImageRGBAView;

})(XYGlyphView);

export var ImageRGBA = (function(superClass) {
  extend(ImageRGBA, superClass);

  function ImageRGBA() {
    return ImageRGBA.__super__.constructor.apply(this, arguments);
  }

  ImageRGBA.prototype.default_view = ImageRGBAView;

  ImageRGBA.prototype.type = 'ImageRGBA';

  ImageRGBA.define({
    image: [p.NumberSpec],
    rows: [p.NumberSpec],
    cols: [p.NumberSpec],
    dw: [p.DistanceSpec],
    dh: [p.DistanceSpec],
    dilate: [p.Bool, false]
  });

  ImageRGBA.prototype.initialize = function(attrs, options) {
    ImageRGBA.__super__.initialize.call(this, attrs, options);
    this.properties.rows.optional = true;
    return this.properties.cols.optional = true;
  };

  return ImageRGBA;

})(XYGlyph);
