package client.renderer.model;

import org.lwjgl.opengl.GL11;

import common.entity.Entity;
import common.entity.types.EntityLiving;
import common.util.ExtMath;

public abstract class ModelBiped extends ModelBase
{
    public ModelRenderer bipedHead;
    public ModelRenderer bipedHeadwear;
    public ModelRenderer bipedBody;
    public ModelRenderer bipedRightArm;
    public ModelRenderer bipedLeftArm;
    public ModelRenderer bipedRightLeg;
    public ModelRenderer bipedLeftLeg;
    public int heldItemLeft;
    public int heldItemRight;
    public boolean isSneak;
    public boolean aimedBow;

    private final boolean canSneak;
    private final float shift;
    private final float fshift;
    private final float ashift;

//    public ModelBiped()
//    {
//        this(0.0F);
//    }

//    public ModelBiped(float modelSize, int arms, int legs)
//    {
//        this(modelSize, 0.0F, 64, 32, arms, legs);
//    }

    public ModelBiped(int textureWidthIn, int textureHeightIn, int arms, int legs)
    {
        this.textureWidth = textureWidthIn;
        this.textureHeight = textureHeightIn;
        this.shift = 24.0f - (float)legs;
        this.fshift = 24.0f - (float)legs - (float)arms;
        this.canSneak = true;
        this.ashift = 5.0f;
    }

    public ModelBiped(int textureWidthIn, int textureHeightIn, float ashift)
    {
        this.textureWidth = textureWidthIn;
        this.textureHeight = textureHeightIn;
        this.shift = 0.0f;
        this.fshift = 0.0f;
        this.canSneak = false;
        this.ashift = ashift;
    }

    /**
     * Sets the models various rotation angles then renders the model.
     */
    public void render(Entity entityIn, float p_78088_2_, float p_78088_3_, float p_78088_4_, float p_78088_5_, float p_78088_6_, float scale)
    {
        this.setRotationAngles(p_78088_2_, p_78088_3_, p_78088_4_, p_78088_5_, p_78088_6_, scale, entityIn);
        GL11.glPushMatrix();

//        if (this.isChild)
//        {
//            float f = 2.0F;
////            if(!this.smallHead) {
////	            SKC.glScalef(1.5F / f, 1.5F / f, 1.5F / f);
////	            SKC.glTranslatef(0.0F, 16.0F * scale, 0.0F);
////	            this.bipedHead.render(scale);
////	            SKC.glPopMatrix();
////	            SKC.glPushMatrix();
////            }
//            SKC.glScalef(1.0F / f, 1.0F / f, 1.0F / f);
//            SKC.glTranslatef(0.0F, 24.0F * scale, 0.0F);
////            if(this.smallHead) {
//            this.bipedHead.render(scale);
////            }
//            this.bipedBody.render(scale);
//            this.bipedRightArm.render(scale);
//            this.bipedLeftArm.render(scale);
//            this.bipedRightLeg.render(scale);
//            this.bipedLeftLeg.render(scale);
//            this.bipedHeadwear.render(scale);
//        }
//        else
//        {
            if (this.isSneak) // entityIn.isSneaking())
            {
                GL11.glTranslatef(0.0F, 0.2F, 0.0F);
            }

            this.bipedHead.render(scale);
            this.bipedBody.render(scale);
            this.bipedRightArm.render(scale);
            this.bipedLeftArm.render(scale);
            this.bipedRightLeg.render(scale);
            this.bipedLeftLeg.render(scale);
            if(this.bipedHeadwear != null)
            	this.bipedHeadwear.render(scale);
//        }

        GL11.glPopMatrix();
    }

    /**
     * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms
     * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how
     * "far" arms and legs can swing at most.
     */
    public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entityIn)
    {
        this.bipedHead.rotateAngleY = netHeadYaw / (180F / (float)Math.PI);
        this.bipedHead.rotateAngleX = headPitch / (180F / (float)Math.PI);
        this.bipedRightArm.rotateAngleX = (entityIn == null ? 1.0f : ((EntityLiving)entityIn).getArmRotation()) * ExtMath.cos(limbSwing * 0.6662F + (float)Math.PI) * /* 2.0F * */ limbSwingAmount; // * 0.5F;
        this.bipedLeftArm.rotateAngleX = (entityIn == null ? 1.0f : ((EntityLiving)entityIn).getArmRotation()) * ExtMath.cos(limbSwing * 0.6662F) * /* 2.0F * */ limbSwingAmount; // * 0.5F;
        this.bipedRightArm.rotateAngleZ = 0.0F;
        this.bipedLeftArm.rotateAngleZ = 0.0F;
        this.bipedRightLeg.rotateAngleX = (entityIn == null ? 1.4f : ((EntityLiving)entityIn).getLegRotation()) * ExtMath.cos(limbSwing * 0.6662F) /* * 1.4F */ * limbSwingAmount;
        this.bipedLeftLeg.rotateAngleX = (entityIn == null ? 1.4f : ((EntityLiving)entityIn).getLegRotation()) * ExtMath.cos(limbSwing * 0.6662F + (float)Math.PI) /* * 1.4F */ * limbSwingAmount;
        this.bipedRightLeg.rotateAngleY = 0.0F;
        this.bipedLeftLeg.rotateAngleY = 0.0F;

        if (this.isRiding)
        {
            this.bipedRightArm.rotateAngleX += -((float)Math.PI / 5F);
            this.bipedLeftArm.rotateAngleX += -((float)Math.PI / 5F);
            this.bipedRightLeg.rotateAngleX = -((float)Math.PI * 2F / 5F);
            this.bipedLeftLeg.rotateAngleX = -((float)Math.PI * 2F / 5F);
            this.bipedRightLeg.rotateAngleY = ((float)Math.PI / 10F);
            this.bipedLeftLeg.rotateAngleY = -((float)Math.PI / 10F);
        }

        if (this.heldItemLeft != 0)
        {
            this.bipedLeftArm.rotateAngleX = this.bipedLeftArm.rotateAngleX * 0.5F - ((float)Math.PI / 10F) * (float)this.heldItemLeft;
        }

        this.bipedRightArm.rotateAngleY = 0.0F;
        this.bipedRightArm.rotateAngleZ = 0.0F;

        switch (this.heldItemRight)
        {
            case 0:
            case 2:
            default:
                break;

            case 1:
                this.bipedRightArm.rotateAngleX = this.bipedRightArm.rotateAngleX * 0.5F - ((float)Math.PI / 10F) * (float)this.heldItemRight;
                break;

            case 3:
                this.bipedRightArm.rotateAngleX = this.bipedRightArm.rotateAngleX * 0.5F - ((float)Math.PI / 10F) * (float)this.heldItemRight;
                this.bipedRightArm.rotateAngleY = -0.5235988F;
        }

        this.bipedLeftArm.rotateAngleY = 0.0F;

        if (this.swingProgress > -9990.0F)
        {
            float f = this.swingProgress;
            this.bipedBody.rotateAngleY = ExtMath.sin(ExtMath.sqrtf(f) * (float)Math.PI * 2.0F) * 0.2F;
            this.bipedRightArm.rotationPointZ = ExtMath.sin(this.bipedBody.rotateAngleY) * this.ashift;
            this.bipedRightArm.rotationPointX = -ExtMath.cos(this.bipedBody.rotateAngleY) * this.ashift;
            this.bipedLeftArm.rotationPointZ = -ExtMath.sin(this.bipedBody.rotateAngleY) * this.ashift;
            this.bipedLeftArm.rotationPointX = ExtMath.cos(this.bipedBody.rotateAngleY) * this.ashift;
            this.bipedRightArm.rotateAngleY += this.bipedBody.rotateAngleY;
            this.bipedLeftArm.rotateAngleY += this.bipedBody.rotateAngleY;
            this.bipedLeftArm.rotateAngleX += this.bipedBody.rotateAngleY;
            f = 1.0F - this.swingProgress;
            f = f * f;
            f = f * f;
            f = 1.0F - f;
            float f1 = ExtMath.sin(f * (float)Math.PI);
            float f2 = ExtMath.sin(this.swingProgress * (float)Math.PI) * -(this.bipedHead.rotateAngleX - 0.7F) * 0.75F;
            this.bipedRightArm.rotateAngleX = (float)((double)this.bipedRightArm.rotateAngleX - ((double)f1 * 1.2D + (double)f2));
            this.bipedRightArm.rotateAngleY += this.bipedBody.rotateAngleY * 2.0F;
            this.bipedRightArm.rotateAngleZ += ExtMath.sin(this.swingProgress * (float)Math.PI) * -0.4F;
        }

        if (this.canSneak && this.isSneak)
        {
            this.bipedBody.rotateAngleX = 0.5F;
            this.bipedRightArm.rotateAngleX += 0.4F;
            this.bipedLeftArm.rotateAngleX += 0.4F;
            this.bipedRightLeg.rotationPointZ = 4.0F;
            this.bipedLeftLeg.rotationPointZ = 4.0F;
            this.bipedRightLeg.rotationPointY = this.shift - 3.0F;
            this.bipedLeftLeg.rotationPointY = this.shift - 3.0F;
            this.bipedHead.rotationPointY = this.fshift + 1.0F;
        }
        else if(this.canSneak)
        {
            this.bipedBody.rotateAngleX = 0.0F;
            this.bipedRightLeg.rotationPointZ = 0.1F;
            this.bipedLeftLeg.rotationPointZ = 0.1F;
            this.bipedRightLeg.rotationPointY = this.shift;
            this.bipedLeftLeg.rotationPointY = this.shift;
            this.bipedHead.rotationPointY = this.fshift;
        }

        this.bipedRightArm.rotateAngleZ += ExtMath.cos(ageInTicks * 0.09F) * 0.05F + 0.05F;
        this.bipedLeftArm.rotateAngleZ -= ExtMath.cos(ageInTicks * 0.09F) * 0.05F + 0.05F;
        this.bipedRightArm.rotateAngleX += ExtMath.sin(ageInTicks * 0.067F) * 0.05F;
        this.bipedLeftArm.rotateAngleX -= ExtMath.sin(ageInTicks * 0.067F) * 0.05F;

        if (this.aimedBow)
        {
            float f3 = 0.0F;
            float f4 = 0.0F;
            this.bipedRightArm.rotateAngleZ = 0.0F;
            this.bipedLeftArm.rotateAngleZ = 0.0F;
            this.bipedRightArm.rotateAngleY = -(0.1F - f3 * 0.6F) + this.bipedHead.rotateAngleY;
            this.bipedLeftArm.rotateAngleY = 0.1F - f3 * 0.6F + this.bipedHead.rotateAngleY + 0.4F;
            this.bipedRightArm.rotateAngleX = -((float)Math.PI / 2F) + this.bipedHead.rotateAngleX;
            this.bipedLeftArm.rotateAngleX = -((float)Math.PI / 2F) + this.bipedHead.rotateAngleX;
            this.bipedRightArm.rotateAngleX -= f3 * 1.2F - f4 * 0.4F;
            this.bipedLeftArm.rotateAngleX -= f3 * 1.2F - f4 * 0.4F;
            this.bipedRightArm.rotateAngleZ += ExtMath.cos(ageInTicks * 0.09F) * 0.05F + 0.05F;
            this.bipedLeftArm.rotateAngleZ -= ExtMath.cos(ageInTicks * 0.09F) * 0.05F + 0.05F;
            this.bipedRightArm.rotateAngleX += ExtMath.sin(ageInTicks * 0.067F) * 0.05F;
            this.bipedLeftArm.rotateAngleX -= ExtMath.sin(ageInTicks * 0.067F) * 0.05F;
        }

        if(this.bipedHeadwear != null)
        	copyModelAngles(this.bipedHead, this.bipedHeadwear);
    }

    public void setModelAttributes(ModelBase model)
    {
    	if(model != null)
    		super.setModelAttributes(model);

        if (model instanceof ModelBiped)
        {
            ModelBiped modelbiped = (ModelBiped)model;
            this.heldItemLeft = modelbiped.heldItemLeft;
            this.heldItemRight = modelbiped.heldItemRight;
            this.isSneak = modelbiped.isSneak;
            this.aimedBow = modelbiped.aimedBow;
//            this.smallHead = modelbiped.smallHead;
        }
    }

    public void setVisible(boolean vis)
    {
        this.bipedHead.showModel = vis;
        if(this.bipedHeadwear != null)
        	this.bipedHeadwear.showModel = vis;
        this.bipedBody.showModel = vis;
        this.bipedRightArm.showModel = vis;
        this.bipedLeftArm.showModel = vis;
        this.bipedRightLeg.showModel = vis;
        this.bipedLeftLeg.showModel = vis;
    }

    public void postRenderArm(float scale)
    {
        this.bipedRightArm.postRender(scale);
    }

//    public void postRenderArm(float scale)
//    {
//        this.bipedRightArm.postRender(scale);
//    }
}
