package shadersmod.transform;

import java.util.Iterator;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import static org.objectweb.asm.Opcodes.*;

import org.objectweb.asm.commons.Remapper;
import org.objectweb.asm.tree.MethodNode;

import shadersmod.common.SMCLog;


import net.minecraft.launchwrapper.IClassTransformer;

// for BlockRendererDispatcher

public class SMCCTBlockRendererDispatcher implements IClassTransformer {

	@Override
	public byte[] transform(String par1, String par2, byte[] par3) {
		SMCLog.fine("transforming %s %s",par1,par2);
		ClassReader cr = new ClassReader(par3);
		ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
		CVTransform cv = new CVTransform(cw);
		cr.accept(cv,0);
		return cw.toByteArray();
	}

	private static class CVTransform extends ClassVisitor
	{
		String classname;
		
		public CVTransform(ClassVisitor cv)
		{
			super(Opcodes.ASM4, cv);		
		}

		@Override
		public void visit(int version, int access, String name,
				String signature, String superName, String[] interfaces) {
			classname = name;
			//SMCLog.info(" class %s",name);
			cv.visit(version, access, name, signature, superName, interfaces);
		}

		@Override
		public MethodVisitor visitMethod(int access, String name, String desc,
				String signature, String[] exceptions) 
		{
			if (Names.blockRendererDispatcher_renderBlock.equalsNameDesc(name, desc))
			{
				//SMCLog.finer("  patching method %s.%s%s = %s",classname,name,desc,nameM);
				return new MVrenderBlock(cv.visitMethod(access, name, desc, signature, exceptions));
			}
			return cv.visitMethod(access, name, desc, signature, exceptions);
		}
	}
	
	private static class MVrenderBlock extends MethodVisitor
	{
		public MVrenderBlock(MethodVisitor mv) {
			super(Opcodes.ASM4, mv);
		}
//		int state = 0;

//		@Override
//		public void visitInsn(int opcode) {
//			if (opcode==IRETURN || opcode==ATHROW) {
//				mv.visitVarInsn(ALOAD, 4);
//				mv.visitMethodInsn(INVOKESTATIC, "shadersmod/client/SVertexBuilder", "popEntity", "(Lnet/minecraft/client/renderer/WorldRenderer;)V");
//			}
//			mv.visitInsn(opcode);
//		}
//
//		@Override
//		public void visitLabel(Label label) {
//			if (state==0) 
//			{
//				mv.visitVarInsn(ALOAD, 1);
//				mv.visitVarInsn(ALOAD, 2);
//				mv.visitVarInsn(ALOAD, 3);
//				mv.visitVarInsn(ALOAD, 4);
//				mv.visitMethodInsn(INVOKESTATIC, "shadersmod/client/SVertexBuilder", "pushEntity", "(Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/util/BlockPos;Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/client/renderer/WorldRenderer;)V");
//				state = 1;
//			}
//			mv.visitLabel(label);
//		}

		@Override
		public void visitMethodInsn(int opcode, String owner, String name,String desc) {
			//SMCLog.finest("    %s.%s%s",ownerM,nameM,descM);
			if (Names.blockFluidRenderer_renderFluid.equals(owner,name,desc)) {
				mv.visitVarInsn(ALOAD, 1);
				mv.visitVarInsn(ALOAD, 2);
				mv.visitVarInsn(ALOAD, 3);
				mv.visitVarInsn(ALOAD, 4);
				mv.visitMethodInsn(INVOKESTATIC, "shadersmod/client/SVertexBuilder", "pushEntity", "("+Names.iBlockState_.desc+Names.blockPos_.desc+Names.iBlockAccess_.desc+Names.worldRenderer_.desc+")V");
				mv.visitMethodInsn(opcode, owner, name, desc);
				mv.visitVarInsn(ALOAD, 4);
				mv.visitMethodInsn(INVOKESTATIC, "shadersmod/client/SVertexBuilder", "popEntity", "("+Names.worldRenderer_.desc+")V");
				return;
			} else
			if (Names.blockModelRenderer_renderModel.equals(owner,name,desc)) {
				mv.visitVarInsn(ALOAD, 1);
				mv.visitVarInsn(ALOAD, 2);
				mv.visitVarInsn(ALOAD, 3);
				mv.visitVarInsn(ALOAD, 4);
				mv.visitMethodInsn(INVOKESTATIC, "shadersmod/client/SVertexBuilder", "pushEntity", "("+Names.iBlockState_.desc+Names.blockPos_.desc+Names.iBlockAccess_.desc+Names.worldRenderer_.desc+")V");
				mv.visitMethodInsn(opcode, owner, name, desc);
				mv.visitVarInsn(ALOAD, 4);
				mv.visitMethodInsn(INVOKESTATIC, "shadersmod/client/SVertexBuilder", "popEntity", "("+Names.worldRenderer_.desc+")V");
				return;
			}
			mv.visitMethodInsn(opcode, owner, name, desc);
		}

	}

}
