// ProceduralTextureNode.hpp
#pragma once

#include "TextureNode.hpp"
#include "glm/vec4.hpp"

namespace MayaFlux::Nodes::GpuSync {

/**
 * @class ProceduralTextureNode
 * @brief Pixels generated by arbitrary functions
 *
 * Philosophy:
 * - Pixels are just numbers - transform them freely
 * - Algorithm-driven generation, not file loading
 * - Live coding friendly - hot-swap generation functions
 * - Use lambda captures for state - no parameter system
 *
 * Usage:
 * ```cpp
 * // Static pattern
 * auto checker = std::make_shared<ProceduralTextureNode>(512, 512,
 *     [](uint32_t x, uint32_t y, uint32_t w, uint32_t h) -> glm::vec4 {
 *         bool is_white = ((x / 32) + (y / 32)) % 2 == 0;
 *         float value = is_white ? 1.0f : 0.0f;
 *         return glm::vec4(value, value, value, 1.0f);
 *     });
 *
 * // Animated gradient via captures
 * float time = 0.0f;
 * auto gradient = std::make_shared<ProceduralTextureNode>(512, 512,
 *     [&time](uint32_t x, uint32_t y, uint32_t w, uint32_t h) {
 *         float u = float(x) / float(w);
 *         float v = float(y) / float(h);
 *         return glm::vec4(u, v, std::sin(time), 1.0f);
 *     });
 *
 * // Each frame:
 * time += 0.016f;
 * gradient->compute_frame(); // Sees updated 'time' automatically
 * ```
 */
class MAYAFLUX_API ProceduralTextureNode : public TextureNode {
public:
    /**
     * @brief Pixel generator function signature
     * @param x Pixel X coordinate
     * @param y Pixel Y coordinate
     * @param width Texture width (for normalization)
     * @param height Texture height (for normalization)
     * @return RGBA color for this pixel
     */
    using PixelGenerator = std::function<glm::vec4(
        uint32_t x, uint32_t y,
        uint32_t width, uint32_t height)>;

    /**
     * @brief Create procedural texture with default (black) generator
     * @param width Texture width
     * @param height Texture height
     */
    ProceduralTextureNode(uint32_t width, uint32_t height);

    /**
     * @brief Create procedural texture with custom generator
     * @param width Texture width
     * @param height Texture height
     * @param generator Pixel generation function
     */
    ProceduralTextureNode(uint32_t width, uint32_t height, PixelGenerator generator);

    /**
     * @brief Set pixel generator function
     * @param generator New generation function
     *
     * Marks texture as dirty - next compute_frame() will regenerate all pixels.
     * Use this for hot-swapping algorithms, not for per-frame updates.
     */
    void set_generator(PixelGenerator generator);

    /**
     * @brief Compute frame - generate all pixels via generator function
     */
    void compute_frame() override;

private:
    PixelGenerator m_generator;
};

} // namespace MayaFlux::Nodes::GpuSync
