// ------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool Xbim.CodeGeneration 
//  
//     Changes to this file may cause incorrect behaviour and will be lost if
//     the code is regenerated.
// </auto-generated>
// ------------------------------------------------------------------------------

using Xbim.Ifc4.Interfaces;
using System.Collections.Generic;
using System.Linq;
using Xbim.Common;

//## Custom using statements
using Xbim.Ifc4x3.GeometryResource;
using Xbim.Ifc4x3.RepresentationResource;
using Xbim.Ifc4x3.MeasureResource;
//##

// ReSharper disable once CheckNamespace
namespace Xbim.Ifc4x3.Kernel
{
	public partial class @IfcProject : IIfcProject
	{
	//## Custom code
        public IEnumerable<IIfcSite> Sites
        {
            get
            {
                return IsDecomposedBy.SelectMany(rel => Enumerable.OfType<IIfcSite>(rel.RelatedObjects));
            }
        }

        public IEnumerable<IIfcSpatialStructureElement> SpatialStructuralElements
        {
            get
            {
                return IsDecomposedBy.SelectMany(rel => rel.RelatedObjects.OfType<IIfcSpatialStructureElement>());
            }
        }

        /// <summary>
        /// Returns all buildings at the highest level of spatial structural decomposition (i.e. root buildings)
        /// </summary>
        public IEnumerable<IIfcBuilding> Buildings
        {
            get
            {
                foreach (var rel in IsDecomposedBy)
                {
                    foreach (var definition in rel.RelatedObjects)
                    {
                        var site = definition as IIfcSite;
                        if (site != null)
                            foreach (var building in site.Buildings)
                                yield return building;
                        if (definition is IIfcBuilding)
                            yield return (definition as IIfcBuilding);
                    }
                }
            }
        }

        public IfcGeometricRepresentationContext ModelContext
        {
            get
            {
                return
                    RepresentationContexts.
                        FirstOrDefault<IfcGeometricRepresentationContext>(r => r.ContextType == "Model");
            }

        }

        /// <summary>
        ///   Sets up the default units as SI
        ///   Creates the GeometricRepresentationContext for a Model view, required by Ifc compliance
        /// </summary>
        public void Initialize(ProjectUnits units)
        {
            var model = Model;
            if (units == ProjectUnits.SIUnitsUK)
            {
                var ua = model.Instances.New<IfcUnitAssignment>();
                ua.Units.Add(model.Instances.New<IfcSIUnit>(s =>
                {
                    s.UnitType = MeasureResource.IfcUnitEnum.LENGTHUNIT;
                    s.Name = MeasureResource.IfcSIUnitName.METRE;
                    s.Prefix = MeasureResource.IfcSIPrefix.MILLI;
                }));
                ua.Units.Add(model.Instances.New<IfcSIUnit>(s =>
                {
                    s.UnitType = MeasureResource.IfcUnitEnum.AREAUNIT;
                    s.Name = MeasureResource.IfcSIUnitName.SQUARE_METRE;
                }));
                ua.Units.Add(model.Instances.New<IfcSIUnit>(s =>
                {
                    s.UnitType = MeasureResource.IfcUnitEnum.VOLUMEUNIT;
                    s.Name = MeasureResource.IfcSIUnitName.CUBIC_METRE;
                }));
                ua.Units.Add(model.Instances.New<IfcSIUnit>(s =>
                {
                    s.UnitType = MeasureResource.IfcUnitEnum.SOLIDANGLEUNIT;
                    s.Name = MeasureResource.IfcSIUnitName.STERADIAN;
                }));
                ua.Units.Add(model.Instances.New<IfcSIUnit>(s =>
                {
                    s.UnitType = MeasureResource.IfcUnitEnum.PLANEANGLEUNIT;
                    s.Name = MeasureResource.IfcSIUnitName.RADIAN;
                }));
                ua.Units.Add(model.Instances.New<IfcSIUnit>(s =>
                {
                    s.UnitType = MeasureResource.IfcUnitEnum.MASSUNIT;
                    s.Name = MeasureResource.IfcSIUnitName.GRAM;
                }));
                ua.Units.Add(model.Instances.New<IfcSIUnit>(s =>
                {
                    s.UnitType = MeasureResource.IfcUnitEnum.TIMEUNIT;
                    s.Name = MeasureResource.IfcSIUnitName.SECOND;
                }));
                ua.Units.Add(model.Instances.New<IfcSIUnit>(s =>
                {
                    s.UnitType =
                        MeasureResource.IfcUnitEnum.THERMODYNAMICTEMPERATUREUNIT;
                    s.Name = MeasureResource.IfcSIUnitName.DEGREE_CELSIUS;
                }));
                ua.Units.Add(model.Instances.New<IfcSIUnit>(s =>
                {
                    s.UnitType = MeasureResource.IfcUnitEnum.LUMINOUSINTENSITYUNIT;
                    s.Name = MeasureResource.IfcSIUnitName.LUMEN;
                }));
                UnitsInContext = ua;
            }
            //Create the Mandatory Model View
            if (ModelContext == null)
            {
                var origin = model.Instances.New<IfcCartesianPoint>(p => p.SetXYZ(0, 0, 0));
                var axis3D = model.Instances.New<IfcAxis2Placement3D>(a => a.Location = origin);
                var gc = model.Instances.New<IfcGeometricRepresentationContext>(c =>
                {
                    c.
                        ContextType
                        =
                        "Model";
                    c.
                        ContextIdentifier
                        =
                        "Building Model";
                    c.
                        CoordinateSpaceDimension
                        = 3;
                    c.Precision
                        =
                        0.00001;
                    c.
                        WorldCoordinateSystem
                        = axis3D;
                }
                    );
                RepresentationContexts.Add(gc);

                var origin2D = model.Instances.New<IfcCartesianPoint>(p => p.SetXY(0, 0));
                var axis2D = model.Instances.New<IfcAxis2Placement2D>(a => a.Location = origin2D);
                var pc = model.Instances.New<IfcGeometricRepresentationContext>(c =>
                {
                    c.
                        ContextType
                        =
                        "Plan";
                    c.
                        ContextIdentifier
                        =
                        "Building Plan View";
                    c.
                        CoordinateSpaceDimension
                        = 2;
                    c.Precision
                        =
                        0.00001;
                    c.
                        WorldCoordinateSystem
                        = axis2D;
                }
                    );
                RepresentationContexts.Add(pc);

            }
        }
        //##
	}
}