package com.mojang.blaze3d.shaders;

import com.google.common.collect.Maps;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import com.mojang.blaze3d.platform.TextureUtil;
import java.io.InputStream;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;

public class Program {
    private final Type type;
    private final String name;
    private final int id;
    private int references;
    
    private Program(final Type a, final int integer, final String string) {
        this.type = a;
        this.id = integer;
        this.name = string;
    }
    
    public void attachToEffect(final Effect dhc) {
        RenderSystem.assertThread(RenderSystem::isOnRenderThread);
        ++this.references;
        GlStateManager.glAttachShader(dhc.getId(), this.id);
    }
    
    public void close() {
        RenderSystem.assertThread(RenderSystem::isOnRenderThread);
        --this.references;
        if (this.references <= 0) {
            GlStateManager.glDeleteShader(this.id);
            this.type.getPrograms().remove(this.name);
        }
    }
    
    public String getName() {
        return this.name;
    }
    
    public static Program compileShader(final Type a, final String string, final InputStream inputStream) throws IOException {
        RenderSystem.assertThread(RenderSystem::isOnRenderThread);
        final String string2 = TextureUtil.readResourceAsString(inputStream);
        if (string2 == null) {
            throw new IOException("Could not load program " + a.getName());
        }
        final int integer5 = GlStateManager.glCreateShader(a.getGlType());
        GlStateManager.glShaderSource(integer5, string2);
        GlStateManager.glCompileShader(integer5);
        if (GlStateManager.glGetShaderi(integer5, 35713) == 0) {
            final String string3 = StringUtils.trim(GlStateManager.glGetShaderInfoLog(integer5, 32768));
            throw new IOException("Couldn't compile " + a.getName() + " program: " + string3);
        }
        final Program dhd6 = new Program(a, integer5, string);
        a.getPrograms().put(string, dhd6);
        return dhd6;
    }
    
    public enum Type {
        VERTEX("vertex", ".vsh", 35633), 
        FRAGMENT("fragment", ".fsh", 35632);
        
        private final String name;
        private final String extension;
        private final int glType;
        private final Map<String, Program> programs;
        
        private Type(final String string3, final String string4, final int integer5) {
            this.programs = Maps.newHashMap();
            this.name = string3;
            this.extension = string4;
            this.glType = integer5;
        }
        
        public String getName() {
            return this.name;
        }
        
        public String getExtension() {
            return this.extension;
        }
        
        private int getGlType() {
            return this.glType;
        }
        
        public Map<String, Program> getPrograms() {
            return this.programs;
        }
    }
}
