"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ListStore = exports.ListStoreFactoryWithDefault = exports.ListStoreFactory = void 0;
exports.fromList = fromList;
// Default implementation
class ListStoreFactory {
    constructor(sourceKind) {
        this.sourceKind = sourceKind;
    }
    createStoreFromList(items) {
        return new ListStore(this.sourceKind, [...items]);
    }
}
exports.ListStoreFactory = ListStoreFactory;
class ListStoreFactoryWithDefault extends ListStoreFactory {
    constructor(sourceKind, create) {
        super(sourceKind);
        this.create = create;
    }
    createStoreFromSize(count) {
        const gs = [];
        for (let gid = 0; gid < count; gid++)
            gs[gid] = this.create();
        return this.createStoreFromList(gs);
    }
}
exports.ListStoreFactoryWithDefault = ListStoreFactoryWithDefault;
class ListStore {
    constructor(sourceKind, items) {
        this.sourceKind = sourceKind;
        this.items = items;
    }
    decideOrder() {
        return new ListOrder(this.sourceKind, this.items);
    }
}
exports.ListStore = ListStore;
class ListOrder {
    constructor(sourceKind, items) {
        this.sourceKind = sourceKind;
        this.items = items;
        this.length = items.length;
        this.revMap = new Map();
        for (let gid = 0; gid < items.length; gid++) {
            this.revMap.set(items[gid], gid);
        }
    }
    modIndex(ix) {
        return ((ix % this.length) + this.length) % this.length;
    }
    tryAt(gid) {
        return this.items[gid];
    }
    at(gid) {
        const g = this.items[gid];
        if (!g)
            throw new RangeError(`Missing Item #${gid} in ${this.sourceKind}`);
        else
            return g;
    }
    [Symbol.iterator]() {
        return this.items[Symbol.iterator]();
    }
    entries() {
        return this.items.entries();
    }
    tryReverse(g) {
        return this.revMap.get(g);
    }
    tryReverseFallback(g, fallback) {
        if (g == null)
            return fallback;
        const gid = this.revMap.get(g);
        if (gid == null)
            return fallback;
        else
            return gid;
    }
    reverse(g) {
        const gid = this.tryReverse(g);
        if (gid == null)
            throw new RangeError(`Missing Item in ${this.sourceKind}`);
        else
            return gid;
    }
}
function fromList(sourceKind, a) {
    return new ListOrder(sourceKind, a);
}
//# sourceMappingURL=index.js.map