package electrosphere.entity.types.creature;

import java.util.HashMap;
import java.util.Map;

import electrosphere.engine.Globals;
import electrosphere.game.data.creature.type.CreatureData;
import electrosphere.game.data.creature.type.visualattribute.VisualAttribute;
import electrosphere.net.synchronization.transport.StateCollection;

/**
 * The template used to construct the creature on the client
 */
public class CreatureTemplate {

    /**
     * The type of the creature
     */
    String creatureType;
    
    /**
     * The attribute map for visual variants
     */
    Map<String,CreatureTemplateAttributeValue> attributeMap = new HashMap<String,CreatureTemplateAttributeValue>();

    /**
     * The equip data for the creature
     */
    private CreatureEquipData equipData = new CreatureEquipData();

    /**
     * The toolbar data for the creature
     */
    private CreatureToolbarData toolbarData = new CreatureToolbarData();

    /**
     * The collection of synchronized values
     */
    private StateCollection stateCollection;

    /**
     * Creates the creature template
     * @param creatureType The type of creature
     * @return The creature template
     */
    public static CreatureTemplate create(String creatureType){
        CreatureTemplate rVal = new CreatureTemplate();
        rVal.creatureType = creatureType;
        return rVal;
    }

    /**
     * Puts an attribute value in the template
     * @param attributeName The name of the attribute
     * @param value The value of the attribute
     */
    public void putAttributeValue(String attributeName, float value){
        attributeMap.put(attributeName,new CreatureTemplateAttributeValue(value));
    }

    /**
     * Puts an attribute value into the template
     * @param attributeName The name of the attribute
     * @param value The value of the attribute
     */
    public void putAttributeValue(String attributeName, String value){
        attributeMap.put(attributeName,new CreatureTemplateAttributeValue(value));
    }

    /**
     * Gets the value of an attribte
     * @param attributeName The name of the attribute
     * @return The value of the attribute
     */
    public CreatureTemplateAttributeValue getAttributeValue(String attributeName){
        return attributeMap.get(attributeName);
    }

    /**
     * Gets the type of the creature
     * @return The type of the creature
     */
    public String getCreatureType(){
        return creatureType;
    }

    /**
     * Gets the creature equip data for the template
     * @return The creature equip data for the template
     */
    public CreatureEquipData getCreatureEquipData(){
        return this.equipData;
    }

    /**
     * Gets the toolbar data for the template
     * @return The toolbar data for the template
     */
    public CreatureToolbarData getCreatureToolbarData(){
        return this.toolbarData;
    }

    /**
     * Gets the state collection for the creature
     * @return The collection of synchronized values
     */
    public StateCollection getStateCollection(){
        return this.stateCollection;
    }

    /**
     * Sets the synchronized values for this creature
     * @param stateCollection The synchronized values
     */
    public void setStateCollection(StateCollection stateCollection){
        this.stateCollection = stateCollection;
    }

    /**
     * Creates a template for the creature with default values
     * @param creatureType The type of creature
     * @return The basic template
     */
    public static CreatureTemplate createDefault(String creatureType){
        CreatureTemplate storedTemplate = CreatureTemplate.create(creatureType);
        CreatureData rawType = Globals.gameConfigCurrent.getCreatureTypeLoader().getType(creatureType);
        if(rawType.getVisualAttributes() != null){
            for(VisualAttribute attributeType : rawType.getVisualAttributes()){
                if(attributeType.getType().equals("remesh")){
                    if(attributeType.getVariants() != null && attributeType.getVariants().size() > 0){
                        //make sure stored template contains creature data
                        if(storedTemplate.getAttributeValue(attributeType.getAttributeId())==null){
                            storedTemplate.putAttributeValue(attributeType.getAttributeId(), attributeType.getVariants().get(0).getId());
                        }
                    }
                }
                if(attributeType.getType().equals("bone")){
                    //make sure stored template contains creature data
                    float midpoint = (attributeType.getMaxValue() - attributeType.getMinValue())/2.0f + attributeType.getMinValue();
                    storedTemplate.putAttributeValue(attributeType.getAttributeId(), midpoint);
                }
            }
        }
        return storedTemplate;
    }

    /**
     * A visual attribute of a creature (ie how wide is their nose, what type of hairstyle do they have, etc)
     */
    public class CreatureTemplateAttributeValue {

        /**
         * The string value of the attribute
         */
        String variantId;

        /**
         * The float value of the attribute
         */
        float value;

        /**
         * Creates a float attribute
         * @param value The value
         */
        public CreatureTemplateAttributeValue(float value){
            this.value = value;
        }

        /**
         * Creates a string attribute
         * @param variantId The string
         */
        public CreatureTemplateAttributeValue(String variantId){
            this.variantId = variantId;
        }

        /**
         * Gets the float value of the attribute
         * @return The value
         */
        public float getValue(){
            return value;
        }

        /**
         * Gets the string value of the attribute
         * @return The string value
         */
        public String getVariantId(){
            return variantId;
        }

        /**
         * Sets the float value of the attribute
         * @param value The float value
         */
        public void setValue(float value){
            this.value = value;
        }

        /**
         * Sets the string value of the attribute
         * @param variantId The string value
         */
        public void setVariantId(String variantId){
            this.variantId = variantId;
        }

    }

}
