
import Foundation
import Metal

class ChevronSimple3DAuraRenderable: ConfiguredQuadRenderable<ChevronSimple3DAuraRenderable.Config> {
    public struct Config: QuadRenderConfiguration {
        let display_size: ADVector2
        let fractal_noise_x: ADFloat
        let fractal_noise_y: ADFloat
        let fractal_noise_z: ADFloat
        let fractal_uniform_scale: ADFloat

        let grain_noise_z: ADFloat
        let grain_noise_scale: ADFloat

        let circle_mask_radius: ADFloat

        let background_color: ADVector3
        let color_a: ADVector3
        let color_b: ADVector3
        let color_c: ADVector3
        let color_d: ADVector3
        let color_e: ADVector3
        let color_f: ADVector3

        let mix_point_start: ADFloat
        let mix_point_background: ADFloat
        let mix_point_backgroundA: ADFloat
        let mix_point_AB: ADFloat
        let mix_point_BC: ADFloat
        let mix_point_end: ADFloat
        let mix_point_min_value: ADFloat

        let chevron_scale: ADFloat
        let chevron_offset_x: ADFloat
        let chevron_offset_y: ADFloat
        let chevron_rotation: ADFloat

        let chevron_aura_b_fractal_noise_z_offset: ADFloat

        let repeat_uv_mix_ratio: ADFloat // 1.0 is the same as (isUsingRepeatUVMixRatio == true)
        let repeat_uv_scalar: ADFloat

        public init(
            displaySize: ADVector2 = .ones,
            fractalNoiseX: ADFloat = .zero,
            fractalNoiseY: ADFloat = .zero,
            fractalNoiseZ: ADFloat = .zero,
            fractalUniformScale: ADFloat = .zero,
            grainNoiseZ: ADFloat = .zero,
            grainNoiseScale: ADFloat = 1.0,
            circleMaskRadius: ADFloat = 0.25,
            backgroundColor: ADVector3 = .zero,
            colorA: ADVector3 = .zero,
            colorB: ADVector3 = .init(x: 0.5, y: 0.5, z: 0.5),
            colorC: ADVector3 = .ones,
            colorD: ADVector3 = .zero,
            colorE: ADVector3 = .init(x: 0.5, y: 0.5, z: 0.5),
            colorF: ADVector3 = .ones,
            mixPointStart: ADFloat = -0.2,
            mixPointBackground: ADFloat = -0.1,
            mixPointBackgroundA: ADFloat = 0.0,
            mixPointAB: ADFloat = 0.2,
            mixPointBC: ADFloat = 0.4,
            mixPointEnd: ADFloat = 2.0,
            mixPointMinValue: ADFloat = 0.01,
            chevronScale: ADFloat = 10.0,
            chevronOffsetX: ADFloat = .zero,
            chevronOffsetY: ADFloat = .zero,
            chevronRotation: ADFloat = 0.785398163397448, // 0.125 * 2.0 * PI
            chevronAuraBFractalNoiseZOffset: ADFloat = 0.0,
            repeatUvMixRatio: ADFloat = .zero, // 1.0 is the same as (isUsingRepeatUVMixRatio == true)
            repeatUvScalar: ADFloat = .zero
        ) {
            display_size = displaySize
            fractal_noise_x = fractalNoiseX
            fractal_noise_y = fractalNoiseY
            fractal_noise_z = fractalNoiseZ
            fractal_uniform_scale = fractalUniformScale
            grain_noise_z = grainNoiseZ
            grain_noise_scale = grainNoiseScale
            circle_mask_radius = circleMaskRadius
            background_color = backgroundColor

            color_a = colorA
            color_b = colorB
            color_c = colorC
            color_d = colorD
            color_e = colorE
            color_f = colorF

            mix_point_start = mixPointStart
            mix_point_background = mixPointBackground
            mix_point_backgroundA = mixPointBackgroundA
            mix_point_AB = mixPointAB
            mix_point_BC = mixPointBC
            mix_point_end = mixPointEnd
            mix_point_min_value = mixPointMinValue

            chevron_scale = chevronScale
            chevron_offset_x = chevronOffsetX
            chevron_offset_y = chevronOffsetY
            chevron_rotation = chevronRotation
            chevron_aura_b_fractal_noise_z_offset = chevronAuraBFractalNoiseZOffset

            repeat_uv_mix_ratio = repeatUvMixRatio
            repeat_uv_scalar = repeatUvScalar
        }

        public static var defaultConfiguration: Config {
            return Config()
        }
    }

    override public var configureAction: ConfigureAction {
        return { encoder in
            super.configureAction(encoder)
        }
    }

    override var fragmentShaderName: String {
        return "chevron_simplex_3d_aura_frag"
    }
}
