import { ShaderLib, TangentSpaceNormalMap, UniformsUtils } from "three";
import { ForwardPlusThreeMaterial } from "./ForwardPlusThreeMaterial.js";

export class FPlusStandardMaterial extends ForwardPlusThreeMaterial {
    constructor() {
        const ml = ShaderLib.standard;

        const uniforms = UniformsUtils.clone(ml.uniforms);

        super({
            uniforms: uniforms,
            vertexShader: ml.vertexShader,
            fragmentShader: ml.fragmentShader,
        });

        /**
         *
         * @type {NormalMapTypes}
         */
        this.normalMapType = TangentSpaceNormalMap;
        /**
         *
         * @type {number}
         */
        this.emissiveIntensity = 1;

        /**
         * @type {boolean}
         */
        this.skinning = false;
    }

    get map() {
        return this.uniforms.map.value;
    }

    /**
     *
     * @param {Texture} v
     */
    set map(v) {
        this.uniforms.map.value = v;
    }

    /**
     *
     * @param {Texture} v
     */
    set normalMap(v) {
        this.uniforms.normalMap.value = v;
    }

    get normalMap() {
        return this.uniforms.normalMap.value;
    }

    get normalScale() {
        return this.uniforms.normalScale.value;
    }

    set normalScale(v) {
        this.uniforms.normalScale.value = v;
    }

    /**
     *
     * @param {Texture} v
     */
    set roughnessMap(v) {
        this.uniforms.roughnessMap.value = v;
    }

    /**
     *
     * @returns {Texture}
     */
    get roughnessMap() {
        return this.uniforms.roughnessMap.value;
    }

    /**
     *
     * @param {Texture} v
     */
    set metalnessMap(v) {
        this.uniforms.metalnessMap.value = v;
    }

    /**
     *
     * @returns {Texture}
     */
    get metalnessMap() {
        return this.uniforms.metalnessMap.value;
    }

    /**
     *
     * @returns {number}
     */
    get roughness() {
        return this.uniforms.roughness.value;
    }

    /**
     *
     * @param {number} v
     */
    set roughness(v) {
        this.uniforms.roughness.value = v;
    }

    /**
     *
     * @returns {number}
     */
    get metalness() {
        return this.uniforms.metalness.value;
    }

    /**
     *
     * @param {number} v
     */
    set metalness(v) {
        this.uniforms.metalness.value = v;
    }

    /**
     *
     * @returns {Texture}
     */
    get lightMap() {
        return this.uniforms.lightMap.value;
    }

    /**
     *
     * @param {Texture} v
     */
    set lightMap(v) {
        this.uniforms.lightMap.value = v;
    }

    /**
     *
     * @returns {number}
     */
    get lightMapIntensity() {
        return this.uniforms.lightMapIntensity.value;
    }

    /**
     *
     * @param {number} v
     */
    set lightMapIntensity(v) {
        this.uniforms.lightMapIntensity.value = v;
    }

    /**
     *
     * @returns {Texture}
     */
    get aoMap() {
        return this.uniforms.aoMap.value;
    }

    /**
     *
     * @param {Texture} v
     */
    set aoMap(v) {
        this.uniforms.aoMap.value = v;
    }

    /**
     *
     * @returns {number}
     */
    get aoMapIntensity() {
        return this.uniforms.aoMapIntensity.value;
    }

    /**
     *
     * @param {number} v
     */
    set aoMapIntensity(v) {
        this.uniforms.aoMapIntensity.value = v;
    }

    /**
     *
     * @param {Color} c
     */
    set emissive(c) {
        this.uniforms.emissive.value = c;
    }

    /**
     *
     * @returns {Color}
     */
    get emissive() {
        return this.uniforms.emissive.value;
    }

    /**
     *
     * @returns {Texture}
     */
    get emissiveMap() {
        return this.uniforms.emissiveMap.value;
    }

    /**
     *
     * @param {Texture} v
     */
    set emissiveMap(v) {
        this.uniforms.emissiveMap.value = v;
    }

    /**
     *
     * @returns {Texture}
     */
    get bumpMap() {
        return this.uniforms.bumpMap.value;
    }

    /**
     *
     * @param {Texture} v
     */
    set bumpMap(v) {
        this.uniforms.bumpMap.value = v;
    }

    /**
     *
     * @returns {number}
     */
    get bumpScale() {
        return this.uniforms.bumpScale.value;
    }

    /**
     *
     * @param {number} v
     */
    set bumpScale(v) {
        this.uniforms.bumpScale.value = v;
    }

    /**
     *
     * @returns {Texture}
     */
    get displacementMap() {
        return this.uniforms.displacementMap.value;
    }

    /**
     *
     * @param {Texture} v
     */
    set displacementMap(v) {
        this.uniforms.displacementMap.value = v;
    }

    /**
     *
     * @returns {number}
     */
    get displacementScale() {
        return this.uniforms.displacementScale.value;
    }

    /**
     *
     * @param {number} v
     */
    set displacementScale(v) {
        this.uniforms.displacementScale.value = v;
    }

    /**
     *
     * @returns {number}
     */
    get displacementBias() {
        return this.uniforms.displacementBias.value;
    }

    /**
     *
     * @param {number} v
     */
    set displacementBias(v) {
        this.uniforms.displacementBias.value = v;
    }

    /**
     *
     * @returns {Texture}
     */
    get envMap() {
        return this.uniforms.envMap.value;
    }

    /**
     *
     * @param {Texture} v
     */
    set envMap(v) {
        this.uniforms.envMap.value = v;
    }

    /**
     *
     * @returns {number}
     */
    get envMapIntensity() {
        return this.uniforms.envMapIntensity.value;
    }

    /**
     *
     * @param {number} v
     */
    set envMapIntensity(v) {
        this.uniforms.envMapIntensity.value = v;
    }

    /**
     *
     * @returns {number}
     */
    get refractionRatio() {
        return this.uniforms.refractionRatio.value;
    }

    /**
     *
     * @param {number} v
     */
    set refractionRatio(v) {
        this.uniforms.refractionRatio.value = v;
    }

    /**
     *
     * @param {MeshStandardMaterial} material
     */
    copy_basic(material) {
        super.copy_basic(material);

        this.map = material.map;

        this.normalMap = material.normalMap;
        this.normalScale = material.normalScale;
        this.normalMapType = material.normalMapType;

        this.roughnessMap = material.roughnessMap;
        this.roughness = material.roughness;

        this.metalnessMap = material.metalnessMap;
        this.metalness = material.metalness;

        this.aoMap = material.aoMap;
        this.aoMapIntensity = material.aoMapIntensity;

        this.lightMap = material.lightMap;
        this.lightMapIntensity = material.lightMapIntensity;

        this.emissive = material.emissive;
        this.emissiveIntensity = material.emissiveIntensity;
        this.emissiveMap = material.emissiveMap;

        this.bumpMap = material.bumpMap;
        this.bumpScale = material.bumpScale;

        this.displacementMap = material.displacementMap;
        this.displacementScale = material.displacementScale;
        this.displacementBias = material.displacementBias;

        this.envMap = material.envMap;
        this.envMapIntensity = material.envMapIntensity;
    }

}
