import '../../../../globals.js';
// Copyright 2024, University of Colorado Boulder
/**
 * Represents a string of WGSL code (which may have dependencies which it can add to a blueprint).
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */
import { alpenglow, decimal, f32, i32, i32Hex, u32, u32Hex } from '../../imports.js';
export default class WGSLString {
}
alpenglow.register('WGSLString', WGSLString);
export class WGSLStringLiteral extends WGSLString {
    constructor(value) {
        super();
        this.value = value;
    }
    withBlueprint(blueprint) {
        return this.value;
    }
}
alpenglow.register('WGSLStringLiteral', WGSLStringLiteral);
export class WGSLStringFunction extends WGSLString {
    constructor(value) {
        super();
        this.value = value;
    }
    withBlueprint(blueprint) {
        return this.value(blueprint);
    }
}
alpenglow.register('WGSLStringFunction', WGSLStringFunction);
export class WGSLStringAccumulator extends WGSLString {
    constructor() {
        super(...arguments);
        this.values = [];
    }
    add(value) {
        this.values.push(value);
    }
    withBlueprint(blueprint) {
        let string = '';
        for (let i = 0; i < this.values.length; i++) {
            string += this.values[i].withBlueprint(blueprint);
        }
        return string;
    }
}
alpenglow.register('WGSLStringAccumulator', WGSLStringAccumulator);
// TODO: use this where we need
export class WGSLModule extends WGSLString {
    constructor(name, declarations) {
        super();
        this.name = name;
        this.declarations = declarations;
    }
    withBlueprint(blueprint) {
        blueprint.add(this.name, this.declarations);
        return '';
    }
}
alpenglow.register('WGSLModule', WGSLModule);
export class WGSLMainModule extends WGSLModule {
    constructor(slots, declarations) {
        super('main', declarations);
        this.slots = slots;
    }
    withBlueprint(blueprint) {
        this.slots.forEach(slot => {
            slot.withBlueprint(blueprint);
        });
        return super.withBlueprint(blueprint);
    }
}
alpenglow.register('WGSLMainModule', WGSLMainModule);
export class WGSLReferenceModule extends WGSLString {
    constructor(name, declarations) {
        super();
        this.name = name;
        this.declarations = declarations;
    }
    withBlueprint(blueprint) {
        blueprint.add(this.name, this.declarations);
        return this.name;
    }
}
alpenglow.register('WGSLReferenceModule', WGSLReferenceModule);
export class WGSLStringModule extends WGSLString {
    constructor(name, string, declarations) {
        super();
        this.name = name;
        this.string = string;
        this.declarations = declarations;
    }
    withBlueprint(blueprint) {
        blueprint.add(this.name, this.declarations);
        return this.string.withBlueprint(blueprint);
    }
}
alpenglow.register('WGSLStringModule', WGSLStringModule);
export class WGSLSlot extends WGSLModule {
    constructor(name, slot, bindingType) {
        super(name, wgsl ``);
        this.slot = slot;
        this.bindingType = bindingType;
    }
    withBlueprint(blueprint) {
        blueprint.addSlot(this.name, this.slot, this.bindingType);
        return '';
    }
}
alpenglow.register('WGSLSlot', WGSLSlot);
export const wgslString = (value) => {
    return new WGSLStringLiteral(value);
};
alpenglow.register('wgslString', wgslString);
export const wgslFunction = (value) => {
    return new WGSLStringFunction(value);
};
alpenglow.register('wgslFunction', wgslFunction);
export const wgslBlueprint = (value) => {
    return new WGSLStringFunction(blueprint => value(blueprint).withBlueprint(blueprint));
};
alpenglow.register('wgslBlueprint', wgslBlueprint);
// For tagged template literals
export const wgsl = (strings, ...values) => {
    return new WGSLStringFunction(blueprint => {
        let string = '';
        for (let i = 0; i < strings.length; i++) {
            string += strings[i];
            if (i < values.length) {
                const value = values[i];
                string += value.withBlueprint(blueprint);
            }
        }
        return string;
    });
};
alpenglow.register('wgsl', wgsl);
// TODO: ideally once we're to a point, we can replace the normal versions with these
// TODO: also, hopefully we can rename them (so we work with the good type) before then
export const decimalS = (n) => wgslString(decimal(n));
alpenglow.register('decimalS', decimalS);
export const u32S = (n) => wgslString(u32(n));
alpenglow.register('u32S', u32S);
export const u32HexS = (n) => wgslString(u32Hex(n));
alpenglow.register('u32HexS', u32HexS);
export const i32S = (n) => wgslString(i32(n));
alpenglow.register('i32S', i32S);
export const i32HexS = (n) => wgslString(i32Hex(n));
alpenglow.register('i32HexS', i32HexS);
export const f32S = (n) => wgslString(f32(n));
alpenglow.register('f32S', f32S);
export const wgslJoin = (separator, values) => {
    return new WGSLStringFunction(blueprint => {
        let string = '';
        for (let i = 0; i < values.length; i++) {
            if (i > 0) {
                string += separator;
            }
            string += values[i].withBlueprint(blueprint);
        }
        return string;
    });
};
alpenglow.register('wgslJoin', wgslJoin);
export const wgslMapJoin = (separator, values, mapper) => {
    return new WGSLStringFunction(blueprint => {
        let string = '';
        for (let i = 0; i < values.length; i++) {
            if (i > 0) {
                string += separator;
            }
            string += mapper(values[i]).withBlueprint(blueprint);
        }
        return string;
    });
};
alpenglow.register('wgslMapJoin', wgslMapJoin);
export const wgslOneLine = (value) => {
    return new WGSLStringFunction(blueprint => {
        return value.withBlueprint(blueprint).replace(/\n/g, ' ');
    });
};
alpenglow.register('wgslOneLine', wgslOneLine);
export const wgslWith = (value, ...modules) => {
    return new WGSLStringFunction(blueprint => {
        modules.forEach(module => {
            module.withBlueprint(blueprint);
        });
        return value.withBlueprint(blueprint);
    });
};
alpenglow.register('wgslWith', wgslWith);
//# sourceMappingURL=WGSLString.js.map