Source: core/Ingredient.js

import { Measure } from '../data/Measure.js';
import { CaloricContent } from '../data/CaloricContent.js';
import round from './round.js';

/**
 * Base class for all ingredients
 */
export class Ingredient {
	/** @prop {number} density */
	density = 1;
	/** @prop {IngredientType} type */
	type = 'ingredient';
	/**
	 * Get ingredient measurement
	 * 
	 * Available measures:
	 * - Measure.DENSITY
	 * - Measure.CW
	 *
	 * @param {MeasureVariant} measure
	 * @returns {number}
	 */
	get(measure) {
		switch (measure) {
			case Measure.DENSITY:
				return this.density;
				break;
			case Measure.CW:
				return CaloricContent.WATER;
				break;
		}
	}

	attributes = {};
	#setAttribute(name, value) {
		this.attributes[ name ] = value;
		return this;
	}
	#setAttributes(attributes) {
		for (let name in attributes)
			this.#setAttribute(name, attributes[name]);
		return this;
	}
	#getAttribute(name) {
		return this.attributes[name] || null;
	}
	/**
	 * Shorthand getter/setter for attributes
	 *
	 * @param {(Object.<string, any>|string)} name
	 * @param {any} [value]
	 * @returns {this}
	 * @example 
	 * ingredient.attr({ name: 'syrup', type: 'fruit' }); // set multiple
	 * ingredient.attr('name', 'syrup'); // set
	 * ingredient.attr('name'); // get
	 */
	attr(name, value) {
		if (typeof name == 'object') {
			return this.#setAttributes(name);
		} else if (typeof value != 'undefined') {
			return this.#setAttribute(name, value);
		}
		return this.#getAttribute(name);
	}
	/**
	 * Get human-readable Ingredient measurment with a given precision
	 *
	 * @param {MeasureVariant} measure
	 * @param {number} [precision=0.01]
	 * @returns {string}
	 */
	fget(measure, precision) {
		switch (measure) {
			default:
				return {
                    code: 'ingredient_'+measure,
                    data: round(this.get(measure), precision || 0.01)
                }
				break;
		}
	}
}
/** @typedef {string} IngredientType */