// Generated by CoffeeScript 1.10.0
(function() {
  var RandomPicker;

  RandomPicker = (function() {

    /*
    Takes a config object like the one shown below, with the same format as is output by Lumenize.histogram()
    
        config =
          histogram: [
            { label: '< 10', count: 1 },  # histogram fields index, startOn, and endBelow are ignored, but returned by getRow() if provided
            { label: '10-20', count: 10 },
            { label: '20-30', count: 102 },
            { label: '30-40', count: 45},
            { label: '>= 40', count: 7}
          ]
    
    So that it will make more sense when used with hand generated distributions, it will also take the following
    
        config =
          distribution: [
            { value: -1.0, p: 0.25 }
            { value:  2.0, p: 0.50 },
            { value:  8.0, p: 0.25 }
          ]
    
    Note, that it runs the same exact code, just replacing what fields are used for the frequencyField and returnValueField
    Similarly, you can override these by explicitly including them in your config.
    
    Also, note that you need not worry about making your 'p' values add up to 1.0. It figures out the portion of the total
     */
    function RandomPicker(config) {
      var cumulative, i, j, k, len, len1, len2, r, ref, ref1, ref2, total;
      this.config = config;
      if (this.config.histogram != null) {
        this.table = this.config.histogram;
      } else if (this.config.distribution != null) {
        this.table = this.config.distribution;
      } else {
        throw new Error('Must provide either a histogram or distribution in your config.');
      }
      if (this.config.frequencyField == null) {
        if (this.config.histogram != null) {
          this.config.frequencyField = 'count';
        } else if (this.config.distribution != null) {
          this.config.frequencyField = 'p';
        }
      }
      if (this.config.returnValueField == null) {
        if (this.config.histogram != null) {
          this.config.returnValueField = 'label';
        } else if (this.config.distribution != null) {
          this.config.returnValueField = 'value';
        }
      }
      total = 0;
      ref = this.table;
      for (i = 0, len = ref.length; i < len; i++) {
        r = ref[i];
        total += r[this.config.frequencyField];
      }
      ref1 = this.table;
      for (j = 0, len1 = ref1.length; j < len1; j++) {
        r = ref1[j];
        r._p = r[this.config.frequencyField] / total;
      }
      cumulative = 0;
      ref2 = this.table;
      for (k = 0, len2 = ref2.length; k < len2; k++) {
        r = ref2[k];
        cumulative += r._p;
        r._pCumulative = cumulative;
      }
    }

    RandomPicker.prototype.getRow = function() {
      var i, len, n, r, ref;
      n = Math.random();
      ref = this.table;
      for (i = 0, len = ref.length; i < len; i++) {
        r = ref[i];
        if (n < r._pCumulative) {
          return r;
        }
      }
      return this.table[this.table.length - 1];
    };

    RandomPicker.prototype.get = function() {
      return this.getRow()[this.config.returnValueField];
    };

    return RandomPicker;

  })();

  exports.RandomPicker = RandomPicker;

}).call(this);
