import List from "../../../../../../core/collection/list/List.js";
import { ParticleParameter } from "./ParticleParameter.js";

export class ParameterSet {
    constructor() {
        /**
         * @private
         * @type {List.<ParticleParameter>}
         */
        this.parameters = new List();
    }

    /**
     *
     * @param {ParticleParameter} parameter
     */
    add(parameter) {
        //ensure that no parameter with the same name exists
        const existingParameter = this.getParameterByName(parameter.name);

        if (existingParameter !== undefined) {
            throw new Error(`Parameter with name '${parameter.name}' already exists`);
        }

        this.parameters.add(parameter);
    }

    /**
     *
     * @param {string} name
     * @returns {ParticleParameter|undefined}
     */
    getParameterByName(name) {
        return this.parameters.find(function (p) {
            return p.name === name;
        });
    }

    build() {
        this.parameters.forEach(function (param) {
            param.build();
        });
    }

    /**
     *
     * @returns {Array<ParticleParameter>}
     */
    asArray() {
        return this.parameters.asArray();
    }

    /**
     *
     * @returns {number}
     */
    hash() {
        return this.parameters.hash();
    }

    /**
     *
     * @param {ParameterSet} other
     * @returns {boolean}
     */
    equals(other) {
        return this.parameters.equals(other.parameters);
    }

    /**
     *
     * @param {number} count
     */
    setTrackCount(count) {

        const parameters = this.parameters;
        const n = parameters.length;

        for (let i = 0; i < n; i++) {

            const p = parameters.get(i);
            p.setTrackCount(count);

        }

    }

    /**
     *
     * @param {number} index
     * @param {ParameterTrackSet} trackSet
     */
    setTracks(index, trackSet) {
        const self = this;

        trackSet.forEach(function (track) {
            const name = track.name;

            const parameter = self.getParameterByName(name);

            if (parameter === undefined) {
                throw new Error(`Failed to add track with name '${name}', no parameter exists with that name`);
            }

            parameter.setTrack(index, track.track);
        });
    }

    toJSON() {
        return this.parameters.toJSON();
    }

    fromJSON(json) {
        this.parameters.fromJSON(json, ParticleParameter);
    }

    /**
     *
     * @param {BinaryBuffer} buffer
     */
    toBinaryBuffer(buffer) {
        this.parameters.toBinaryBuffer(buffer);
    }

    /**
     *
     * @param {BinaryBuffer} buffer
     */
    fromBinaryBuffer(buffer) {
        this.parameters.fromBinaryBuffer(buffer, ParticleParameter);
    }
}