package org.apache.slide.projector.constraints;

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

import org.apache.commons.contract.constraints.Constraints;
import org.apache.commons.contract.constraints.MapConstraints;
import org.apache.commons.contract.descriptor.ParameterDescriptor;
import org.apache.commons.contract.i18n.ParameterMessage;
import org.apache.commons.xmlio.out.XMLStringWriter;
import org.apache.commons.xmlio.out.XMLWriter;
import org.jdom.Element;

public class MapFactory extends AbstractValueFactory {
	public Class getValueClass() {
		return Map.class;
	}

	public String getElementName() {
    	return "map";
    }

	public Object load(Element element) {
		Map map = new HashMap();
		for ( Iterator i = element.getChildren().iterator(); i.hasNext(); ) {
			Element childElement = (Element)i.next();
			String key = childElement.getAttributeValue("key");
			Element entryElement = (Element)childElement.getChildren().iterator().next();
			map.put(key, ConstraintsManager.getInstance().loadValue(entryElement));			
		}
		return map;
	}

    public void save(Object value, XMLStringWriter writer) {
    	Map map = (Map)value;
        writer.writeStartTag(XMLWriter.createStartTag(getElementName()));
        for ( Iterator i = map.entrySet().iterator(); i.hasNext(); ) {
            Map.Entry entry = (Map.Entry)i.next();
            writer.writeStartTag(XMLWriter.createStartTag("entry", "key", (String)entry.getKey()));
            ConstraintsManager.getInstance().saveValue(entry.getValue(), writer);
            writer.writeEndTag(XMLWriter.createEndTag("entry"));
        }
        writer.writeEndTag(XMLWriter.createEndTag(getElementName()));
    }

    public Constraints loadDescriptor(Element element) {
		MapConstraints valueDescriptor = new MapConstraints();
		for ( Iterator i = element.getChildren().iterator(); i.hasNext(); ) {
			Element entry = (Element)i.next();
			String key = entry.getAttributeValue("key");
			String description = entry.getAttributeValue("description");
    		Element allowedEntryValueElement = (Element)element.getChildren().iterator().next();
   			Constraints allowedEntryValue = ConstraintsManager.getInstance().loadConstraints(allowedEntryValueElement);
   			valueDescriptor.addEntryDescriptor(new ParameterDescriptor(key, new ParameterMessage(description), allowedEntryValue));
		}
		return valueDescriptor;
    }
}