﻿<?xml version="1.0" encoding="UTF-8"?>
<!-- ==================================================================================
|  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|  * See LICENSE.md in the project root for license terms and full copyright notice.
======================================================================================= -->
<ECSchema schemaName="Functional" alias="func" version="01.00.04" xmlns="http://www.bentley.com/schemas/Bentley.ECXML.3.2" description="The Functional schema defines common base classes to be used by discipline-specific functional domains.">

    <ECSchemaReference name="CoreCustomAttributes" version="01.00.03" alias="CoreCA"/>
    <ECSchemaReference name="BisCustomAttributes" version="01.00.00" alias="bisCA"/>
    <ECSchemaReference name="BisCore" version="01.00.15" alias="bis"/>
    <ECSchemaReference name="ECDbMap" version="02.00.00" alias="ecdbmap"/>

    <ECCustomAttributes>
        <ProductionStatus xmlns="CoreCustomAttributes.01.00.03">
            <SupportedUse>Production</SupportedUse>
        </ProductionStatus>
        <SchemaLayerInfo xmlns="BisCustomAttributes.01.00.00">
            <Value>Core</Value>
        </SchemaLayerInfo>
    </ECCustomAttributes>

    <ECEntityClass typeName="FunctionalPartition" displayLabel="Functional Partition" description="A func:FunctionalPartition element establishes a 'Functional' Modeling Perspective for its parent bis:Subject. It is intended to be specialized, and should be considered 'abstract'.">
        <BaseClass>bis:InformationPartitionElement</BaseClass>
        <ECCustomAttributes>
            <ClassHasHandler xmlns="BisCore.01.00.00" />
        </ECCustomAttributes>
    </ECEntityClass>

    <ECEntityClass typeName="FunctionalModel" displayLabel="Functional Model" description="A container for persisting func:FunctionalElement instances.">
        <BaseClass>bis:RoleModel</BaseClass>
        <ECCustomAttributes>
            <ClassHasHandler xmlns="BisCore.01.00.00"/>
        </ECCustomAttributes>
    </ECEntityClass>

    <ECEntityClass typeName="FunctionalElement" modifier="Abstract" displayLabel="Functional Element" description="A func:FunctionalElement models required functionality that will ultimately be fulfilled by a physical Entity.">
        <BaseClass>bis:RoleElement</BaseClass>
        <ECCustomAttributes>
            <ShareColumns xmlns="ECDbMap.02.00.00">
                <MaxSharedColumnsBeforeOverflow>32</MaxSharedColumnsBeforeOverflow>
                <ApplyToSubclassesOnly>True</ApplyToSubclassesOnly>
            </ShareColumns>
        </ECCustomAttributes>
        <ECNavigationProperty propertyName="TypeDefinition" relationshipName="FunctionalElementIsOfType" direction="Forward" displayLabel="Type Definition">
            <ECCustomAttributes>
                <ForeignKeyConstraint xmlns="ECDbMap.02.00.00"/>
            </ECCustomAttributes>
            <!-- NOTE: Has same propertyName as other element subclasses in case the concept of "TypeDefinition" needs to move down to bis:Element. -->
        </ECNavigationProperty>
    </ECEntityClass>

    <ECEntityClass typeName="FunctionalBreakdownElement" modifier="Abstract" displayLabel="Functional Breakdown" description="A func:FunctionalBreakdownElement models an aggregate functional Entity with child func:FunctionalElements modeling its parts.">
        <BaseClass>FunctionalElement</BaseClass>
        <BaseClass>bis:IParentElement</BaseClass>
        <ECCustomAttributes>
            <ClassHasHandler xmlns="BisCore.01.00.00"/>
        </ECCustomAttributes>
    </ECEntityClass>

    <ECEntityClass typeName="FunctionalComposite" displayLabel="Functional Composite" description="DEPRECATED: Inherit from FunctionalBreakdownElement instead.">
        <BaseClass>FunctionalBreakdownElement</BaseClass>
        <ECCustomAttributes>
            <ClassHasHandler xmlns="BisCore.01.00.00"/>
            <Deprecated xmlns="CoreCustomAttributes.01.00.03">
                <Description>The best practice is now to inherit from a FunctionalBreakdownElement instead.</Description>
            </Deprecated>
        </ECCustomAttributes>
    </ECEntityClass>

    <ECEntityClass typeName="FunctionalComponentElement" modifier="Abstract" displayLabel="Functional Component" description="A func:FunctionalComponentElement models an 'atomic' functional Entity which will not be sub-modeled at a finer granularity and does not have 'child' parts.">
        <BaseClass>FunctionalElement</BaseClass>
        <ECCustomAttributes>
            <ClassHasHandler xmlns="BisCore.01.00.00"/>
        </ECCustomAttributes>
    </ECEntityClass>

    <ECEntityClass typeName="FunctionalPortion" displayLabel="Functional Portion" description="DEPRECATED: A Functional Portion is a Functional Component that will be broken down in more detail in a separate (sub) Functional Model.">
        <ECCustomAttributes>
            <ClassHasHandler xmlns="BisCore.01.00.00"/>
            <Deprecated xmlns="CoreCustomAttributes.01.00.03">
                <Description>The best practice is now to inherit from a FunctionalComponentElement subclass and mix in ISubModeledElement when a breakdown concept is needed.</Description>
            </Deprecated>
        </ECCustomAttributes>
        <BaseClass>FunctionalComponentElement</BaseClass>
        <BaseClass>bis:ISubModeledElement</BaseClass>
    </ECEntityClass>

    <ECEntityClass typeName="FunctionalType" modifier="Abstract" displayLabel="Functional Type" description="Defines a shared set of properties (the 'type') that can be associated with a func:FunctionalElement.">
        <BaseClass>bis:TypeDefinitionElement</BaseClass>
        <ECCustomAttributes>
            <ClassHasHandler xmlns="BisCore.01.00.00"/>
        </ECCustomAttributes>
    </ECEntityClass>
    
    <ECRelationshipClass typeName="FunctionalElementIsOfType" strength="referencing" modifier="None" description="A type-instance relation; one that indicates that the specific func:FunctionalElement is an instance of the defined func:FunctionalType.">
        <Source multiplicity="(0..*)" roleLabel="is of type" polymorphic="true">
            <Class class="FunctionalElement" />
        </Source>
        <Target multiplicity="(0..1)" roleLabel="is type of" polymorphic="true">
            <Class class="FunctionalType"/>
        </Target>
    </ECRelationshipClass>

    <ECRelationshipClass typeName="PhysicalElementFulfillsFunction" strength="referencing" modifier="None" description="Relates func:FunctionalElement instances (which model a required function) to the bis:PhysicalElement instances that model the physical Entity that fulfills the function." >
        <BaseClass>bis:ElementRefersToElements</BaseClass>
        <Source multiplicity="(0..*)" roleLabel="fulfills" polymorphic="true">
            <Class class="bis:PhysicalElement"/>
        </Source>
        <Target multiplicity="(0..*)" roleLabel="is fulfilled by" polymorphic="true">
            <Class class="FunctionalElement"/>
        </Target>
    </ECRelationshipClass>

    <ECRelationshipClass typeName="DrawingGraphicRepresentsFunctionalElement" strength="referencing" modifier="None" description="Relates bis:DrawingGraphic instances to the func:FunctionalElement instances they represent.">
        <BaseClass>bis:DrawingGraphicRepresentsElement</BaseClass>
        <Source multiplicity="(0..*)" roleLabel="represents" polymorphic="true">
            <Class class="bis:DrawingGraphic"/>
        </Source>
        <Target multiplicity="(0..*)" roleLabel="is represented by" polymorphic="true">
            <Class class="FunctionalElement"/>
        </Target>
    </ECRelationshipClass>

</ECSchema>
