package speiger.src.coreengine.rendering.shader;

import java.util.function.Function;
import java.util.function.Supplier;

import speiger.src.coreengine.assets.base.IAssetProvider;
import speiger.src.coreengine.rendering.utils.GLStateTracker;

public class Shader<T extends ShaderProgram> implements Supplier<T> {
	T program;
	Function<IAssetProvider, T> provider;
	
	private Shader(Function<IAssetProvider, T> provider) {
		this.provider = provider;
	}
	
	public static <T extends ShaderProgram> Shader<T> create(Function<IAssetProvider, T> provider) {
		return new Shader<>(provider);
	}
	
	public static <T extends ShaderProgram> Shader<T> createAndRegister(Function<IAssetProvider, T> provider) {
		Shader<T> shader = new Shader<>(provider);
		shader.register();
		return shader;
	}
	
	public void load(IAssetProvider provider) {
		if(program != null) program.remove();
		program = this.provider.apply(provider);
	}
	
	public void validate() {
		if(program == null) return;
		program.validateProgram();
	}
	
	public void register() {
		GLStateTracker.instance().shaders.register(this);
	}
	
	public void remove() {
		if(program == null) return;
		program.remove();
		program = null;
	}
	
	public void removeProgram() {
		remove();
		GLStateTracker.instance().shaders.remove(this);
	}
	
	public void bind() { program.bind(); }
	@Override
	public T get() { return program; }
}