'use strict';

var index = require('../../utils/es/index.js');

/**
 * Get an image's histogram
 * @return {object} An object with an array of color occurrence counts for each channel (r,g,b)
 */
function histogram() {
  const histogram = {
    r: new Array(256).fill(0),
    g: new Array(256).fill(0),
    b: new Array(256).fill(0)
  };
  this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, index) {
    histogram.r[this.bitmap.data[index + 0]]++;
    histogram.g[this.bitmap.data[index + 1]]++;
    histogram.b[this.bitmap.data[index + 2]]++;
  });
  return histogram;
}

/**
 * Normalize values
 * @param  {integer} value Pixel channel value.
 * @param  {integer} min   Minimum value for channel
 * @param  {integer} max   Maximum value for channel
 * @return {integer} normalized values
 */
const normalize = function (value, min, max) {
  return (value - min) * 255 / (max - min);
};
const getBounds = function (histogramChannel) {
  return [histogramChannel.findIndex(value => value > 0), 255 - histogramChannel.slice().reverse().findIndex(value => value > 0)];
};

/**
 * Normalizes the image
 * @param {function(Error, Jimp)} cb (optional) a callback for when complete
 * @returns {Jimp} this for chaining of methods
 */
var normalize$1 = (() => ({
  normalize(cb) {
    const h = histogram.call(this);

    // store bounds (minimum and maximum values)
    const bounds = {
      r: getBounds(h.r),
      g: getBounds(h.g),
      b: getBounds(h.b)
    };

    // apply value transformations
    this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function (x, y, idx) {
      const r = this.bitmap.data[idx + 0];
      const g = this.bitmap.data[idx + 1];
      const b = this.bitmap.data[idx + 2];
      this.bitmap.data[idx + 0] = normalize(r, bounds.r[0], bounds.r[1]);
      this.bitmap.data[idx + 1] = normalize(g, bounds.g[0], bounds.g[1]);
      this.bitmap.data[idx + 2] = normalize(b, bounds.b[0], bounds.b[1]);
    });
    if (index.isNodePattern(cb)) {
      cb.call(this, null, this);
    }
    return this;
  }
}));

module.exports = normalize$1;
