import { getEngine } from '../../../app/api.js';
import '../../../scene/scene.js';
import { Vector2 } from '@zephyr3d/base';
import '../../../values.js';
import '../../../render/render_queue.js';
import '../../../render/primitive.js';
import '@zephyr3d/device';
import '../../../material/shader/helper.js';
import '../../../material/lambert.js';
import '../../../material/blinn.js';
import '../../../material/unlit.js';
import '../../../material/particle.js';
import '../../../material/meshmaterial.js';
import '../../../material/grassmaterial.js';
import '../../../material/terrain-cm.js';
import '../../../material/pbrmr.js';
import '../../../material/pbrsg.js';
import '../../../material/pbrblueprint.js';
import { SpriteMaterial } from '../../../material/sprite.js';
import '../../../material/sprite_std.js';
import { defineProps } from '../types.js';
import '../../blueprint/material/texture.js';
import '../../../render/rendergraph/forward_plus_builder.js';
import '../../../render/sky.js';
import '../../../render/clipmap.js';
import '../../../shaders/atmosphere.js';
import { GraphNode } from '../../../scene/graph_node.js';
import '../../../shadow/shadowmapper.js';
import '../../../scene/mesh.js';
import '../../../scene/basesprite.js';
import { Sprite } from '../../../scene/sprite.js';
import '../../../scene/water.js';
import '../../../scene/scene_node.js';
import '../../../scene/particlesys.js';
import '../../../scene/batchgroup.js';
import '../../../scene/terrain-cm/terrain-cm.js';
import '../../../scene/terrain-cm/grass.js';
import '../../../scene/raycast_visitor.js';
import { meshInstanceClsMap } from './common.js';

/** @internal */ function getSpriteClass() {
    return {
        ctor: Sprite,
        name: 'Sprite',
        parent: GraphNode,
        noTitle: true,
        createFunc (ctx) {
            const node = new Sprite(ctx.scene);
            node.parent = ctx;
            return {
                obj: node
            };
        },
        getProps () {
            return defineProps([
                {
                    name: 'Anchor',
                    description: 'Sprite pivot in normalized UV space',
                    type: 'vec2',
                    default: [
                        0.5,
                        0.5
                    ],
                    get (value) {
                        value.num[0] = this.anchorX;
                        value.num[1] = this.anchorY;
                    },
                    set (value) {
                        this.anchorX = value.num[0];
                        this.anchorY = value.num[1];
                    }
                },
                {
                    name: 'UVTopLeft',
                    description: 'Top-left UV coordinate of the sprite image',
                    type: 'vec2',
                    default: [
                        0,
                        0
                    ],
                    get (value) {
                        const lt = this.uvTopLeft;
                        value.num[0] = lt.x;
                        value.num[1] = lt.y;
                    },
                    set (value) {
                        this.uvTopLeft = new Vector2(value.num[0], value.num[1]);
                    }
                },
                {
                    name: 'UVBottomRight',
                    description: 'Bottom-right UV coordinate of the sprite image',
                    type: 'vec2',
                    default: [
                        1,
                        1
                    ],
                    get (value) {
                        const rb = this.uvBottomRight;
                        value.num[0] = rb.x;
                        value.num[1] = rb.y;
                    },
                    set (value) {
                        this.uvBottomRight = new Vector2(value.num[0], value.num[1]);
                    }
                },
                {
                    name: 'Material',
                    description: 'Sprite material object',
                    type: 'object',
                    options: {
                        mimeTypes: [
                            'application/vnd.zephyr3d.material+json'
                        ]
                    },
                    get (value) {
                        const m = this.material?.coreMaterial;
                        value.str[0] = getEngine().resourceManager.getAssetId(m) ?? '';
                    },
                    async set (value) {
                        if (value?.str[0]) {
                            const material = await getEngine().resourceManager.fetchMaterial(value.str[0]);
                            if (material && material instanceof SpriteMaterial) {
                                this.material = material;
                            } else {
                                console.error(material ? `Not a sprite material: ${value.str[0]}` : `Material not found: ${value.str[0]}`);
                            }
                        }
                    }
                },
                {
                    name: 'Geometry Instance',
                    description: 'If true, the sprite uses a material instance',
                    type: 'bool',
                    get (value) {
                        value.bool[0] = !!this.material?.$isInstance;
                    },
                    set (value) {
                        this.material = (value.bool[0] ? this.material?.createInstance() : this.material?.coreMaterial) ?? null;
                    }
                },
                {
                    name: 'MaterialInstanceUniforms',
                    description: 'Per-instance overrides for sprite material uniforms',
                    type: 'object',
                    phase: 1,
                    options: {
                        objectTypes: []
                    },
                    isHidden () {
                        return this.material && !this.material?.$isInstance;
                    },
                    isNullable () {
                        return true;
                    },
                    get (value) {
                        const C = this.material?.$isInstance ? meshInstanceClsMap.get(this.material.coreMaterial.constructor) : null;
                        value.object[0] = C ? new C.C(this.material) : null;
                    },
                    set (value) {
                        if (value.object[0]) {
                            this.material = value.object[0]?.material;
                        }
                    }
                }
            ]);
        }
    };
}

export { getSpriteClass };
//# sourceMappingURL=sprite.js.map
