/* file: tolerance_zone_definition.swift 	 generated: Mon Jan  3 16:32:52 2022 */

/* This file was generated by the EXPRESS to Swift translator "exp2swift", 
    derived from STEPcode (formerly NIST's SCL).
 exp2swift version: v.1.0.1, derived from stepcode v0.8 as of 2019/11/23 
 WARNING: You probably don't want to edit it since your modifications 
    will be lost if exp2swift is used to regenerate it.
 */

 
import SwiftSDAIcore

extension AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF {
//MARK: -ENTITY DEFINITION in EXPRESS
/*

  ENTITY tolerance_zone_definition
    SUPERTYPE OF ( 
        ONEOF ( 
            projected_zone_definition, 
            non_uniform_zone_definition, 
            runout_zone_definition ) );
      zone        : tolerance_zone;
      boundaries  : SET [0 : ?] OF shape_aspect;
  END_ENTITY; -- tolerance_zone_definition (line:32777 file:ap242ed2_mim_lf_v1.101.TY.exp)

*/


//MARK: - ALL DEFINED ATTRIBUTES
/*
  ENTITY(SELF)	tolerance_zone_definition
    ATTR:  zone,	TYPE: tolerance_zone -- EXPLICIT

    ATTR:  boundaries,	TYPE: SET [0 : ?] OF shape_aspect -- EXPLICIT


  SUB- ENTITY(2)	runout_zone_definition
    ATTR:  orientation,	TYPE: runout_zone_orientation -- EXPLICIT


  SUB- ENTITY(3)	projected_zone_definition_with_offset
    ATTR:  offset,	TYPE: length_measure_with_unit -- EXPLICIT


  SUB- ENTITY(4)	projected_zone_definition
    ATTR:  projection_end,	TYPE: shape_aspect -- EXPLICIT

    ATTR:  projected_length,	TYPE: length_measure_with_unit -- EXPLICIT


  SUB- ENTITY(5)	non_uniform_zone_definition
    (no local attributes)

*/


//MARK: - Partial Entity
  public final class _tolerance_zone_definition : SDAI.PartialEntity {
    public override class var entityReferenceType: SDAI.EntityReference.Type {
      eTOLERANCE_ZONE_DEFINITION.self
    }

    //ATTRIBUTES
    /// EXPLICIT ATTRIBUTE 
    public internal(set) var _zone: eTOLERANCE_ZONE // PLAIN EXPLICIT ATTRIBUTE

    /// EXPLICIT ATTRIBUTE 
    public internal(set) var _boundaries: SDAI.SET<eSHAPE_ASPECT>/*[0:nil]*/  // PLAIN EXPLICIT ATTRIBUTE

    public override var typeMembers: Set<SDAI.STRING> {
      var members = Set<SDAI.STRING>()
      members.insert(SDAI.STRING(Self.typeName))
      return members
    }


    //VALUE COMPARISON SUPPORT
    public override func hashAsValue(into hasher: inout Hasher, visited complexEntities: inout Set<SDAI.ComplexEntity>) {
      super.hashAsValue(into: &hasher, visited: &complexEntities)
      self._zone.value.hashAsValue(into: &hasher, visited: &complexEntities)
      self._boundaries.value.hashAsValue(into: &hasher, visited: &complexEntities)
    }

    public override func isValueEqual(to rhs: SDAI.PartialEntity, visited comppairs: inout Set<SDAI.ComplexPair>) -> Bool {
      guard let rhs = rhs as? Self else { return false }
      if !super.isValueEqual(to: rhs, visited: &comppairs) { return false }
      if let comp = self._zone.value.isValueEqualOptionally(to: rhs._zone.value, visited: &comppairs)	{
        if !comp { return false }
      }
      else { return false }
      if let comp = self._boundaries.value.isValueEqualOptionally(to: rhs._boundaries.value, visited: &comppairs)	{
        if !comp { return false }
      }
      else { return false }
      return true
    }

    public override func isValueEqualOptionally(to rhs: SDAI.PartialEntity, visited comppairs: inout Set<SDAI.ComplexPair>) -> Bool? {
      guard let rhs = rhs as? Self else { return false }
      var result: Bool? = true
      if let comp = super.isValueEqualOptionally(to: rhs, visited: &comppairs) {
        if !comp { return false }
      }
      else { result = nil }
      if let comp = self._zone.value.isValueEqualOptionally(to: rhs._zone.value, visited: &comppairs) {
        if !comp { return false }
      }
      else { result = nil }
      if let comp = self._boundaries.value.isValueEqualOptionally(to: rhs._boundaries.value, visited: &comppairs) {
        if !comp { return false }
      }
      else { result = nil }
      return result
    }


    //EXPRESS IMPLICIT PARTIAL ENTITY CONSTRUCTOR
    public init(ZONE: eTOLERANCE_ZONE, BOUNDARIES: SDAI.SET<eSHAPE_ASPECT>/*[0:nil]*/ ) {
      self._zone = ZONE
      self._boundaries = BOUNDARIES
      super.init(asAbstructSuperclass:())

    }

    //p21 PARTIAL ENTITY CONSTRUCTOR
    public required convenience init?(parameters: [P21Decode.ExchangeStructure.Parameter], exchangeStructure: P21Decode.ExchangeStructure) {
      let numParams = 2
      guard parameters.count == numParams
      else { exchangeStructure.error = "number of p21 parameters(\(parameters.count)) are different from expected(\(numParams)) for entity(\(Self.entityName)) constructor"; return nil }

      guard case .success(let p0) = exchangeStructure.recoverRequiredParameter(as: eTOLERANCE_ZONE.self, from: parameters[0])
      else { exchangeStructure.add(errorContext: "while recovering parameter #0 for entity(\(Self.entityName)) constructor"); return nil }

      guard case .success(let p1) = exchangeStructure.recoverRequiredParameter(as: SDAI.SET<eSHAPE_ASPECT>.self, from: parameters[1])
      else { exchangeStructure.add(errorContext: "while recovering parameter #1 for entity(\(Self.entityName)) constructor"); return nil }

      self.init( ZONE: p0, BOUNDARIES: p1 )
    }
  }


//MARK: - Entity Reference

/** ENTITY reference
- EXPRESS:
```express
  ENTITY tolerance_zone_definition
    SUPERTYPE OF ( 
        ONEOF ( 
            projected_zone_definition, 
            non_uniform_zone_definition, 
            runout_zone_definition ) );
      zone        : tolerance_zone;
      boundaries  : SET [0 : ?] OF shape_aspect;
  END_ENTITY; -- tolerance_zone_definition (line:32777 file:ap242ed2_mim_lf_v1.101.TY.exp)

```
*/
  public final class eTOLERANCE_ZONE_DEFINITION : SDAI.EntityReference {

    //MARK: PARTIAL ENTITY
    public override class var partialEntityType: SDAI.PartialEntity.Type {
      _tolerance_zone_definition.self
    }
    public let partialEntity: _tolerance_zone_definition

    //MARK: SUPERTYPES
    public var super_eTOLERANCE_ZONE_DEFINITION: eTOLERANCE_ZONE_DEFINITION { return self } 	// [1]

    //MARK: SUBTYPES
    public var sub_eRUNOUT_ZONE_DEFINITION: eRUNOUT_ZONE_DEFINITION? {	// [2]
      return self.complexEntity.entityReference(eRUNOUT_ZONE_DEFINITION.self)
    }

    public var sub_ePROJECTED_ZONE_DEFINITION_WITH_OFFSET: ePROJECTED_ZONE_DEFINITION_WITH_OFFSET? {	// [3]
      return self.complexEntity.entityReference(ePROJECTED_ZONE_DEFINITION_WITH_OFFSET.self)
    }

    public var sub_ePROJECTED_ZONE_DEFINITION: ePROJECTED_ZONE_DEFINITION? {	// [4]
      return self.complexEntity.entityReference(ePROJECTED_ZONE_DEFINITION.self)
    }

    public var sub_eNON_UNIFORM_ZONE_DEFINITION: eNON_UNIFORM_ZONE_DEFINITION? {	// [5]
      return self.complexEntity.entityReference(eNON_UNIFORM_ZONE_DEFINITION.self)
    }


    //MARK: ATTRIBUTES
    /// __EXPLICIT__ attribute
    /// - origin: SUB( ``ePROJECTED_ZONE_DEFINITION`` )
    public var PROJECTION_END: eSHAPE_ASPECT?  {
      get {
        return sub_ePROJECTED_ZONE_DEFINITION?.partialEntity._projection_end
      }
      set(newValue) {
        guard let partial = sub_ePROJECTED_ZONE_DEFINITION?.super_ePROJECTED_ZONE_DEFINITION.partialEntity
          else { return }
        partial._projection_end = SDAI.UNWRAP(newValue)
      }
    }

    /// __EXPLICIT__ attribute
    /// - origin: SELF( ``eTOLERANCE_ZONE_DEFINITION`` )
    public var ZONE: eTOLERANCE_ZONE {
      get {
        return SDAI.UNWRAP( self.partialEntity._zone )
      }
      set(newValue) {
        let partial = self.partialEntity
        partial._zone = SDAI.UNWRAP(newValue)
      }
    }

    /// __EXPLICIT__ attribute
    /// - origin: SELF( ``eTOLERANCE_ZONE_DEFINITION`` )
    public var BOUNDARIES: SDAI.SET<eSHAPE_ASPECT>/*[0:nil]*/  {
      get {
        return SDAI.UNWRAP( self.partialEntity._boundaries )
      }
      set(newValue) {
        let partial = self.partialEntity
        partial._boundaries = SDAI.UNWRAP(newValue)
      }
    }

    /// __EXPLICIT__ attribute
    /// - origin: SUB( ``eRUNOUT_ZONE_DEFINITION`` )
    public var ORIENTATION: eRUNOUT_ZONE_ORIENTATION?  {
      get {
        return sub_eRUNOUT_ZONE_DEFINITION?.partialEntity._orientation
      }
      set(newValue) {
        guard let partial = sub_eRUNOUT_ZONE_DEFINITION?.super_eRUNOUT_ZONE_DEFINITION.partialEntity
          else { return }
        partial._orientation = SDAI.UNWRAP(newValue)
      }
    }

    /// __EXPLICIT__ attribute
    /// - origin: SUB( ``ePROJECTED_ZONE_DEFINITION`` )
    public var PROJECTED_LENGTH: eLENGTH_MEASURE_WITH_UNIT?  {
      get {
        return sub_ePROJECTED_ZONE_DEFINITION?.partialEntity._projected_length
      }
      set(newValue) {
        guard let partial = sub_ePROJECTED_ZONE_DEFINITION?.super_ePROJECTED_ZONE_DEFINITION.partialEntity
          else { return }
        partial._projected_length = SDAI.UNWRAP(newValue)
      }
    }

    /// __EXPLICIT__ attribute
    /// - origin: SUB( ``ePROJECTED_ZONE_DEFINITION_WITH_OFFSET`` )
    public var OFFSET: eLENGTH_MEASURE_WITH_UNIT?  {
      get {
        return sub_ePROJECTED_ZONE_DEFINITION_WITH_OFFSET?.partialEntity._offset
      }
      set(newValue) {
        guard let partial = sub_ePROJECTED_ZONE_DEFINITION_WITH_OFFSET?.super_ePROJECTED_ZONE_DEFINITION_WITH_OFFSET
          .partialEntity else { return }
        partial._offset = SDAI.UNWRAP(newValue)
      }
    }


    //MARK: INITIALIZERS
    public convenience init?(_ entityRef: SDAI.EntityReference?) {
      let complex = entityRef?.complexEntity
      self.init(complex: complex)
    }

    public required init?(complex complexEntity: SDAI.ComplexEntity?) {
      guard let partial = complexEntity?.partialEntityInstance(_tolerance_zone_definition.self) else { return nil }
      self.partialEntity = partial

      super.init(complex: complexEntity)
    }

    public required convenience init?<G: SDAIGenericType>(fromGeneric generic: G?) {
      guard let entityRef = generic?.entityReference else { return nil }
      self.init(complex: entityRef.complexEntity)
    }

    public convenience init?<S: SDAISelectType>(_ select: S?) { self.init(possiblyFrom: select) }
    public convenience init?(_ complex: SDAI.ComplexEntity?) { self.init(complex: complex) }

    //SIMPLE ENTITY REFERENCE
    public convenience init?(_ partial:_tolerance_zone_definition) {
      let complex = SDAI.ComplexEntity(entities:[partial])
      self.init(complex: complex)
    }


    //MARK: DICTIONARY DEFINITION
    public class override var entityDefinition: SDAIDictionarySchema.EntityDefinition { _entityDefinition }
    private static let _entityDefinition: SDAIDictionarySchema.EntityDefinition = createEntityDefinition()

    private static func createEntityDefinition() -> SDAIDictionarySchema.EntityDefinition {
      let entityDef = SDAIDictionarySchema.EntityDefinition(name: "TOLERANCE_ZONE_DEFINITION", type: self, explicitAttributeCount: 2)

      //MARK: SUPERTYPE REGISTRATIONS
      entityDef.add(supertype: eTOLERANCE_ZONE_DEFINITION.self)

      //MARK: ATTRIBUTE REGISTRATIONS
      entityDef.addAttribute(name: "PROJECTION_END", keyPath: \eTOLERANCE_ZONE_DEFINITION.PROJECTION_END, 
        kind: .explicit, source: .subEntity, mayYieldEntityReference: true)
      entityDef.addAttribute(name: "ZONE", keyPath: \eTOLERANCE_ZONE_DEFINITION.ZONE, 
        kind: .explicit, source: .thisEntity, mayYieldEntityReference: true)
      entityDef.addAttribute(name: "BOUNDARIES", keyPath: \eTOLERANCE_ZONE_DEFINITION.BOUNDARIES, 
        kind: .explicit, source: .thisEntity, mayYieldEntityReference: true)
      entityDef.addAttribute(name: "ORIENTATION", keyPath: \eTOLERANCE_ZONE_DEFINITION.ORIENTATION, 
        kind: .explicit, source: .subEntity, mayYieldEntityReference: true)
      entityDef.addAttribute(name: "PROJECTED_LENGTH", keyPath: \eTOLERANCE_ZONE_DEFINITION.PROJECTED_LENGTH, 
        kind: .explicit, source: .subEntity, mayYieldEntityReference: true)
      entityDef.addAttribute(name: "OFFSET", keyPath: \eTOLERANCE_ZONE_DEFINITION.OFFSET, 
        kind: .explicit, source: .subEntity, mayYieldEntityReference: true)

      return entityDef
    }

  }
}
