package client.renderer.entity;

import org.lwjgl.opengl.GL11;

import client.renderer.GlState;
import client.renderer.layers.LayerArmor;
import client.renderer.layers.LayerArrow;
import client.renderer.layers.LayerCape;
import client.renderer.layers.LayerCharge;
import client.renderer.layers.LayerExtra;
import client.renderer.layers.LayerHeldItem;
import client.renderer.layers.LayerPowerRods;
import client.renderer.model.ModelBiped;
import client.renderer.model.ModelHumanoid;
import client.renderer.texture.EntityTexManager;
import common.entity.npc.EntityNPC;
import common.item.ItemAction;
import common.item.ItemStack;


public class RenderHumanoid extends RenderNpc
{
    protected final ModelBiped modelBipedMain;
    private final String defTex;
    private final int arms;
    private final int legs;
    
//    public RenderHumanoid(RenderManager renderManager)
//    {
//    	this(renderManager, new ModelHumanoid(), true);
//    }
    
    public RenderHumanoid(RenderManager renderManager, int arms, int legs, String defTex)
    {
    	this(renderManager, new ModelHumanoid(64, 16 + (4 + arms) * 2 + 4 + legs, arms, legs), arms, legs, true, defTex);
    }
    
    protected RenderHumanoid(RenderManager renderManager, ModelHumanoid model, int arms, int legs, boolean armor, String defTex)
    {
        super(renderManager, model);
        this.modelBipedMain = model;
        this.defTex = defTex;
        this.arms = arms;
        this.legs = legs;
//        this.addLayer(new LayerCustomHead(model.bipedHead));
        this.addLayer(new LayerHeldItem(this, -1, arms - 5));
        if(armor)
        	this.addLayer(new LayerArmor(this, arms, legs));
        this.addLayer(new LayerArrow(this)); // {
//        	public void doRenderLayer(EntityLivingBase entity, float p_177141_2_, float p_177141_3_, float partialTicks, float p_177141_5_, float p_177141_6_, float p_177141_7_, float scale) {
////        		if(!entity.isChild())
//        			super.doRenderLayer(entity, p_177141_2_, p_177141_3_, partialTicks, p_177141_5_, p_177141_6_, p_177141_7_, scale);
//            }
//        });
        this.addLayer(new LayerCape(this, - (arms + legs - 24), arms + 4));
        this.addLayer(new LayerPowerRods(this));
        this.addLayer(new LayerCharge(this));
    }

//    public void transformHeldFull3DItemLayer()
//    {
//        SKC.glTranslatef(0.0F, 0.1875F, 0.0F);
//    }

    public ModelHumanoid getMainModel()
    {
        return (ModelHumanoid)super.getMainModel();
    }
    
    public void doRender(EntityNPC entity, double x, double y, double z, float partialTicks)
    {
//    	if(entity.isBoss())
//            BossStatus.setBossStatus(entity);
        double d0 = y;
        if(/* this.canSneak() && */ entity.isSneakingVisually())
            d0 = y - 0.125D;
        this.setModelVisibilities(entity);
        super.doRender(entity, x, d0, z, partialTicks);
    }

    protected void renderLayers(EntityNPC entity, float swing, float amount, float partial, float time, float dYaw, float dPitch, float scale) {
        super.renderLayers(entity, swing, amount, partial, time, dYaw, dPitch, scale);
    	LayerExtra extra = EntityTexManager.getLayer(entity);
        if(extra != null) {
    		extra.setModel(this.getMainModel());
//            boolean bright = this.setBrightness(entity, partial, extra.shouldCombineTextures());
            extra.doRenderLayer(entity, swing, amount, partial, time, dYaw, dPitch, scale);
//            if(bright)
//                this.unsetBrightness();
        }
    }

//    public void renderName(EntityNPC entity, double x, double y, double z)
//    {
//        super.renderName(entity, x, y, z);
//        if(entity.isPlayer()Client && ((EntityNPCClient)entity).getHeadList() != null 
//        		&& this.canRenderStats(entity) && entity == this.renderManager.pointedEntity)
//        	this.renderLabel(entity, x, y + 0.6, z, ((EntityNPCClient)entity).getHeadList());
//    }
//    
//    protected boolean canRenderName(EntityNPC entity)
//    {
//    	return entity == this.renderManager.pointedEntity && this.canRenderStats(entity);
//    }

    protected void setModelVisibilities(EntityNPC npc)
    {
        ModelHumanoid modelplayer = this.getMainModel();
        ItemStack itemstack = npc.getHeldItem();
        modelplayer.setSlim(npc.hasSlimArms()); // .hasSlimSkin());
        modelplayer.setVisible(true);
        boolean third = this.manager.gm == null || npc != this.manager.gm.getRenderViewEntity() || this.manager.gm.thirdPersonView != 0 || !this.manager.gm.showPlayerFirstPerson || this.manager.gm.charEditor;
        modelplayer.bipedHead.showModel &= third;
        modelplayer.bipedHeadwear.showModel &= third;
//        if(npc.isPlayer()) {
//            modelplayer.bipedHeadwear.showModel &= npc.isWearing(ModelPart.HEAD);
//            modelplayer.bipedBodyWear.showModel &= npc.isWearing(ModelPart.JACKET);
//            modelplayer.bipedLeftLegwear.showModel &= npc.isWearing(ModelPart.LEGS);
//            modelplayer.bipedRightLegwear.showModel &= npc.isWearing(ModelPart.LEGS);
//            modelplayer.bipedLeftArmwear.showModel &= npc.isWearing(ModelPart.SLEEVES);
//            modelplayer.bipedRightArmwear.showModel &= npc.isWearing(ModelPart.SLEEVES);
//            modelplayer.slimLeftArmwear.showModel &= npc.isWearing(ModelPart.SLEEVES);
//            modelplayer.slimRightArmwear.showModel &= npc.isWearing(ModelPart.SLEEVES);
//        }
        modelplayer.heldItemLeft = 0;
        modelplayer.aimedBow = false;
        modelplayer.isSneak = /* this.canSneak() && */ npc.isSneakingVisually();
        modelplayer.raisedArms = npc.hasArmsRaised();
//        modelplayer.sticks = npc.hasPowerRods();

        if (itemstack == null || itemstack.getItem().getWieldType() == null)
        {
            modelplayer.heldItemRight = 0;
        }
        else
        {
            modelplayer.heldItemRight = 1;

            if (npc.isUsingItem())
            {
                ItemAction enumaction = itemstack.getItemUseAction();
                enumaction = enumaction == ItemAction.NONE ? itemstack.getItem().getItemPosition() : enumaction;

                if (enumaction == ItemAction.BLOCK)
                {
                    modelplayer.heldItemRight = 3;
                }
                else if (enumaction == ItemAction.AIM)
                {
                    modelplayer.aimedBow = true;
                }
            }
            else {
                ItemAction enumaction = itemstack.getItem().getItemPosition();
                
            	if(enumaction == ItemAction.AIM) {
            		modelplayer.aimedBow = true;
            	}
            }
        }
    }
    
//    protected String getEntityTexture(EntityNPC entity)
//    {
//    	return entity.getLocationSkin();
//    }
    
    protected void preRenderCallback(EntityNPC entitylivingbaseIn, float partialTickTime)
    {
//    	if(entitylivingbaseIn instanceof EntityHaunter) {
//            float f = ((EntityHaunter)entitylivingbaseIn).getFlashIntensity(partialTickTime);
//            float f1 = 1.0F + ExtMath.sin(f * 100.0F) * f * 0.01F;
//            f = ExtMath.clampf(f, 0.0F, 1.0F);
//            f = f * f;
//            f = f * f;
//            float f2 = (1.0F + f * 0.4F) * f1;
//            float f3 = (1.0F + f * 0.1F) / f1;
//            SKC.glScalef(f2, f3, f2);
//    	}
        float f = entitylivingbaseIn.getRenderScale(); // 0.9375F;
        GL11.glScalef(f, f, f);
    }
    
//    protected int getColorMultiplier(EntityNPC entitylivingbaseIn, float lightBrightness, float partialTickTime)
//    {
//    	if(entitylivingbaseIn instanceof EntityHaunter) {
//	        float f = ((EntityHaunter)entitylivingbaseIn).getFlashIntensity(partialTickTime);
//	
//	        if ((int)(f * 10.0F) % 2 == 0)
//	        {
//	            return 0;
//	        }
//	        else
//	        {
//	            int i = (int)(f * 0.2F * 255.0F);
//	            i = ExtMath.clampi(i, 0, 255);
//	            return i << 24 | 16777215;
//	        }
//    	}
//    	else {
//    		return super.getColorMultiplier(entitylivingbaseIn, lightBrightness, partialTickTime);
//    	}
//    }
    
    public void renderPlayerArm(EntityNPC entity)
    {
        float f = 1.0F;
        GlState.color(f, f, f, 1.0F);
        ModelHumanoid modelplayer = this.getMainModel();
        this.setModelVisibilities(entity);
        modelplayer.swingProgress = 0.0F;
        modelplayer.isSneak = false;
        modelplayer.heldItemRight = 0;
        modelplayer.heldItemLeft = 0;
        modelplayer.aimedBow = false;
        modelplayer.isRiding = false;
        modelplayer.raisedArms = false;
        modelplayer.setRotationAngles(0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0625F, entity);
        modelplayer.renderRightArm((float)this.arms - 12.0f);
    }
    
    public final String getDefaultTexture()
    {
    	return this.defTex;
    }

//	public int getCompressedSize() {
//		return 14752;
//	}
    
    public void getSegments(TexList opaque, TexList alpha) {
    	alpha.add( 0 , 0 , 8 , 8 );
    	opaque.add(8 , 0 , 16, 8 );
    	alpha.add( 24, 0 , 8 , 8 );
		opaque.add(0 , 8 , 32, 8 );
		alpha.add( 32, 0 , 32, 16);

		alpha.add( 0 , 16, 4 , 4 );
		opaque.add(4 , 16, 8 , 4 );
		alpha.add( 12, 16, 8 , 4 );
		opaque.add(20, 16, 16, 4 );
		alpha.add( 36, 16, 8 , 4 );
		opaque.add(44, 16, 8 , 4 );
		alpha.add( 52, 16, 4 , 4 );
		opaque.add(0 , 20, 56, this.arms);
		alpha.add( 56, 16, 8 , this.arms + 4);
		
		alpha.add( 0 , this.arms + 20, 64, this.arms + 4);

		alpha.add( 0 , this.arms * 2 + 24, 16, this.legs + 4);
		alpha.add( 16, this.arms * 2 + 24, 4 , 4 );
		opaque.add(20, this.arms * 2 + 24, 8 , 4 );
		alpha.add( 28, this.arms * 2 + 24, 8 , 4 );
		opaque.add(36, this.arms * 2 + 24, 8 , 4 );
		alpha.add( 44, this.arms * 2 + 24, 4 , 4 );
		opaque.add(16, this.arms * 2 + 28, 32, this.legs);
		alpha.add( 48, this.arms * 2 + 24, 16, this.legs + 4);
    }

//	public int compToImage(byte[] comp, int[] img, int stride) {
//		int pos = 0;
//		
//		pos = copyData(comp, pos, stride, img,  0,  0,  8, 8, true);
//		pos = copyData(comp, pos, stride, img,  8, 0,  16, 8, false);
//		pos = copyData(comp, pos, stride, img,  24,  0,  8, 8, true);
//		pos = copyData(comp, pos, stride, img,  0, 8,  32, 8, false);
//		pos = copyData(comp, pos, stride, img,  32, 0, 32, 16, true);
//
//		pos = copyData(comp, pos, stride, img, 0,  16,  4, 4, true);
//		pos = copyData(comp, pos, stride, img, 4,  16,  8, 4, false);
//		pos = copyData(comp, pos, stride, img, 12,  16,  8, 4, true);
//		pos = copyData(comp, pos, stride, img, 20, 16,  16, 4, false);
//		pos = copyData(comp, pos, stride, img, 36,  16,  8, 4, true);
//		pos = copyData(comp, pos, stride, img, 44,  16,  8, 4, false);
//		pos = copyData(comp, pos, stride, img, 52,  16,  4, 4, true);
//		pos = copyData(comp, pos, stride, img, 0, 20, 56, 12, false);
//		pos = copyData(comp, pos, stride, img, 56,  16, 8, 16, true);
//		
//		pos = copyData(comp, pos, stride, img, 0, 32, 64, 16, true);
//
//		pos = copyData(comp, pos, stride, img, 0, 48, 16, 16, true);
//		pos = copyData(comp, pos, stride, img, 16,  48,  4, 4, true);
//		pos = copyData(comp, pos, stride, img, 20,  48,  8, 4, false);
//		pos = copyData(comp, pos, stride, img, 28,  48,  8, 4, true);
//		pos = copyData(comp, pos, stride, img, 36,  48,  8, 4, false);
//		pos = copyData(comp, pos, stride, img, 44,  48,  4, 4, true);
//		pos = copyData(comp, pos, stride, img, 16, 52, 32, 12, false);
//		pos = copyData(comp, pos, stride, img, 48, 48, 16, 16, true);
//		
//		return pos;
//	}
//
//	public int imageToComp(byte[] comp, int[] img, int stride) {
//		int pos = 0;
//
//		pos = copyData(stride, img, 0 , 0 , 8 , 8 , comp, pos, true);
//		pos = copyData(stride, img, 8 , 0 , 16, 8 , comp, pos, false);
//		pos = copyData(stride, img, 24, 0 , 8 , 8 , comp, pos, true);
//		pos = copyData(stride, img, 0 , 8 , 32, 8 , comp, pos, false);
//		pos = copyData(stride, img, 32, 0 , 32, 16, comp, pos, true);
//
//		pos = copyData(stride, img, 0 , 16, 4 , 4 , comp, pos, true);
//		pos = copyData(stride, img, 4 , 16, 8 , 4 , comp, pos, false);
//		pos = copyData(stride, img, 12, 16, 8 , 4 , comp, pos, true);
//		pos = copyData(stride, img, 20, 16, 16, 4 , comp, pos, false);
//		pos = copyData(stride, img, 36, 16, 8 , 4 , comp, pos, true);
//		pos = copyData(stride, img, 44, 16, 8 , 4 , comp, pos, false);
//		pos = copyData(stride, img, 52, 16, 4 , 4 , comp, pos, true);
//		pos = copyData(stride, img, 0 , 20, 56, 12, comp, pos, false);
//		pos = copyData(stride, img, 56, 16, 8 , 16, comp, pos, true);
//		
//		pos = copyData(stride, img, 0 , 32, 64, 16, comp, pos, true);
//
//		pos = copyData(stride, img, 0 , 48, 16, 16, comp, pos, true);
//		pos = copyData(stride, img, 16, 48, 4 , 4 , comp, pos, true);
//		pos = copyData(stride, img, 20, 48, 8 , 4 , comp, pos, false);
//		pos = copyData(stride, img, 28, 48, 8 , 4 , comp, pos, true);
//		pos = copyData(stride, img, 36, 48, 8 , 4 , comp, pos, false);
//		pos = copyData(stride, img, 44, 48, 4 , 4 , comp, pos, true);
//		pos = copyData(stride, img, 16, 52, 32, 12, comp, pos, false);
//		pos = copyData(stride, img, 48, 48, 16, 16, comp, pos, true);
//		
//		return pos;
//	}
	
    public void getHeadUVs(CoordList list) {
    	list.add(0, 0, 8, 8, 8, 8);
    	list.add(0, 0, 40, 8, 8, 8);
    }
}
