const RecurseData = require('./recurse-data')const Weighting = require('./weighting')const PrngMethods = require('./prng-methods')const { type } = require('./utils')
function Moon (seedin) {
const initseed = seedin !== undefined ? seedin : Math.floor(Math.random() * 1e8)
this.weighting = Weighting(this)
const { state, reseed, random } = PrngMethods(this, initseed)
this.state = state this.random = random this.reseed = reseed
const { recurseData, handleFunction } = RecurseData(fiona, initseed, this)
let data = null
this.data = input => { if (type(input) === 'Function') { input = input(handleFunction('() => data', data)) }
switch (type(input)) { case 'Array': data = recurseData((data || []).concat(input), `data[${(data || []).length}]`); break case 'Object': data = recurseData(Object.assign({}, data || {}, input), 'data'); break default: data = input }
return data }
this.chain = input => { this.data(input) return this }
this.value = () => data
this.callback = cb => cb.bind(this)(data, this)
this.info = () => ({ initseed })
this.clone = () => fiona(initseed).state(this.state())
return this}
const fiona = (...args) => new Moon(...args)
fiona.version = '__VERSION__'
fiona.fn = Moon.prototype = { constructor: Moon }
fiona.plugin = (name, fn) => fiona.fn[name] = function (...args) { return fn({ seeded: this }, ...args) }
fiona.call = (cmd, ...args) => ({ seeded }) => seeded[cmd](...args)
module.exports = fiona