package client.gui.character;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.List;

import javax.imageio.ImageIO;

import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;

import client.Client;
import client.Client.FileMode;
import client.gui.FileCallback;
import client.gui.Font;
import client.gui.GuiLoading;
import client.gui.element.ActButton;
import client.gui.element.Element;
import client.gui.element.GuiList;
import client.gui.element.Label;
import client.gui.element.ListEntry;
import client.gui.element.MultiLabel;
import client.gui.element.NavButton;
import client.gui.element.PressType;
import client.gui.element.Slider;
import client.gui.element.SliderCallback;
import client.init.DimensionMapping;
import client.gui.element.FieldAction;
import client.gui.element.Area;
import client.gui.element.ButtonCallback;
import client.gui.element.Field;
import client.gui.element.FieldCallback;
import client.renderer.Drawing;
import client.renderer.GlState;
import client.renderer.ItemRenderer;
import client.renderer.entity.RenderManager;
import client.renderer.texture.EntityTexManager;
import client.util.FileUtils;
import client.util.SkinConverter;
import client.vars.CVarCategory;
import client.vars.EnumVar;
import client.vars.Variable;
import client.vars.EnumVar.EnumFunction;
import client.window.Button;
import common.collect.Lists;
import common.dimension.DimType;
import common.dimension.Dimension;
import common.dimension.Space;
import common.entity.npc.Alignment;
import common.entity.npc.CharacterInfo;
import common.entity.npc.EntityHuman;
import common.entity.npc.EntityNPC;
import common.entity.npc.SpeciesInfo;
import common.entity.types.EntityLiving;
import common.init.EntityInfo;
import common.init.EntityRegistry;
import common.init.SpeciesRegistry;
import common.init.SpeciesRegistry.ModelType;
import common.log.Log;
import common.network.IPlayer;
import common.packet.CPacketAction;
import common.packet.CPacketMessage;
import common.packet.CPacketSkin;
import common.rng.Random;
import common.util.Displayable;
import common.util.Identifyable;
import common.util.Util;

public class GuiChar extends GuiList<GuiChar.SkinEntry>
{
	protected class SkinEntry implements ListEntry
	{
	    private final File skinFile;
	    private final String id;
	    private final ModelType model;
	    private final CharacterInfo charinfo;
	    private final BufferedImage skinImage;
	    private final int dynId;

	    protected SkinEntry(String id, File file, CharacterInfo charinfo, BufferedImage image, ModelType model)
	    {
	        this.skinFile = file;
	    	this.charinfo = charinfo;
	    	this.id = id;
	        this.model = model;
	        if(this.skinFile != null) {
	            this.skinImage = image;
	            int w = this.skinImage.getWidth();
	            int h = this.skinImage.getHeight();
	            int[] data = new int[w * h];
	            this.skinImage.getRGB(0, 0, w, h, data, 0, w);
	            this.dynId = 0xffff0000 + GuiChar.this.elements.size();
	        	EntityTexManager.setTexture(this.dynId, EntityTexManager.imageToComp(data, model), model);
	        }
	        else {
	            this.skinImage = null;
	        	this.dynId = -1;
	        }
	    }

	    public void draw(int x, int y, int width, int height, int mouseX, int mouseY, boolean hovered)
	    {
	        String str = 
	        		(this.skinFile != null ? this.skinFile.getName() : (
    				(this.charinfo.species.prefix && this.charinfo.type != null && !this.charinfo.type.toString().isEmpty() ? 
    				this.charinfo.type.toString() : 
    				EntityRegistry.getEntityName(this.charinfo.species.id))
    				+ (this.charinfo.name.isEmpty() ? "" : (" " + this.charinfo.name))));

	        Drawing.drawText(str, x + 64 + 3, y, 0xff000000 | (this.charinfo == null ? 
            		0xffffff : this.charinfo.color1 | this.charinfo.color2));
            if(this.charinfo != null)
	            Drawing.drawTextRight(this.charinfo.skin, x + width - 2, y + height - Font.HEIGHT, 0xffc0c0c0);

	        GlState.color(1.0F, 1.0F, 1.0F, 1.0F);
	        
	        if (hovered)
	            Drawing.drawRect(x, y, 64, 64, -1601138544);
	        
	        this.drawTextureAt(x, y, EntityTexManager.getSkin(this.dynId, this.charinfo != null ? this.charinfo.skin : null, this.model));
	    }

	    protected void drawTextureAt(int x, int y, String tex)
	    {
	        GlState.enableBlend();
	        GlState.enableDepth();
	        boolean flag = GuiChar.this.gm.cameraUsed;
	        GuiChar.this.gm.cameraUsed = true;
	        EntityTexManager.altTexture = tex;
	        EntityTexManager.altLayer = this.dynId;
	        EntityTexManager.altNpcLayer = this.dynId == -1 && this.charinfo != null ? this.charinfo.skin : null;
	        drawEntity(x + 32, y + 60, 28.0f 
	        		* Math.min(1.8f / GuiChar.this.gm.player.height, 1.5f / GuiChar.this.gm.player.width), -45.0f, -20.0f, GuiChar.this.gm.player);
	        GuiChar.this.gm.cameraUsed = flag;
	        EntityTexManager.altTexture = null;
	        EntityTexManager.altLayer = -1;
	        EntityTexManager.altNpcLayer = null;
	        GlState.disableBlend();
	        GlState.disableDepth();
	    }
	    
	    public void deleteTexture() {
	    	if(this.dynId != -1) {
	    		EntityTexManager.setTexture(this.dynId, null, null);
	    	}
	    }

	    public void select(boolean dclick, int mx, int my)
	    {
//            BufferedImage img = this.skinImage;
//            if(this.charinfo != null) {
//            	try {
//            		img = TextureUtil.readImage(FileUtils.getResource(
//            				EntityNPC.getSkinTexture(this.charinfo.skin)));
//            	}
//            	catch(IOException e) {
//            		if(e instanceof FileNotFoundException)
//						Log.JNI.warn("Textur für Skin ist nicht vorhanden: " + 
//						EntityNPC.getSkinTexture(this.charinfo.skin));
//					else
//						Log.JNI.error(e, "Konnte Textur nicht laden");
//            		return;
//            	}
//            }
            GuiChar.this.templateButton.enabled = this.charinfo != null;
    		if(this.skinImage == null) {
    			GuiChar.this.gm.getNetHandler().addToSendQueue(new CPacketSkin(null, this.charinfo.skin));
    		}
    		else {
    			int[] img = new int[this.model.texWidth * this.model.texHeight];
    			this.skinImage.getRGB(0, 0, this.skinImage.getWidth(), this.skinImage.getHeight(), img, 0, this.skinImage.getWidth());
    			GuiChar.this.gm.getNetHandler().addToSendQueue(new CPacketSkin(EntityTexManager.imageToComp(img, this.model), null));
    		}
//            GuiChar.this.gm.getNetHandler().addToSendQueue(new CPacketSkin(this.skinImage, this.skinImage != null ? null : this.charinfo.skin, this.model));
            GuiChar.this.currentSkin = this.skinFile != null ? this.skinFile.getName() : this.charinfo.skin;
            GuiChar.this.waiting = false;
	    }
	    
	    public String getLocation()
	    {
	        return this.charinfo == null ? null : this.charinfo.skin;
	    }
	}
	
	private class DragAdjust extends Element {
		private int mouseX;
		private int mouseY;
	    private float yawOffset;
	    private float pitchOffset;

		public DragAdjust(int x, int y, int w, int h) {
			super(x, y, w, h, null);
		}

		protected void drawBackground() {
			Drawing.drawRect(this.pos_x, this.pos_y, this.size_x, this.size_y, 0x20ffffff);
		}
		
		protected void drawForeground(int x1, int y1, int x2, int y2) {
		}
		
		public void drag(int x, int y) {
			GuiChar.this.yaw = this.yawOffset + (this.mouseX - x) * 2.0f;
			GuiChar.this.pitch = this.pitchOffset + (this.mouseY - y) * 2.0f;
		}

		public void mouse(Button btn, int x, int y, boolean ctrl, boolean shift) {
			this.mouseX = x;
			this.mouseY = y;
			this.yawOffset = GuiChar.this.yaw;
			this.pitchOffset = GuiChar.this.pitch;
		}

		public boolean canHover() {
			return false;
		}
	}
	
	public static enum FilterType implements Identifyable, Displayable {
		ALL("all", "Alle anzeigen"), CUSTOM("custom", "Nur eigene"), NPC("preset", "Nur vorgegebene"), SPECIES("species", "Nur Spezies"), SPECIES_CUSTOM("species_custom", "Spezies und eigene");

		private final String name;
		private final String display;
		
		private FilterType(String name, String display) {
			this.name = name;
			this.display = display;
		}
		
		public String getName() {
			return this.name;
		}
		
		public String getDisplay() {
			return this.display;
		}
	}

	public static class FilterFunction implements EnumFunction<FilterType> {
		public void apply(EnumVar cv, FilterType value) {
			if(Client.CLIENT.open instanceof GuiChar)
				Client.CLIENT.show(Client.CLIENT.open);
		}
	}
	
	public static final GuiChar INSTANCE = new GuiChar();
	private static final File TEXTURE_FOLDER = new File("skins");
	
	private final List<Dimension> dimensions = Lists.newArrayList();

    private ActButton templateButton;
    private DragAdjust adjust;
    private ActButton dimButton;
    private MultiLabel descLines;
    private ActButton cancelButton;
    private float yaw = -15.0f;
    private float pitch = -15.0f;
    private boolean waiting = true;
    private int dimension;
    private String currentSkin;

    @Variable(name = "char_filter_species", category = CVarCategory.GUI, display = "Filtern", callback = FilterFunction.class, switched = true)
	private FilterType filterSpecies = FilterType.ALL;
    
    private GuiChar() {
    }
    
    public void init(int width, int height)
    {
    	super.init(width, height);
    	this.dimensions.clear();
    	for(Dimension dim : DimensionMapping.getDimensions()) {
    		this.dimensions.add(dim);
    	}
    	this.waiting = true;
        this.setDimensions(390, height, 32, height - 32);
        if(this.gm.getRenderManager().gm == null) {
        	this.unload();
        	this.adjust = null;
        	return;
        }
        this.currentSkin = this.gm.player != null && !EntityTexManager.hasCustomSkin(this.gm.player.getId()) ? this.gm.player.getChar() : null;
        this.load(this.gm.player == null ? ModelType.HUMANOID : this.gm.player.getModel(), this.gm.player != null ? this.gm.player.getSpecies() : SpeciesRegistry.CLASSES.get(EntityHuman.class));
        this.add(new ActButton(2, 12, 193, 0, new ButtonCallback() {
			public void use(ActButton elem, PressType action) {
				GuiChar.this.gm.showFileDialog(FileMode.FILE_LOAD_MULTI, "Skin konvertieren", TEXTURE_FOLDER, new FileCallback() {
					public void selected(File file) {
						if(SkinConverter.convertSkin(file, TEXTURE_FOLDER, false))
							GuiChar.this.gm.show(GuiChar.this);
					}
				});
			}
		}, "Importieren: Standard"));
        this.add(new ActButton(197, 12, 193, 0, new ButtonCallback() {
			public void use(ActButton elem, PressType action) {
				GuiChar.this.gm.showFileDialog(FileMode.FILE_LOAD_MULTI, "Skin konvertieren (schlank)", TEXTURE_FOLDER, new FileCallback() {
					public void selected(File file) {
						if(SkinConverter.convertSkin(file, TEXTURE_FOLDER, true))
							GuiChar.this.gm.show(GuiChar.this);
					}
				});
			}
		}, "Importieren: Schlank"));
        this.addSelector("char_filter_species", 392, 12, 250, 0);
        this.add(new ActButton(2, height - 30, 193, 0, new ButtonCallback() {
			public void use(ActButton elem, PressType action) {
				GuiChar.this.gm.show(GuiChar.this);
			}
		}, "Neu laden"));
        this.templateButton = this.add(new ActButton(197, height - 30, 193, 0, new ButtonCallback() {
			public void use(ActButton elem, PressType action) {
				SkinEntry skin = GuiChar.this.getSelected();
				if(skin != null && skin.getLocation() != null) {
            		String loc = skin.getLocation();
            		File file = new File(TEXTURE_FOLDER, loc + ".png");
            		int z = 1;
            		while(file.exists()) {
            			file = new File(TEXTURE_FOLDER, loc + "_" + (++z) + ".png");
            		}
            		InputStream in = null;
            		try {
            			in = FileUtils.getResource(EntityNPC.getSkinTexture(loc));
            			Files.copy(in, file.toPath());
            		}
            		catch(Exception e) {
            			if(e instanceof FileNotFoundException)
							Log.IO.warn("Textur ist nicht zum Kopieren vorhanden: " + EntityNPC.getSkinTexture(loc));
						else
							Log.IO.error(e, "Konnte Textur nicht kopieren");
            		}
            		finally {
						if(in != null) {
							try {
								in.close();
							}
							catch(Throwable e) {
							}
						}
					}
            		GuiChar.this.gm.show(GuiChar.this);
            	}
			}
		}, "Vorlage kopieren"));
        if(width >= 784 + 460 && height >= 128 + 640)
            this.adjust = this.add(new DragAdjust(width / 2 - 230, height - 64 - 640, 460, 640));
        else
        	this.adjust = this.add(new DragAdjust(390 - 115 - 4, height - 32 - 160 - 4, 115, 160));

		this.add(new Label(width - 390, 48, 388, "Spezies: " + (this.gm.player == null ? "<?>" : this.gm.player.getSpecies().name), true));
        this.add(new NavButton(width - 390, 48, 388, 0, GuiSpecies.INSTANCE, "Spezies ändern"));
		this.add(new Label(width - 390, 82, 388, "Klasse: " + (this.gm.player == null || this.gm.player.getSpecies().classEnum == null || this.gm.player.getNpcClass() == null || this.gm.player.getNpcClass().toString().isEmpty() ? "<Keine>" : this.gm.player.getNpcClass().toString()), true))
			.enabled = this.gm.player != null && this.gm.player.getSpecies().classEnum != null;
        this.add(new NavButton(width - 390, 82, 388, 0, GuiClass.INSTANCE, "Klasse ändern"))
			.enabled = this.gm.player != null && this.gm.player.getSpecies().classEnum != null;
        
        final ActButton[] alignBtns = new ActButton[Alignment.values().length];
        for (int z = 0; z < Alignment.values().length; z++)
        {
        	final Alignment align = Alignment.values()[z];
        	alignBtns[z] = this.add(new ActButton(width - 390 + (z % 3) * 130, height - 32 - 20 * 3 + 20 * (z / 3), 128, 0, new ButtonCallback() {
    			public void use(ActButton elem, PressType action) {
                	if(GuiChar.this.gm.player != null) {
                		GuiChar.this.waiting = false;
                		GuiChar.this.gm.player.client.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_ALIGN, align.ordinal()));
                        for(ActButton btn : alignBtns) {
                        	btn.enabled = btn != elem;
                        }
                	}
    			}
    		}, align.color + align.display));
        	alignBtns[z].enabled = this.gm.player == null || this.gm.player.getAlignment() != align;
        }
        this.add(new Slider(width - 390, 136, 388, 0, 1, this.gm.player == null ? 120 : this.gm.player.getMinSize(), this.gm.player == null ? 320 : this.gm.player.getMaxSize(), this.gm.player == null ? 180 : this.gm.player.getDefaultSize(), this.gm.player == null ? 180 : this.gm.player.getCurrentSize(), new SliderCallback() {
			public void use(Slider elem, int value) {
				if(GuiChar.this.gm.player != null) {
            		GuiChar.this.waiting = false;
					GuiChar.this.gm.player.client.addToSendQueue(new CPacketAction(CPacketAction.Action.SET_HEIGHT, value));
				}
			}
		}, "Spieler-Größe", "cm")).enabled = this.gm.player == null || this.gm.player.getMinSize() != this.gm.player.getMaxSize();
		this.add(new Label(width - 390, 116, 388, "Name", true));
		this.add(new Label(width - 390, 170, 388, "Beschreibung", true));
    	final Area descField = this.add(new Area(width - 390, 170, 388, height - 328, IPlayer.MAX_INFO_LENGTH, ""));
        this.add(new ActButton(width - 195, height - 30, 193, 0, new ButtonCallback() {
			public void use(ActButton elem, PressType action) {
				if(GuiChar.this.gm.player != null) {
					GuiChar.this.gm.show(new GuiLoading("Lade Welt ..."));
					Dimension dim = GuiChar.this.dimensions.get(GuiChar.this.dimension);
		    		GuiChar.this.gm.player.client.addToSendQueue(new CPacketMessage(CPacketMessage.Type.INFO, descField.getText()));
					GuiChar.this.gm.player.client.addToSendQueue(new CPacketAction(CPacketAction.Action.CLOSE_EDITOR, DimensionMapping.getId(dim)));
				}
			}
		}, "Charakter erstellen"));
        this.cancelButton = this.add(new ActButton(width - 390, height - 30, 193, 0, new ButtonCallback() {
			public void use(ActButton elem, PressType action) {
				if(GuiChar.this.gm.player != null)
					GuiChar.this.gm.show(GuiCharacters.INSTANCE);
			}
		}, "Abbrechen"));
        this.setCharsAvailable();
    	this.add(new Field(width - 390, 116, 388, 0, IPlayer.MAX_NICK_LENGTH, new FieldCallback() {
			public void use(Field elem, FieldAction value) {
				if(value == FieldAction.SEND || value == FieldAction.UNFOCUS) {
					String name = elem.getText();
			    	if(name.isEmpty())
			    		elem.setText(GuiChar.this.gm.player == null ? "..." : GuiChar.this.gm.player.getCustomNameTag());
			    	else if(GuiChar.this.gm.player != null) {
                		GuiChar.this.waiting = false;
			    		GuiChar.this.gm.player.client.addToSendQueue(new CPacketMessage(CPacketMessage.Type.DISPLAY, name));
			    	}
				}
			}
		}, IPlayer.VALID_NICK, this.gm.player == null ? "" : this.gm.player.getCustomNameTag()));
        this.templateButton.enabled = false;
        this.dimension = new Random().zrange(this.dimensions.size());
    	EntityInfo info = EntityRegistry.DNA.get(this.gm.player == null ? EntityRegistry.getEntityString(EntityHuman.class) : EntityRegistry.getEntityString(this.gm.player));
    	if(info != null && info.origin() != null) {
    		Dimension dim = DimensionMapping.getDimension(info.origin());
    		if(dim != null) {
	        	for(int z = 0; z < this.dimensions.size(); z++) {
	        		if(this.dimensions.get(z) == dim) {
	        			this.dimension = z;
	        			break;
	        		}
	        	}
    		}
    	}
        this.dimButton = this.add(new ActButton(width - 390, height - 156, 388, 0, new ButtonCallback() {
			public void use(ActButton elem, PressType mode) {
				if(mode == PressType.TERTIARY) {
					GuiChar.this.dimension = new Random().zrange(GuiChar.this.dimensions.size());
	        	}
				else if(mode == PressType.SECONDARY) {
            		if(--GuiChar.this.dimension < 0)
            			GuiChar.this.dimension = GuiChar.this.dimensions.size() - 1;
            	}
            	else {
            		if(++GuiChar.this.dimension >= GuiChar.this.dimensions.size())
            			GuiChar.this.dimension = 0;
            	}
				GuiChar.this.setDimButton();
			}
		}, ""));
		this.descLines = this.add(new MultiLabel(width - 390, height - 156 + Element.BASE_HEIGHT, 388, 42, "", true));
        this.setDimButton();
    }
    
    private void setDimButton() {
    	Dimension dim = this.dimensions.get(this.dimension);
    	this.dimButton.setText((dim.getType() == DimType.PLANET ? "Heimplanet" : (dim.getType() == DimType.MOON ? "Heimmond" : (dim.getType() == DimType.STAR ? "Heimstern" : "Heimdimension"))) + ": " + (dim == Space.INSTANCE ? "*unbekannt*" : dim.getDisplay()));
	    this.descLines.setText(Util.buildLines(dim.getBaseNames()));
    }
    
    public void onGuiClosed()
    {
        this.unload();
    }
    
    public void drawOverlays()
    {
    	if(this.adjust != null) {
    		float factor = this.gm.player.width > 2.15f ? 2.15f / this.gm.player.width : 1.0f;
    		factor = this.gm.player.height > 3.0f && 3.0f / this.gm.player.height < factor ? 3.0f / this.gm.player.height : factor;
    		if(this.gm.fbX >= 784 + 460 && this.gm.fbY >= 128 + 640)
    			drawEntity(400 + (this.gm.fbX - 400 - 400) / 2, this.gm.fbY - 160, 160.0f * factor, this.yaw, this.pitch, this.gm.player);
    		else
    			drawEntity(390 - 4 - 115 / 2, this.gm.fbY - 60, 40.0f * factor, this.yaw, this.pitch, this.gm.player);
    	}
    }
    
    public void updateScreen() {
    	if(this.adjust == null && this.gm.getRenderManager().gm != null)
    		this.gm.show(this);
    }
    
    public void checkReopen() {
    	if(this.adjust != null && this.waiting) {
    		this.waiting = false;
    		this.gm.show(this);
    	}
    }
    
	public String getTitle() {
		return "Charakter anpassen";
	}
	
	public void setCharsAvailable() {
		if(this.cancelButton != null)
			this.cancelButton.enabled = !this.gm.characterList.isEmpty();
	}
	
    public static BufferedImage loadSkin(File file)
    {
    	BufferedImage img = null;
        try {
        	img = ImageIO.read(file);
        }
        catch(IOException e) {
        	return null;
        }
        if(img == null) {
        	return null;
        }
        return img;
    }

    public void load(ModelType model, SpeciesInfo speciesOnly)
    {
        this.unload();
        TEXTURE_FOLDER.mkdirs();
        File[] files = this.filterSpecies == FilterType.NPC || this.filterSpecies == FilterType.SPECIES ? null : TEXTURE_FOLDER.listFiles(new FileFilter() {
			public boolean accept(File pathname) {
				return pathname.isFile() && pathname.getName().endsWith(".png");
			}
		});
        int pos = 0;
//    	this.elements.add(new SkinEntry("default", null, null, null, model));
//		if("default".equals(currentSkin))
//			this.setSelected(pos);
//		pos++;
        if(files != null) {
	        Arrays.sort(files);
	        for(File file : files)
	        {
	        	BufferedImage img = loadSkin(file);
	        	if(img != null) {
        			if(img.getWidth() == model.texWidth && img.getHeight() == model.texHeight) {
		        		this.elements.add(new SkinEntry(file.getName(), file, null, img, model));
		        		if(file.getName().equals(this.currentSkin))
		        			this.setSelected(pos);
		        		pos++;
        			}
	        	}
	        }
        }
        if(this.filterSpecies == FilterType.CUSTOM)
        	return;
        for(SpeciesInfo species : this.filterSpecies == FilterType.SPECIES || this.filterSpecies == FilterType.SPECIES_CUSTOM ? Lists.newArrayList(speciesOnly) : SpeciesRegistry.SPECIMEN) {
	        for(CharacterInfo charinfo : species.chars) {
	        	if(charinfo.species.renderer == model) {
		        	this.elements.add(new SkinEntry(charinfo.skin, null, charinfo, null, charinfo.species.renderer));
		    		if(charinfo.skin.equals(this.currentSkin))
		    			this.setSelected(pos);
		    		pos++;
	        	}
	        }
        }
    }

    public void unload()
    {
        for (SkinEntry entry : this.elements)
        {
            entry.deleteTexture();
        }
        
        this.elements.clear();
    }
    
    public int getSlotHeight()
    {
        return 64 + 4;
    }

    
//    public static void drawEntityOnScreen(int posX, int posY, float scale, float mouseX, float mouseY, EntityLiving ent)
//    {
//        GlState.enableColorMaterial();
//        SKC.glPushMatrix();
//        SKC.glTranslatef((float)posX, (float)posY, 50.0F);
//        SKC.glScalef(-scale, scale, scale);
//        SKC.glRotatef(180.0F, 0.0F, 0.0F, 1.0F);
//        float f = ent.yawOffset;
//        float f1 = ent.rotYaw;
//        float f2 = ent.rotPitch;
//        float f3 = ent.prevHeadYaw;
//        float f4 = ent.headYaw;
//        SKC.glRotatef(135.0F, 0.0F, 1.0F, 0.0F);
//        ItemRenderer.enableStandardItemLighting();
//        SKC.glRotatef(-135.0F, 0.0F, 1.0F, 0.0F);
//        SKC.glRotatef(-((float)Math.atan((double)(mouseY / 40.0F))) * 20.0F, 1.0F, 0.0F, 0.0F);
//        ent.yawOffset = (float)Math.atan((double)(mouseX / 40.0F)) * 20.0F;
//        ent.rotYaw = (float)Math.atan((double)(mouseX / 40.0F)) * 40.0F;
//        ent.rotPitch = -((float)Math.atan((double)(mouseY / 40.0F))) * 20.0F;
//        ent.headYaw = ent.rotYaw;
//        ent.prevHeadYaw = ent.rotYaw;
//        SKC.glTranslatef(0.0F, 0.0F, 0.0F);
//        RenderManager rendermanager = Game.getGame().getRenderManager();
//        rendermanager.setPlayerViewY(180.0F);
////        rendermanager.setRenderShadow(false);
//        rendermanager.renderEntity(ent, 0.0D, 0.0D, 0.0D, 1.0F);
////        rendermanager.setRenderShadow(true);
//        ent.yawOffset = f;
//        ent.rotYaw = f1;
//        ent.rotPitch = f2;
//        ent.prevHeadYaw = f3;
//        ent.headYaw = f4;
//        SKC.glPopMatrix();
//        ItemRenderer.disableStandardItemLighting();
//        GlState.disableRescaleNormal();
//        GlState.setActiveTexture(SKC.GL_TEXTURE1);
//        GlState.disableTexture2D();
//        GlState.setActiveTexture(SKC.GL_TEXTURE0);
//    }
    
    public static void drawEntity(int posX, int posY, float scale, float yaw, float pitch, EntityLiving ent)
    {
		GlState.color(1.0F, 1.0F, 1.0F, 1.0F);
    	GlState.enableDepth();
        GlState.enableColorMaterial();
        GL11.glPushMatrix();
        GL11.glTranslatef((float)posX, (float)posY, 200.0F);
        GL11.glScalef(-scale, scale, scale);
        GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F);
        float f = ent.yawOffset;
        float f1 = ent.rotYaw;
        float f2 = ent.rotPitch;
        float f3 = ent.prevHeadYaw;
        float f4 = ent.headYaw;
        GL11.glRotatef(135.0F, 0.0F, 1.0F, 0.0F);
        ItemRenderer.enableStandardItemLighting();
        GL11.glRotatef(-135.0F, 0.0F, 1.0F, 0.0F);
        GL11.glTranslatef(0.0F, ent.height / 2, 0.0F);
        GL11.glRotatef(-pitch, 1.0F, 0.0F, 0.0F);
        ent.yawOffset = yaw;
        ent.rotYaw = yaw;
        ent.rotPitch = 0.0f;
        ent.headYaw = ent.rotYaw;
        ent.prevHeadYaw = ent.rotYaw;
        GL11.glTranslatef(0.0F, -(ent.height / 2), 0.0F);
        RenderManager rendermanager = Client.CLIENT.getRenderManager();
        rendermanager.setPlayerViewY(180.0F);
        rendermanager.renderEntity(ent, 0.0D, 0.0D, 0.0D, 1.0F);
//        GL11.glTranslatef(0.0F, 0.0F, 0.0F);
        ent.yawOffset = f;
        ent.rotYaw = f1;
        ent.rotPitch = f2;
        ent.prevHeadYaw = f3;
        ent.headYaw = f4;
        GL11.glPopMatrix();
        ItemRenderer.disableStandardItemLighting();
        GlState.disableRescaleNormal();
        GlState.setActiveTexture(GL13.GL_TEXTURE1);
        GlState.disableTexture2D();
        GlState.setActiveTexture(GL13.GL_TEXTURE0);
        GlState.disableDepth();
    }
}

