import type { AnyFragmentInputBuiltin, AnyFragmentOutputBuiltin, OmitBuiltins } from '../../builtin.ts';
import type { UndecorateRecord } from '../../data/dataTypes.ts';
import type { InstanceToSchema } from '../../data/instanceToSchema.ts';
import type { BaseData, Decorated, Interpolate, Location, Vec4f, Vec4i, Vec4u, WgslStruct } from '../../data/wgslTypes.ts';
import { type TgpuNamable } from '../../shared/meta.ts';
import { $internal } from '../../shared/symbols.ts';
import type { Prettify } from '../../shared/utilityTypes.ts';
import type { AnyAutoCustoms, AutoFragmentIn, AutoFragmentOut } from './autoIO.ts';
import type { BaseIOData, InferIO, IOLayout, IORecord } from './fnTypes.ts';
import { type IOLayoutToSchema } from './ioSchema.ts';
export type FragmentInConstrained = IORecord<BaseIOData | Decorated<BaseIOData, (Location | Interpolate)[]> | AnyFragmentInputBuiltin>;
export type VertexOutToVarying<T> = OmitBuiltins<{
    [K in keyof T]: InstanceToSchema<T[K]>;
}>;
type FragmentColorValue = Vec4f | Vec4i | Vec4u;
export type FragmentOutConstrained = IOLayout<FragmentColorValue | Decorated<FragmentColorValue, (Location | Interpolate)[]> | AnyFragmentOutputBuiltin>;
/**
 * Describes a fragment entry function signature (its arguments, return type and targets)
 */
type TgpuFragmentFnShellHeader<FragmentIn extends TgpuFragmentFn.In = TgpuFragmentFn.In, FragmentOut extends TgpuFragmentFn.Out = TgpuFragmentFn.Out> = {
    readonly in: FragmentIn | undefined;
    readonly out: FragmentOut;
    readonly returnType: IOLayoutToSchema<FragmentOut>;
    readonly entryPoint: 'fragment';
};
type CleanIO<T> = T extends Record<string, BaseData> ? Prettify<UndecorateRecord<OmitBuiltins<T>>> : Prettify<UndecorateRecord<OmitBuiltins<{
    a: T;
}>>> extends {
    a: infer Result;
} ? Result : Record<string, never>;
/**
 * Describes a fragment entry function signature (its arguments, return type and targets).
 * Allows creating tgpu fragment functions by calling this shell
 * and passing the implementation (as WGSL string or JS function) as the argument.
 */
export interface TgpuFragmentFnShell<out TIn extends TgpuFragmentFn.In = TgpuFragmentFn.In, out TOut extends TgpuFragmentFn.Out = TgpuFragmentFn.Out> extends TgpuFragmentFnShellHeader<TIn, TOut> {
    /**
     * Creates a type-safe implementation of this signature
     */
    (implementation: (input: InferIO<TIn>, out: TOut extends IORecord ? WgslStruct<TOut> : TOut) => InferIO<TOut>): TgpuFragmentFn<CleanIO<TIn>, CleanIO<TOut>>;
    /**
     * @param implementation
     *   Raw WGSL function implementation with header and body
     *   without `fn` keyword and function name
     *   e.g. `"(x: f32) -> f32 { return x; }"`;
     */
    (implementation: string): TgpuFragmentFn<CleanIO<TIn>, CleanIO<TOut>>;
    (strings: TemplateStringsArray, ...values: unknown[]): TgpuFragmentFn<CleanIO<TIn>, CleanIO<TOut>>;
}
export interface TgpuFragmentFn<in Varying extends TgpuFragmentFn.In = Record<string, never>, out Output extends TgpuFragmentFn.Out = TgpuFragmentFn.Out> extends TgpuNamable {
    readonly [$internal]: true;
    readonly shell: TgpuFragmentFnShellHeader<Varying, Output>;
    readonly outputType: IOLayoutToSchema<Output>;
    $uses(dependencyMap: Record<string, unknown>): this;
}
export declare namespace TgpuFragmentFn {
    type In = Record<string, BaseData>;
    type Out = Record<string, BaseData> | BaseData;
    type AutoIn<T extends AnyAutoCustoms> = AutoFragmentIn<T>;
    type AutoOut<T extends AnyAutoCustoms = AnyAutoCustoms> = AutoFragmentOut<T>;
    type AutoInEmpty = AutoFragmentIn<Record<string, never>>;
}
export declare function fragmentFn<FragmentOut extends FragmentOutConstrained>(options: {
    out: FragmentOut;
}): TgpuFragmentFnShell<{}, FragmentOut>;
export declare function fragmentFn<FragmentIn extends FragmentInConstrained, FragmentOut extends FragmentOutConstrained>(options: {
    in: FragmentIn;
    out: FragmentOut;
}): TgpuFragmentFnShell<FragmentIn, FragmentOut>;
export declare function isTgpuFragmentFn<FragmentIn extends FragmentInConstrained, FragmentOut extends FragmentOutConstrained>(value: unknown): value is TgpuFragmentFn<FragmentIn, FragmentOut>;
export {};
