package org.apache.slide.projector.constraints;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.contract.Context;
import org.apache.commons.contract.constraints.CastException;
import org.apache.commons.contract.constraints.Constraints;
import org.apache.commons.contract.constraints.ValidationException;
import org.apache.commons.i18n.LocalizedError;
import org.apache.commons.i18n.LocalizedText;
import org.apache.slide.projector.ContentType;
import org.apache.slide.projector.value.Text;

public class TextConstraints implements Constraints {
    public final static TextConstraints UNCONSTRAINED = new TextConstraints();
    
    protected boolean constrained;
    protected List allowedContentTypes = new ArrayList();

    public TextConstraints() {
        this.constrained = false;
    }

    public TextConstraints(String[] allowedContentTypes) {
        this.constrained = true;
        this.allowedContentTypes = new ArrayList(Arrays.asList(allowedContentTypes));
    }

    public void addAllowedContentType(String contentType) {
        constrained = true;
        allowedContentTypes.add(contentType);
    }

    public boolean isConstrained() {
        return constrained;
    }

    public boolean isEnumrable() {
        return ( allowedContentTypes.size() > 0 );
    }

    public String[] getAllowedContentTypes() {
        return (String [])allowedContentTypes.toArray(new String [allowedContentTypes.size()]);
    }

    public Object cast(Object value, Context context) throws CastException {
        if (value instanceof Text) {
            return value;
        } else if (value instanceof String) {
            return new Text((String)value);
        } else if (value instanceof String[]) {
            return new Text(((String [])value)[0]);
        } else {
            return new Text(value.toString());
        }
    }

    public void validate(Object value, Context context) throws ValidationException {
        Text text = (Text)value;
        if ( constrained ) {
    		if ( isEnumrable() ) {
    			for ( Iterator i = allowedContentTypes.iterator(); i.hasNext(); ) {
    				if (ContentType.matches((String)i.next(), text.getContentType())) {
    					return;
    				}
    			}
    			throw new ValidationException(new LocalizedError("invalidTextValue", new String[] { text.getContentType() }));
    		}
    	}
    }

    public LocalizedText verboseConstraints() {
        return null;
    }
}