import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial";
import { Color3 } from "@babylonjs/core/Maths/math.color";
import { MmdPluginMaterialSphereTextureBlendMode } from "./mmdPluginMaterial";
import { MmdPluginMaterial } from "./mmdPluginMaterial";
/**
 * MMD standard material
 *
 * This material is an extension of the `StandardMaterial` and includes features for mmd's shading specifications
 *
 * The user can decide whether to activate each mmd shading specification
 *
 * If you disable all features, it behaves the same as `StandardMaterial`
 */
export class MmdStandardMaterial extends StandardMaterial {
    _pluginMaterial;
    _renderOutline = false;
    /**
     * Outline width (default: 0.01)
     */
    outlineWidth = 0.01;
    /**
     * Outline color (default: (0, 0, 0))
     */
    outlineColor = new Color3(0, 0, 0);
    /**
     * Outline alpha (default: 1.0)
     */
    outlineAlpha = 1.0;
    /**
     * Create a new MMD standard material
     * @param name Define the name of the material in the scene
     * @param scene The scene the material belongs to
     */
    constructor(name, scene) {
        super(name, scene);
        this.specularColor = new Color3(0, 0, 0);
        const pluginMaterial = this._pluginMaterial = new MmdPluginMaterial(this);
        pluginMaterial.isEnabled = true;
        pluginMaterial.ignoreDiffuseWhenToonTextureIsNull = true;
    }
    /**
     * Get or set sphere texture
     */
    get sphereTexture() {
        return this._pluginMaterial.sphereTexture;
    }
    set sphereTexture(value) {
        this._pluginMaterial.sphereTexture = value;
    }
    /**
     * Get or set sphere texture blend mode (default: MmdPluginMaterialSphereTextureBlendMode.Add)
     */
    get sphereTextureBlendMode() {
        return this._pluginMaterial.sphereTextureBlendMode;
    }
    set sphereTextureBlendMode(value) {
        this._pluginMaterial.sphereTextureBlendMode = value;
    }
    /**
     * Get or set toon texture
     */
    get toonTexture() {
        return this._pluginMaterial.toonTexture;
    }
    set toonTexture(value) {
        this._pluginMaterial.toonTexture = value;
    }
    /**
     * If toe on texture is not set, decide whether to treat it as if it had white toon texture applied (default: true)
     *
     * In general, in order to get a stylized rendering, it's better to do true
     *
     * and if you want a more realistic rendering, it's better to do false
     */
    get ignoreDiffuseWhenToonTextureIsNull() {
        return this._pluginMaterial.ignoreDiffuseWhenToonTextureIsNull;
    }
    set ignoreDiffuseWhenToonTextureIsNull(value) {
        this._pluginMaterial.ignoreDiffuseWhenToonTextureIsNull = value;
    }
    /**
     * Get or set whether to apply ambient color to diffuse color (default: true)
     *
     * In babylon.js, the ambient color is not affected by the light source, but in mmd, it is
     *
     * Therefore, if you want to get a more mmd-like rendering, it is better to do true
     */
    get applyAmbientColorToDiffuse() {
        return this._pluginMaterial.applyAmbientColorToDiffuse;
    }
    set applyAmbientColorToDiffuse(value) {
        this._pluginMaterial.applyAmbientColorToDiffuse = value;
    }
    /**
     * Get or set whether to use the texture multiplicative color (default: (1, 1, 1, 1))
     *
     * If this property is first accessed as set, the shader is recompiled to support texture color properties
     *
     * After that, the feature is no longer turned off to prevent shader recompilation
     *
     * These features are subject to change at a later date
     */
    get textureMultiplicativeColor() {
        this._pluginMaterial.useTextureColor = true;
        return this._pluginMaterial.textureMultiplicativeColor;
    }
    set textureMultiplicativeColor(value) {
        this._pluginMaterial.useTextureColor = true;
        this._pluginMaterial.textureMultiplicativeColor = value;
    }
    /**
     * Get or set whether to use the texture additive color (default: (0, 0, 0, 0))
     *
     * If this property is first accessed as set, the shader is recompiled to support texture color properties
     *
     * After that, the feature is no longer turned off to prevent shader recompilation
     *
     * These features are subject to change at a later date
     */
    get textureAdditiveColor() {
        this._pluginMaterial.useTextureColor = true;
        return this._pluginMaterial.textureAdditiveColor;
    }
    set textureAdditiveColor(value) {
        this._pluginMaterial.useTextureColor = true;
        this._pluginMaterial.textureAdditiveColor = value;
    }
    /**
     * Get or set whether to use the sphere texture multiplicative color (default: (1, 1, 1, 1))
     *
     * If this property is first accessed as set, the shader is recompiled to support texture color properties
     *
     * After that, the feature is no longer turned off to prevent shader recompilation
     *
     * These features are subject to change at a later date
     */
    get sphereTextureMultiplicativeColor() {
        this._pluginMaterial.useSphereTextureColor = true;
        return this._pluginMaterial.sphereTextureMultiplicativeColor;
    }
    set sphereTextureMultiplicativeColor(value) {
        this._pluginMaterial.useSphereTextureColor = true;
        this._pluginMaterial.sphereTextureMultiplicativeColor = value;
    }
    /**
     * Get or set whether to use the sphere texture additive color (default: (0, 0, 0, 0))
     *
     * If this property is first accessed as set, the shader is recompiled to support texture color properties
     *
     * After that, the feature is no longer turned off to prevent shader recompilation
     *
     * These features are subject to change at a later date
     */
    get sphereTextureAdditiveColor() {
        this._pluginMaterial.useSphereTextureColor = true;
        return this._pluginMaterial.sphereTextureAdditiveColor;
    }
    set sphereTextureAdditiveColor(value) {
        this._pluginMaterial.useSphereTextureColor = true;
        this._pluginMaterial.sphereTextureAdditiveColor = value;
    }
    /**
     * Get or set whether to use the toon texture multiplicative color (default: (1, 1, 1, 1))
     *
     * If this property is first accessed as set, the shader is recompiled to support texture color properties
     *
     * After that, the feature is no longer turned off to prevent shader recompilation
     *
     * These features are subject to change at a later date
     */
    get toonTextureMultiplicativeColor() {
        this._pluginMaterial.useToonTextureColor = true;
        return this._pluginMaterial.toonTextureMultiplicativeColor;
    }
    set toonTextureMultiplicativeColor(value) {
        this._pluginMaterial.useToonTextureColor = true;
        this._pluginMaterial.toonTextureMultiplicativeColor = value;
    }
    /**
     * Get or set whether to use the toon texture additive color (default: (0, 0, 0, 0))
     *
     * If this property is first accessed as set, the shader is recompiled to support texture color properties
     *
     * After that, the feature is no longer turned off to prevent shader recompilation
     *
     * These features are subject to change at a later date
     */
    get toonTextureAdditiveColor() {
        this._pluginMaterial.useToonTextureColor = true;
        return this._pluginMaterial.toonTextureAdditiveColor;
    }
    set toonTextureAdditiveColor(value) {
        this._pluginMaterial.useToonTextureColor = true;
        this._pluginMaterial.toonTextureAdditiveColor = value;
    }
    /**
     * Whether to use the outline rendering (default: false)
     */
    get renderOutline() {
        return this._renderOutline;
    }
    set renderOutline(value) {
        // Lazy Load the component
        if (value) {
            this.getScene().getMmdOutlineRenderer?.();
        }
        this._renderOutline = value;
    }
    /**
     * Specifies if the material will require alpha blending
     * @returns a boolean specifying if alpha blending is needed
     */
    needAlphaBlending() {
        if (this._disableAlphaBlending) {
            return false;
        }
        return super.needAlphaBlending() ||
            (this._pluginMaterial.sphereTexture !== null &&
                this._pluginMaterial.sphereTextureBlendMode === MmdPluginMaterialSphereTextureBlendMode.Multiply);
    }
}
