package shadersmod.client;

import java.nio.ByteBuffer;
import java.util.List;

import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;

import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.WorldVertexBufferUploader;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.renderer.vertex.VertexFormatElement;

public class SVertexBufferDrawer extends WorldVertexBufferUploader {

	@SuppressWarnings("incomplete-switch")
	@Override
	public void draw(BufferBuilder vertexBuffer) {
        if (vertexBuffer.getVertexCount() > 0)
        {
            VertexFormat vertexformat = vertexBuffer.getVertexFormat();
            int stride = vertexformat.getNextOffset();
            ByteBuffer bytebuffer = vertexBuffer.getByteBuffer();
            List<VertexFormatElement> list = vertexformat.getElements();

            for (int i = 0; i < list.size(); ++i)
            {
                SVertexElement vertexelement = (SVertexElement)list.get(i);
                SVertexElementUsage usage = vertexelement.getSVEUsage();
                int type = vertexelement.getType().getGlConstant();
                int index = vertexelement.getIndex();
                bytebuffer.position(vertexformat.getOffset(i));

                switch (usage)
                {
                    case POSITION:
                        GlStateManager.glVertexPointer(vertexelement.getElementCount(), type, stride, bytebuffer);
                        GlStateManager.glEnableClientState(GL11.GL_VERTEX_ARRAY);
                        break;

                    case UV:
                        OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit + index);
                        GlStateManager.glTexCoordPointer(vertexelement.getElementCount(), type, stride, bytebuffer);
                        GlStateManager.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
                        OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit);
                        break;

                    case COLOR:
                        GlStateManager.glColorPointer(vertexelement.getElementCount(), type, stride, bytebuffer);
                        GlStateManager.glEnableClientState(GL11.GL_COLOR_ARRAY);
                        break;

                    case NORMAL:
                        GlStateManager.glNormalPointer(type, stride, bytebuffer);
                        GlStateManager.glEnableClientState(GL11.GL_NORMAL_ARRAY);
                        break;

                    case MIDUV:
                        GL20.glVertexAttribPointer(Shaders.midTexCoordAttrib, vertexelement.getElementCount(), type, false, stride, bytebuffer);
                        GL20.glEnableVertexAttribArray(Shaders.midTexCoordAttrib);
                        break;
                    case TANGENT:
                        GL20.glVertexAttribPointer(Shaders.tangentAttrib, vertexelement.getElementCount(), type, false, stride, bytebuffer);
                        GL20.glEnableVertexAttribArray(Shaders.tangentAttrib);
                        break;
                    case ENTITY:
                        GL20.glVertexAttribPointer(Shaders.entityAttrib, vertexelement.getElementCount(), type, false, stride, bytebuffer);
                        GL20.glEnableVertexAttribArray(Shaders.entityAttrib);
                        break;
                }
            }

            GlStateManager.glDrawArrays(vertexBuffer.getDrawMode(), 0, vertexBuffer.getVertexCount());

            for (int i = 0; i < list.size(); ++i)
            {
            	SVertexElement element = (SVertexElement)list.get(i);
            	SVertexElementUsage usage = element.getSVEUsage();
                int index = element.getIndex();

                switch (usage)
                {
                    case POSITION:
                        GlStateManager.glDisableClientState(GL11.GL_VERTEX_ARRAY);
                        break;

                    case UV:
                        OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit + index);
                        GlStateManager.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
                        OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit);
                        break;

                    case COLOR:
                        GlStateManager.glDisableClientState(GL11.GL_COLOR_ARRAY);
                        GlStateManager.resetColor();
                        break;

                    case NORMAL:
                        GlStateManager.glDisableClientState(GL11.GL_NORMAL_ARRAY);
                        break;

                    case MIDUV:
                        GL20.glDisableVertexAttribArray(Shaders.midTexCoordAttrib);
                        break;
                    case TANGENT:
                        GL20.glDisableVertexAttribArray(Shaders.tangentAttrib);
                        break;
                    case ENTITY:
                        GL20.glDisableVertexAttribArray(Shaders.entityAttrib);
                        break;
                }
            }
        }

        vertexBuffer.reset();
    }

}
