package common.packet;

import java.io.IOException;
import java.util.List;

import common.entity.DataWatcher;
import common.entity.npc.EntityNPC;
import common.init.EntityRegistry;
import common.init.ItemRegistry;
import common.item.ItemStack;
import common.network.IClientPlayer;
import common.network.IPlayer;
import common.network.Packet;
import common.network.PacketBuffer;
import common.util.ExtMath;

public class SPacketSpawnPlayer implements Packet<IClientPlayer>
{
    private int entityId;
    private int type;
    private int x;
    private int y;
    private int z;
    private byte yaw;
    private byte pitch;
    private int currentItem;
    private DataWatcher watcher;
    private List<DataWatcher.WatchableObject> data;
	private byte[] texture;

    public SPacketSpawnPlayer()
    {
    }

    public SPacketSpawnPlayer(EntityNPC player)
    {
        this.entityId = player.getId();
        this.type = EntityRegistry.getEntityID(player);
        this.x = ExtMath.floord(player.posX * 32.0D);
        this.y = ExtMath.floord(player.posY * 32.0D);
        this.z = ExtMath.floord(player.posZ * 32.0D);
        this.yaw = (byte)((int)(player.rotYaw * 256.0F / 360.0F));
        this.pitch = (byte)((int)(player.rotPitch * 256.0F / 360.0F));
        ItemStack itemstack = player.inventory.getCurrentItem();
        this.currentItem = itemstack == null ? 0 : ItemRegistry.getIdFromItem(itemstack.getItem());
        this.watcher = player.getDataWatcher();
        this.texture = player.getSkin();
    }

    /**
     * Reads the raw packet data from the data stream.
     */
    public void readPacketData(PacketBuffer buf) throws IOException
    {
        this.entityId = buf.readVarInt();
        this.type = buf.readUnsignedShort();
        this.x = buf.readInt();
        this.y = buf.readInt();
        this.z = buf.readInt();
        this.yaw = buf.readByte();
        this.pitch = buf.readByte();
        this.currentItem = buf.readShort();
        this.data = DataWatcher.readWatchedListFromPacketBuffer(buf);
        this.texture = buf.readByteArray();
        if(this.texture.length == 0) {
        	this.texture = null;
        }
        else if(this.texture.length > IPlayer.MAX_SKIN_SIZE) {
        	this.texture = new byte[IPlayer.MAX_SKIN_SIZE];
        }
    }

    /**
     * Writes the raw packet data to the data stream.
     */
    public void writePacketData(PacketBuffer buf) throws IOException
    {
        buf.writeVarInt(this.entityId);
        buf.writeShort(this.type & 65535);
        buf.writeInt(this.x);
        buf.writeInt(this.y);
        buf.writeInt(this.z);
        buf.writeByte(this.yaw);
        buf.writeByte(this.pitch);
        buf.writeShort(this.currentItem);
        this.watcher.writeTo(buf);
    	buf.writeByteArray(this.texture == null ? new byte[0] : this.texture);
    }

    /**
     * Passes this Packet on to the NetHandler for processing.
     */
    public void processPacket(IClientPlayer handler)
    {
        handler.handleSpawnPlayer(this);
    }

    public List<DataWatcher.WatchableObject> getData()
    {
        if (this.data == null)
        {
            this.data = this.watcher.getAllWatched();
        }

        return this.data;
    }

    public int getEntityID()
    {
        return this.entityId;
    }

    public int getEntityType()
    {
        return this.type;
    }

    public int getX()
    {
        return this.x;
    }

    public int getY()
    {
        return this.y;
    }

    public int getZ()
    {
        return this.z;
    }

    public float getYaw()
    {
    	return (float)(((int)this.yaw) * 360) / 256.0F;
    }

    public float getPitch()
    {
        return (float)(((int)this.pitch) * 360) / 256.0F;
    }

    public int getCurrentItemID()
    {
        return this.currentItem;
    }
    
    public byte[] getTexture() {
    	return this.texture;
    }
}
