package de.uni_hamburg.fs;

import collections.CollectionEnumeration;


/**
 * Abstract base class representing a type defined by a single concept in the feature structure system.
 * Implements both Type and ParsedType interfaces by delegating most operations to its underlying concept.
 * This class serves as a wrapper around a Concept to provide type-specific functionality.
 */
public abstract class SingleConceptType implements Type, ParsedType {
    /**
     * The underlying concept that defines this type's structure and behavior.
     * Most type operations are delegated to this concept instance.
     */
    Concept _concept;

    /**
     * Default constructor for SingleConceptType.
     */
    protected SingleConceptType() {}

    /**
     * Return whether this Type is extensional.
     */
    @Override
    public boolean isExtensional() {
        return _concept.isExtensional();
    }

    /**
     * Returns the concept that defines this type.
     * All type-specific behavior is determined by this concept.
     *
     * @return the underlying concept of this type
     */
    public Concept getConcept() {
        return _concept;
    }

    /**
     * Return whether the feature {@literal <feature>} is appropriate in this Type.
     */
    @Override
    public boolean isApprop(Name featureName) {
        return _concept.isApprop(featureName);
    }

    /**
     * Return the required Type of the Value found under the given feature.
     * The feature has to be appropriate for this Type.
     */
    @Override
    public Type appropType(Name featureName) throws NoSuchFeatureException {
        return _concept.appropType(featureName);
    }

    /**
     * Return an Enumeration of all appropriate features.
     */
    @Override
    public CollectionEnumeration appropFeatureNames() {
        return _concept.appropFeatureNames();
    }

    @Override
    public String toString() {
        return getName();
    }

    @Override
    public ParsedType unite(ParsedType that) throws UnificationFailure {
        if (that.equals(ParsedType.PARSED_TOP)) {
            return this;
        }
        if (that instanceof BasicType) {
            return (BasicType) unify((BasicType) that);
        }
        throw new UnificationFailure();
    }

    @Override
    public Type asType() throws UnificationFailure {
        return this;
    }
}