/*
 * SPDX-FileCopyrightText: 2019-2026 Mattia Basaglia <dev@dragon.best>
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 */

#pragma once

#include "glaxnimate/model/property/reference_property.hpp"
#include "glaxnimate/model/stretchable_time.hpp"
#include "glaxnimate/model/shapes/composable/composable.hpp"
#include "glaxnimate/model/assets/composition.hpp"


namespace glaxnimate::model {

class PreCompLayer : public Composable
{
    GLAXNIMATE_OBJECT(PreCompLayer)

    GLAXNIMATE_SUBOBJECT(StretchableTime, timing)
    GLAXNIMATE_PROPERTY_REFERENCE(Composition, composition, &PreCompLayer::valid_precomps, &PreCompLayer::is_valid_precomp, &PreCompLayer::composition_changed)
    GLAXNIMATE_PROPERTY(QSizeF, size, {})
    GLAXNIMATE_PROPERTY(bool, unbounded, false, {}, {}, PropertyTraits::Visual)

public:
    using Composable::Composable;


    QIcon tree_icon() const override;
    QString type_name_human() const override;
    void set_time(FrameTime t) override;

    /**
     * \brief Returns the (frame) time relative to this layer
     *
     * Useful for stretching / remapping etc.
     * Always use this to get animated property values,
     * even if currently it doesn't do anything
     */
    FrameTime relative_time(FrameTime time) const;

    QRectF local_bounding_rect(FrameTime t) const override;
    QTransform local_transform_matrix(model::FrameTime t) const override;

    void add_shapes(model::FrameTime t, math::bezier::MultiBezier & bez, const QTransform& transform) const override;

    glaxnimate::math::bezier::MultiBezier to_clip(model::FrameTime t) const override;

Q_SIGNALS:
    void opacity_changed(float op);
    void composition_changed();

protected:
    glaxnimate::math::bezier::MultiBezier to_painter_path_impl(model::FrameTime t) const override;
    void on_paint(renderer::Renderer*, FrameTime, PaintMode, model::Modifier*) const override;
    void on_composition_changed(model::Composition* old_comp, model::Composition* new_comp) override;

private:
    std::vector<DocumentNode*> valid_precomps() const;
    bool is_valid_precomp(DocumentNode* node) const;
    void refresh_owner_composition();

};

} // namespace glaxnimate::model
