import { assert } from "../../assert.js";
import BinaryField from "./Field.js";

class Type {
    /**
     *
     * @param {String} name
     * @constructor
     */
    constructor(name) {
        assert.equal(typeof name, "string", `Name must be of type "string", instead was "${typeof name}"`);

        /**
         *
         * @type {String}
         */
        this.name = name;
        /**
         *
         * @type {Array.<Field>}
         */
        this.fields = [];
        /**
         *
         * @type {boolean}
         */
        this.isPrimitive = false;
        /**
         *
         * @type {boolean}
         */
        this.isFixedLength = false;
    }

    /**
     *
     * @param {String} name
     * @returns {Field|null}
     */
    getFieldByName(name) {
        const fields = this.fields;
        let i = 0;
        const l = fields.length;
        for (; i < l; i++) {
            const field = fields[i];
            if (field.name === name) {
                return field;
            }
        }
        return null;
    }

    /**
     *
     * @param {String} name
     * @param {Type} type
     * @returns {Field}
     */
    addField(name, type) {
        let field = this.getFieldByName(name);
        if (field !== null) {
            throw new Error("Binary structure already contains a field named '" + name + "'");
        } else {
            field = new BinaryField(name, type);
            this.fields.push(field);
        }
        return field;
    }

    /**
     *
     * @returns {Type}
     */
    clone() {
        const result = new Type();
        result.fields = this.fields.slice();
        return result;
    }
}


export default Type;
