package speiger.src.coreengine.platform.graphics.opengl.utils;

import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;

import speiger.src.coreengine.platform.graphics.api.shader.ColorTarget;
import speiger.src.coreengine.platform.graphics.api.utils.AlphaFunction;
import speiger.src.coreengine.platform.graphics.opengl.shader.ShaderTracker;
import speiger.src.coreengine.platform.graphics.opengl.utils.states.BlendState;
import speiger.src.coreengine.platform.graphics.opengl.utils.states.CullState;
import speiger.src.coreengine.platform.graphics.opengl.utils.states.FloatState;
import speiger.src.coreengine.platform.graphics.opengl.utils.states.GLPolygon;
import speiger.src.coreengine.platform.graphics.opengl.utils.states.GLState;
import speiger.src.coreengine.platform.graphics.opengl.utils.states.PixelState;
import speiger.src.coreengine.platform.graphics.opengl.utils.states.SamplerState;
import speiger.src.coreengine.platform.graphics.opengl.utils.states.ScissorState;
import speiger.src.coreengine.platform.graphics.opengl.utils.states.TextureState;

public final class GLStates {
	public final GLState multiSampling = new GLState(GL13.GL_MULTISAMPLE);
	public final GLState depth = new GLState(GL11.GL_DEPTH_TEST);
	public final GLPolygon polygon = new GLPolygon();
	public final GLState backCulling = new CullState();
	public final FloatState pointSize = new FloatState(1F, GL11::glPointSize);
	public final FloatState lineSize = new FloatState(1F, GL11::glLineWidth);
	public final TextureState textures = new TextureState();
	public final SamplerState samplers = new SamplerState();
	public final BlendState blend = new BlendState();
	public final ScissorState scissors = new ScissorState();
	public final ViewPortStack viewPort = new ViewPortStack();
	
	//Texture States
	public final PixelState unpack_alignment = new PixelState(GL11.GL_UNPACK_ALIGNMENT, 4);
	public final PixelState unpack_skip_pixel = new PixelState(GL11.GL_UNPACK_SKIP_PIXELS, 0);
	public final PixelState unpack_skip_rows = new PixelState(GL11.GL_UNPACK_SKIP_ROWS, 0);
	public final PixelState unpack_row_length = new PixelState(GL11.GL_UNPACK_ROW_LENGTH, 0);
	
	public final ShaderTracker shaders = new ShaderTracker();
	
	
	int colorMask = ColorTarget.ALL;
	boolean depthMask = true;
	AlphaFunction depthFunction = AlphaFunction.GEQUAL;
	int activeVAO = 0;
	int activeShader = 0;
	
	public void setColorMask(int mask) {
		if(colorMask == mask) return;
		colorMask = mask;
		GL11.glColorMask((mask & ColorTarget.RED) != 0, (mask & ColorTarget.GREEN) != 0, (mask & ColorTarget.BLUE) != 0, (mask & ColorTarget.ALPHA) != 0);
	}
	
	public void setDepthMask(boolean depth) {
		if(depthMask == depth) return;
		depthMask = depth;
		GL11.glDepthMask(depth);
	}
	
	public void setDepthFunction(AlphaFunction function) {
		if(depthFunction == function) return;
		depthFunction = function;
		GL11.glDepthFunc(GLUtils.toGL(function));
	}
}
