package common.tileentity;

import java.util.List;

import common.collect.Lists;
import common.color.DyeColor;
import common.init.Items;
import common.item.ItemStack;
import common.network.Packet;
import common.packet.SPacketUpdateTileEntity;
import common.tags.TagObject;

public class TileEntityBanner extends TileEntity
{
    private int baseColor;

    /** A list of all the banner patterns. */
    private List<TagObject> patterns;
    private boolean field_175119_g;
    private List<TileEntityBanner.EnumBannerPattern> patternList;
    private List<DyeColor> colorList;

    /**
     * This is a String representation of this banners pattern and color lists, used for texture caching.
     */
    private String patternResourceLocation;

    public void setItemValues(ItemStack stack)
    {
        this.patterns = null;

        if (stack.hasTagCompound() && stack.getTagCompound().hasObject("BlockEntityTag"))
        {
            TagObject nbttagcompound = stack.getTagCompound().getObject("BlockEntityTag");

            if (nbttagcompound.hasList("Patterns"))
            {
                this.patterns = Lists.newArrayList();
                for(TagObject pattern : nbttagcompound.getList("Patterns")) {
                	this.patterns.add(pattern.copy());
                }
            }

            if (nbttagcompound.hasInt("Base"))
            {
                this.baseColor = nbttagcompound.getInt("Base");
            }
            else
            {
                this.baseColor = DyeColor.WHITE.getDyeDamage();
            }
        }
        else
        {
            this.baseColor = DyeColor.WHITE.getDyeDamage();
        }

        this.patternList = null;
        this.colorList = null;
        this.patternResourceLocation = "";
        this.field_175119_g = true;
    }

    public void writeTags(TagObject compound)
    {
        super.writeTags(compound);
        setBaseColorAndPatterns(compound, this.baseColor, this.patterns);
    }

    public static void setBaseColorAndPatterns(TagObject compound, int baseColorIn, List<TagObject> patternsIn)
    {
        compound.setInt("Base", baseColorIn);

        if (patternsIn != null)
        {
            compound.setList("Patterns", patternsIn);
        }
    }

    public void readTags(TagObject compound)
    {
        super.readTags(compound);
        this.baseColor = compound.getInt("Base");
        this.patterns = compound.getList("Patterns");
        this.patternList = null;
        this.colorList = null;
        this.patternResourceLocation = null;
        this.field_175119_g = true;
    }

    /**
     * Allows for a specialized description packet to be created. This is often used to sync tile entity data from the
     * server to the client easily. For example this is used by signs to synchronise the text to be displayed.
     */
    public Packet getDescriptionPacket()
    {
        return new SPacketUpdateTileEntity(this);
    }

    public int getBaseColor()
    {
        return this.baseColor;
    }

    public static DyeColor getBaseColor(ItemStack stack)
    {
        TagObject nbttagcompound = stack.getSubCompound("BlockEntityTag", false);
        return nbttagcompound != null && nbttagcompound.hasInt("Base") ? DyeColor.byDyeDamage(nbttagcompound.getInt("Base")) : DyeColor.WHITE;
    }

    /**
     * Retrieves the amount of patterns stored on an ItemStack. If the tag does not exist this value will be 0.
     */
    public static int getPatterns(ItemStack stack)
    {
        TagObject nbttagcompound = stack.getSubCompound("BlockEntityTag", false);
        return nbttagcompound != null && nbttagcompound.hasList("Patterns") ? nbttagcompound.getList("Patterns").size() : 0;
    }

    public List<TileEntityBanner.EnumBannerPattern> getPatternList()
    {
        this.initializeBannerData();
        return this.patternList;
    }

    public List<TagObject> getPatterns()
    {
        return this.patterns;
    }

    public List<DyeColor> getColorList()
    {
        this.initializeBannerData();
        return this.colorList;
    }

    public String getPatternResourceLocation()
    {
        this.initializeBannerData();
        return this.patternResourceLocation;
    }

    /**
     * Establishes all of the basic properties for the banner. This will also apply the data from the tile entities nbt
     * tag compounds.
     */
    private void initializeBannerData()
    {
        if (this.patternList == null || this.colorList == null || this.patternResourceLocation == null)
        {
            if (!this.field_175119_g)
            {
                this.patternResourceLocation = "";
            }
            else
            {
                this.patternList = Lists.<TileEntityBanner.EnumBannerPattern>newArrayList();
                this.colorList = Lists.<DyeColor>newArrayList();
                this.patternList.add(TileEntityBanner.EnumBannerPattern.BASE);
                this.colorList.add(DyeColor.byDyeDamage(this.baseColor));
                this.patternResourceLocation = "b" + this.baseColor;

                if (this.patterns != null)
                {
                    for (int i = 0; i < this.patterns.size(); ++i)
                    {
                        TagObject nbttagcompound = this.patterns.get(i);
                        TileEntityBanner.EnumBannerPattern tileentitybanner$enumbannerpattern = TileEntityBanner.EnumBannerPattern.getPatternByID(nbttagcompound.getString("Pattern"));

                        if (tileentitybanner$enumbannerpattern != null)
                        {
                            this.patternList.add(tileentitybanner$enumbannerpattern);
                            int j = nbttagcompound.getInt("Color");
                            this.colorList.add(DyeColor.byDyeDamage(j));
                            this.patternResourceLocation = this.patternResourceLocation + tileentitybanner$enumbannerpattern.getPatternID() + j;
                        }
                    }
                }
            }
        }
    }
    
    public int getColor() {
    	return 0xffffff;
    }

    /**
     * Removes all the banner related data from a provided instance of ItemStack.
     */
    public static void removeBannerData(ItemStack stack)
    {
        TagObject nbttagcompound = stack.getSubCompound("BlockEntityTag", false);

        if (nbttagcompound != null && nbttagcompound.hasList("Patterns"))
        {
        	List<TagObject> nbttaglist = nbttagcompound.getList("Patterns");

            if (nbttaglist.size() > 0)
            {
                nbttaglist.remove(nbttaglist.size() - 1);

                if (nbttaglist.isEmpty())
                {
                    stack.getTagCompound().remove("BlockEntityTag");

                    if (stack.getTagCompound().isEmpty())
                    {
                        stack.setTagCompound((TagObject)null);
                    }
                }
            }
        }
    }

    public static enum EnumBannerPattern
    {
        BASE("base", "b", "%s Banner", 0, false),
        SQUARE_BOTTOM_LEFT("square_bottom_left", "bl", "%s rechtes Untereck", 0, false, "   ", "   ", "#  "),
        SQUARE_BOTTOM_RIGHT("square_bottom_right", "br", "%s linkes Untereck", 0, false, "   ", "   ", "  #"),
        SQUARE_TOP_LEFT("square_top_left", "tl", "%s rechtes Obereck", 0, false, "#  ", "   ", "   "),
        SQUARE_TOP_RIGHT("square_top_right", "tr", "%s linkes Obereck", 0, false, "  #", "   ", "   "),
        STRIPE_BOTTOM("stripe_bottom", "bs", "%s Bannerfuß", 1, false, "   ", "   ", "###"),
        STRIPE_TOP("stripe_top", "ts", "%s Bannerhaupt", 0, false, "###", "   ", "   "),
        STRIPE_LEFT("stripe_left", "ls", "%s rechte Flanke", -1, false, "#  ", "#  ", "#  "),
        STRIPE_RIGHT("stripe_right", "rs", "%s linke Flanke", -1, false, "  #", "  #", "  #"),
        STRIPE_CENTER("stripe_center", "cs", "%s Pfahl", 1, false, " # ", " # ", " # "),
        STRIPE_MIDDLE("stripe_middle", "ms", "%s Balken", 1, false, "   ", "###", "   "),
        STRIPE_DOWNRIGHT("stripe_downright", "drs", "%s Schrägbalken", 1, false, "#  ", " # ", "  #"),
        STRIPE_DOWNLEFT("stripe_downleft", "dls", "%s Schräglinksbalken", 1, false, "  #", " # ", "#  "),
        STRIPE_SMALL("small_stripes", "ss", "Vier %s Pfähle", 1, true, "# #", "# #", "   "),
        CROSS("cross", "cr", "%s Andreaskreuz", 0, false, "# #", " # ", "# #"),
        STRAIGHT_CROSS("straight_cross", "sc", "%s Kreuz", 0, false, " # ", "###", " # "),
        TRIANGLE_BOTTOM("triangle_bottom", "bt", "%s halbe Spitze", -1, false, "   ", " # ", "# #"),
        TRIANGLE_TOP("triangle_top", "tt", "%s gestürzte halbe Spitze", -1, false, "# #", " # ", "   "),
        TRIANGLES_BOTTOM("triangles_bottom", "bts", "%s gespickelter Bannerfuß", 1, false, "   ", "# #", " # "),
        TRIANGLES_TOP("triangles_top", "tts", "%s gespickeltes Bannerhaupt", 0, false, " # ", "# #", "   "),
        DIAGONAL_LEFT("diagonal_left", "ld", "%s schräglinks geteilt", null, false, "## ", "#  ", "   "),
        DIAGONAL_RIGHT("diagonal_up_right", "rd", "%s schräglinks geteilt (Invertiert)", null, false, "   ", "  #", " ##"),
        DIAGONAL_LEFT_MIRROR("diagonal_up_left", "lud", "%s schrägrechts geteilt (Invertiert)", null, false, "   ", "#  ", "## "),
        DIAGONAL_RIGHT_MIRROR("diagonal_right", "rud", "%s schrägrechts geteilt", null, false, " ##", "  #", "   "),
        CIRCLE_MIDDLE("circle", "mc", "%s Kugel", -1, false, "   ", " # ", "   "),
        RHOMBUS_MIDDLE("rhombus", "mr", "%s Raute", -1, false, " # ", "# #", " # "),
        HALF_VERTICAL("half_vertical", "vh", "Rechts %s gespalten", null, true, "## ", "## ", "## "),
        HALF_HORIZONTAL("half_horizontal", "hh", "Oben %s geteilt", null, true, "###", "###", "   "),
        HALF_VERTICAL_MIRROR("half_vertical_right", "vhr", "Links %s gespalten", null, true, " ##", " ##", " ##"),
        HALF_HORIZONTAL_MIRROR("half_horizontal_bottom", "hhb", "Unten %s geteilt", null, true, "   ", "###", "###"),
        BORDER("border", "bo", "%s Bord", 1, false, "###", "# #", "###"),
        CURLY_BORDER("curly_border", "cbo", "%s Spickelbord", 1, false, new ItemStack(Items.vine)),
        RUNE("rune", "run", "%s Rune", -1, false, new ItemStack(Items.golden_apple)),
        GRADIENT("gradient", "gra", "%s Farbverlauf", 1, false, "# #", " # ", " # "),
        GRADIENT_UP("gradient_up", "gru", "%s Farbverlauf (Invertiert)", 1, false, " # ", " # ", "# #"),
        BRICKS("bricks", "bri", "Feld %s gemauert", null, true, new ItemStack(Items.brick_block)),
        SKULL("skull", "sku", "%s Schädel", 1, false, new ItemStack(Items.skull)),
        FLOWER("flower", "flo", "%s Blume", -1, false, new ItemStack(Items.daisy)),
        THING("thing", "thi", "%s <???>", 0, false, new ItemStack(Items.charged_apple));

        private String patternName;
        private String patternID;
        private String display;
        private Integer displayType;
        private boolean displayLower;
        private String[] craftingLayers;
        private ItemStack patternCraftingStack;

        private EnumBannerPattern(String name, String id, String display, Integer displayType, boolean displayLower)
        {
            this.craftingLayers = new String[3];
            this.patternName = name;
            this.patternID = id;
            this.display = display;
            this.displayType = displayType;
        }

        private EnumBannerPattern(String name, String id, String display, Integer displayType, boolean displayLower, ItemStack craftingItem)
        {
            this(name, id, display, displayType, displayLower);
            this.patternCraftingStack = craftingItem;
        }

        private EnumBannerPattern(String name, String id, String display, Integer displayType, boolean displayLower, String craftingTop, String craftingMid, String craftingBot)
        {
            this(name, id, display, displayType, displayLower);
            this.craftingLayers[0] = craftingTop;
            this.craftingLayers[1] = craftingMid;
            this.craftingLayers[2] = craftingBot;
        }

        public String getPatternName()
        {
            return this.patternName;
        }

        public String getPatternID()
        {
            return this.patternID;
        }

        public String getDisplay()
        {
            return this.display;
        }

        public Integer getDisplayType()
        {
            return this.displayType;
        }

        public boolean isColorLowercase()
        {
            return this.displayLower;
        }

        public String[] getCraftingLayers()
        {
            return this.craftingLayers;
        }

        public boolean hasValidCrafting()
        {
            return this.patternCraftingStack != null || this.craftingLayers[0] != null;
        }

        public boolean hasCraftingStack()
        {
            return this.patternCraftingStack != null;
        }

        public ItemStack getCraftingStack()
        {
            return this.patternCraftingStack;
        }

        public static TileEntityBanner.EnumBannerPattern getPatternByID(String id)
        {
            for (TileEntityBanner.EnumBannerPattern tileentitybanner$enumbannerpattern : values())
            {
                if (tileentitybanner$enumbannerpattern.patternID.equals(id))
                {
                    return tileentitybanner$enumbannerpattern;
                }
            }

            return null;
        }
    }
}
