package electrosphere.renderer.model;

import electrosphere.engine.Globals;
import electrosphere.renderer.OpenGLState;
import electrosphere.renderer.texture.Texture;
import org.lwjgl.assimp.AIMaterial;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL13.GL_TEXTURE0;

/**
 * A material
 */
public class Material {
    
    String diffuse;
    String specular;
    boolean hasTransparency = false;
    
    //Sets whether this material should get its texture pointers from the assetManager by looking up diffuse and specular paths
    //or whether it should have a manually set texturePointer and not look up while binding
    boolean usesFetch = true;
    
    //texture pointer for the specular
    int texturePointer;
    //texture pointer for the normal
    int normalPointer;
    
    /**
     * A material that contains textures
     */
    public Material(){
        
    }

    //basically useless because blender doesn't support exporting mats with fbx
    public static Material load_material_from_aimaterial(AIMaterial input){
        Material rVal = new Material();
//         if(input.mNumProperties() > 0){
//             PointerBuffer property_buffer = input.mProperties();
//             while(property_buffer.hasRemaining()){
//                 AIMaterialProperty new_property = AIMaterialProperty.create(property_buffer.get());
// //                System.out.println("Property: " + new_property.mKey().dataString());
//             }
//         }
        return rVal;
    }
    public String get_diffuse(){
        return diffuse;
    }
    public String get_specular(){
        return specular;
    }
    public void set_diffuse(String t){
        diffuse = t;
//        if(t.isTransparent()){
//            hasTransparency = true;
//        }
    }
    public void set_specular(String t){
        specular = t;
//        if(t.isTransparent()){
//            hasTransparency = true;
//        }
    }
    
    public void setTexturePointer(int pointer){
        texturePointer = pointer;
        usesFetch = false;
    }

    /**
     * Sets the in-material pointer for the normal
     * @param pointer the normal texture
     */
    public void setNormalTexturePointer(int pointer){
        normalPointer = pointer;
        usesFetch = false;
    }
    
    /**
     * Applies the material
     */
    public void apply_material(OpenGLState openGLState){
        //Controls whether the texturePointer should be resolved by looking up the diffuse in asset manager or using the texture pointer already set in this material
        if(usesFetch){
            if(diffuse != null){
                Texture diffuseTexture = Globals.assetManager.fetchTexture(diffuse);
                if(diffuseTexture != null){
                    diffuseTexture.bind(openGLState,0);
                    Globals.renderingEngine.checkError();
                    openGLState.getActiveShader().setUniform(openGLState, "material.diffuse", 0);
                    Globals.renderingEngine.checkError();
                }
            }
            if(specular != null){
                Texture specularTexture = Globals.assetManager.fetchTexture(specular);
                if(specularTexture != null){
                    specularTexture.bind(openGLState,1);
                    Globals.renderingEngine.checkError();
                    openGLState.getActiveShader().setUniform(openGLState, "material.specular", 1);
                    Globals.renderingEngine.checkError();
                }
            }
        } else {
            openGLState.glBindTextureUnit(GL_TEXTURE0, texturePointer, GL_TEXTURE_2D);
            Globals.renderingEngine.checkError();
        }
    }
    public void apply_material(OpenGLState openGLState, int diffuse_channel, int specular_channel){
        Texture diffuseTexture = Globals.assetManager.fetchTexture(diffuse);
        if(diffuseTexture != null){
            diffuseTexture.bind(openGLState,diffuse_channel);
        }
        Texture specularTexture = Globals.assetManager.fetchTexture(specular);
        if(specularTexture != null){
            specularTexture.bind(openGLState,specular_channel);
        }
        Globals.renderingEngine.checkError();
    }
    
    public boolean isTransparent(){
        boolean rVal = false;
        Texture diffuseTexture = Globals.assetManager.fetchTexture(diffuse);
        if(diffuseTexture != null && diffuseTexture.isTransparent()){
            rVal = true;
        }
        Texture specularTexture = Globals.assetManager.fetchTexture(specular);
        if(specularTexture != null && specularTexture.isTransparent()){
            rVal = true;
        }
        return rVal;
    }
}
