package common.attributes;

import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;

import common.collect.Maps;
import common.collect.Sets;
import common.util.LowerStringMap;

import java.util.Set;

public class AttributeMap
{
    protected final Map<Attribute, AttributeInstance> attributes = Maps.<Attribute, AttributeInstance>newHashMap();
    protected final Map<String, AttributeInstance> nameMap = new LowerStringMap();
    private final Set<AttributeInstance> dirtyAttributes;
    
    public AttributeMap(boolean client) {
    	this.dirtyAttributes = client ? null : Sets.<AttributeInstance>newHashSet();
    }

    public AttributeInstance getAttributeInstance(Attribute attribute)
    {
        return (AttributeInstance)this.attributes.get(attribute);
    }

    public AttributeInstance getAttributeInstanceByName(String attributeName)
    {
//    	AttributeInstance iattributeinstance = 
    	return (AttributeInstance)this.nameMap.get(attributeName);

//        if (iattributeinstance == null)
//        {
//            iattributeinstance = (AttributeInstance)this.descMap.get(attributeName);
//        }
//
//        return (AttributeInstance)iattributeinstance;
    }

    public AttributeInstance registerAttribute(Attribute attribute)
    {
        if(this.nameMap.containsKey(attribute.getUnlocalizedName()))
            throw new IllegalArgumentException("Attribute is already registered!");
        AttributeInstance inst = new AttributeInstance(this, attribute);
        this.nameMap.put(attribute.getUnlocalizedName(), inst);
        this.attributes.put(attribute, inst);
//            for (BaseAttribute iattribute = attribute.func_180372_d(); iattribute != null; iattribute = iattribute.func_180372_d())
//            {
//                this.field_180377_c.put(iattribute, attribute);
//            }
//        if(attribute.getDescription() != null)
//            this.descMap.put(attribute.getDescription(), inst);
        return inst;
    }

    public Collection<AttributeInstance> getAllAttributes()
    {
        return this.nameMap.values();
    }

    public void flagDirty(AttributeInstance instance)
    {
        if (this.dirtyAttributes != null && instance.getAttribute().getShouldWatch())
        {
            this.dirtyAttributes.add(instance);
        }

//        for (BaseAttribute iattribute : this.field_180377_c.get(instance.getAttribute()))
//        {
//            ModifiableAttributeInstance modifiableattributeinstance = this.getAttributeInstance(iattribute);
//
//            if (modifiableattributeinstance != null)
//            {
//                modifiableattributeinstance.flagForUpdate();
//            }
//        }
    }

    public Set<AttributeInstance> getDirty()
    {
        return this.dirtyAttributes;
    }

    public Collection<AttributeInstance> getWatchedAttributes()
    {
        Set<AttributeInstance> set = Sets.<AttributeInstance>newHashSet();

        for (AttributeInstance iattributeinstance : this.getAllAttributes())
        {
            if (iattributeinstance.getAttribute().getShouldWatch())
            {
                set.add(iattributeinstance);
            }
        }

        return set;
    }

    public void removeAttributeModifiers(Map<Attribute, Set<AttributeModifier>> modifiers)
    {
        for (Entry<Attribute, Set<AttributeModifier>> entry : modifiers.entrySet())
        {
            AttributeInstance iattributeinstance = this.getAttributeInstanceByName(entry.getKey().getUnlocalizedName());

            if (iattributeinstance != null)
            {
            	for(AttributeModifier mod : entry.getValue()) {
            		iattributeinstance.removeModifier(mod);
            	}
            }
        }
    }

    public void applyAttributeModifiers(Map<Attribute, Set<AttributeModifier>> modifiers)
    {
        for (Entry<Attribute, Set<AttributeModifier>> entry : modifiers.entrySet())
        {
            AttributeInstance iattributeinstance = this.getAttributeInstanceByName(entry.getKey().getUnlocalizedName());

            if (iattributeinstance != null)
            {
            	for(AttributeModifier mod : entry.getValue()) {
	                iattributeinstance.removeModifier(mod);
	                iattributeinstance.applyModifier(mod);
            	}
            }
        }
    }

    public void removeAttributeModifiers(Map<Attribute, Set<AttributeModifier>> modifiers, int slot, int amount)
    {
        for (Entry<Attribute, Set<AttributeModifier>> entry : modifiers.entrySet())
        {
            AttributeInstance iattributeinstance = this.getAttributeInstanceByName(entry.getKey().getUnlocalizedName());

            if (iattributeinstance != null)
            {
            	for(AttributeModifier mod : entry.getValue()) {
	            	AttributeModifier nmod = new AttributeModifier(mod, slot+1, amount);
	                iattributeinstance.removeModifier(nmod);
            	}
            }
        }
    }

    public void applyAttributeModifiers(Map<Attribute, Set<AttributeModifier>> modifiers, int slot, int amount)
    {
        for (Entry<Attribute, Set<AttributeModifier>> entry : modifiers.entrySet())
        {
            AttributeInstance iattributeinstance = this.getAttributeInstanceByName(entry.getKey().getUnlocalizedName());

            if (iattributeinstance != null)
            {
            	for(AttributeModifier mod : entry.getValue()) {
	            	AttributeModifier nmod = new AttributeModifier(mod, slot+1, amount);
	                iattributeinstance.removeModifier(nmod);
	                iattributeinstance.applyModifier(nmod);
            	}
            }
        }
    }
}
