// Generated by CoffeeScript 1.7.1
var Generator, stream, util;

stream = require('stream');

util = require('util');

module.exports = function() {
  var callback, data, generator, options;
  if (arguments.length === 2) {
    options = arguments[0];
    callback = arguments[1];
  } else if (arguments.length === 1) {
    if (typeof arguments[0] === 'function') {
      options = {};
      callback = arguments[0];
    } else {
      options = arguments[0];
    }
  } else if (arguments.length === 0) {
    options = {};
  }
  generator = new Generator(options);
  if (callback) {
    data = [];
    generator.on('readable', function() {
      var d, _results;
      _results = [];
      while (d = generator.read()) {
        _results.push(data.push(options.objectMode ? d : d.toString()));
      }
      return _results;
    });
    generator.on('error', callback);
    generator.on('end', function() {
      return callback(null, options.objectMode ? data : data.join(''));
    });
  }
  return generator;
};

Generator = function(options) {
  var i, v, _base, _base1, _base2, _base3, _base4, _base5, _base6, _base7, _base8, _i, _len, _ref;
  this.options = options != null ? options : {};
  stream.Readable.call(this, this.options);
  this.options.count = 0;
  if ((_base = this.options).duration == null) {
    _base.duration = 4 * 60 * 1000;
  }
  if ((_base1 = this.options).columns == null) {
    _base1.columns = 8;
  }
  if ((_base2 = this.options).max_word_length == null) {
    _base2.max_word_length = 16;
  }
  if ((_base3 = this.options).fixed_size == null) {
    _base3.fixed_size = false;
  }
  if (this.fixed_size_buffer == null) {
    this.fixed_size_buffer = '';
  }
  if ((_base4 = this.options).start == null) {
    _base4.start = Date.now();
  }
  if ((_base5 = this.options).end == null) {
    _base5.end = null;
  }
  if ((_base6 = this.options).seed == null) {
    _base6.seed = false;
  }
  if ((_base7 = this.options).length == null) {
    _base7.length = -1;
  }
  if ((_base8 = this.options).delimiter == null) {
    _base8.delimiter = ',';
  }
  this.count_written = 0;
  this.count_created = 0;
  if (typeof this.options.columns === 'number') {
    this.options.columns = new Array(this.options.columns);
  }
  _ref = this.options.columns;
  for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
    v = _ref[i];
    if (v == null) {
      v = 'ascii';
    }
    if (typeof v === 'string') {
      this.options.columns[i] = Generator[v];
    }
  }
  return this;
};

util.inherits(Generator, stream.Readable);

module.exports.Generator = Generator;

Generator.prototype.random = function() {
  if (this.options.seed) {
    return this.options.seed = this.options.seed * Math.PI * 100 % 100 / 100;
  } else {
    return Math.random();
  }
};

Generator.prototype.end = function() {
  return this.push(null);
};

Generator.prototype._read = function(size) {
  var column, data, header, length, line, lineLength, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref;
  data = [];
  length = this.fixed_size_buffer.length;
  if (length) {
    data.push(this.fixed_size_buffer);
  }
  while (true) {
    if ((this.count_created === this.options.length) || (this.options.end && Date.now() > this.options.end)) {
      if (data.length) {
        if (this.options.objectMode) {
          for (_i = 0, _len = data.length; _i < _len; _i++) {
            line = data[_i];
            this.count_written++;
            this.push(line);
          }
        } else {
          this.count_written++;
          this.push(data.join(''));
        }
      }
      return this.push(null);
    }
    line = [];
    _ref = this.options.columns;
    for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
      header = _ref[_j];
      line.push("" + (header(this)));
    }
    if (this.options.objectMode) {
      lineLength = 0;
      for (_k = 0, _len2 = line.length; _k < _len2; _k++) {
        column = line[_k];
        lineLength += column.length;
      }
    } else {
      line = "" + (this.count_created === 0 ? '' : '\n') + (line.join(this.options.delimiter));
      lineLength = line.length;
    }
    this.count_created++;
    if (length + lineLength > size) {
      if (this.options.objectMode) {
        data.push(line);
        for (_l = 0, _len3 = data.length; _l < _len3; _l++) {
          line = data[_l];
          this.count_written++;
          this.push(line);
        }
      } else {
        if (this.options.fixed_size) {
          this.fixed_size_buffer = line.substr(size - length);
          data.push(line.substr(0, size - length));
        } else {
          data.push(line);
        }
        this.count_written++;
        this.push(data.join(''));
      }
      break;
    }
    length += lineLength;
    data.push(line);
  }
};

Generator.ascii = function(gen) {
  var char, column, nb_chars, _i, _ref;
  column = [];
  for (nb_chars = _i = 0, _ref = Math.ceil(gen.random() * gen.options.max_word_length); 0 <= _ref ? _i < _ref : _i > _ref; nb_chars = 0 <= _ref ? ++_i : --_i) {
    char = Math.floor(gen.random() * 32);
    column.push(String.fromCharCode(char + (char < 16 ? 65 : 97 - 16)));
  }
  return column.join('');
};

Generator.int = function(gen) {
  return Math.floor(gen.random() * Math.pow(2, 52));
};

Generator.bool = function(gen) {
  return Math.floor(gen.random() * 2);
};
