/// <summary>
        /// Modifiy the terrain for the junction
        /// </summary>
        /// <param name="sections">The number of sections</param>
        /// <param name="tm">The terrain modifier</param>
        private void CreateJunctionsTerrain(int sections, TerrainModifier tm)
        {
            float couveSize = 2.5f;

            _roadNetworkNode.OrderRoads();

            IMaterialFrequency materialFrequency = _roadNetworkNode.GetComponent <OverridableMaterialFrequency>();

            if (materialFrequency == null)
            {
                materialFrequency = RoadConstructorHelper.MaterialFrequencySet;
            }

            RoadNetworkNode  roadA, roadB, roadC;
            RoadCrossSection rA, rB, rC;

            RoadUnionHelper.DefineCrossSectionOffSet(couveSize, 0, _roadNetworkNode, out roadA, out rA);
            RoadUnionHelper.DefineCrossSectionOffSet(couveSize, 1, _roadNetworkNode, out roadB, out rB);
            RoadUnionHelper.DefineCrossSectionOffSet(couveSize, 2, _roadNetworkNode, out roadC, out rC);

            int connectionSet = IntersectionManager.Instance.AddLinkedIntersecions(rA, rB, rC);

            RoadNetworkNode roadNetworkNode = _roadNetworkNode;
            string          materialName    = RoadConstructorHelper.GetMainMaterial(materialFrequency);

            DrawDetailsJunctionRoad drs = new DrawDetailsJunctionRoad(connectionSet, roadNetworkNode, materialName);

            drs.ModifyTerrain(_roadNetworkNode.BuildData, tm);

            RoadConstructorHelper.ApplyLeadingStrights(_roadNetworkNode, tm, 0);
            RoadConstructorHelper.ApplyLeadingStrights(_roadNetworkNode, tm, 1);
            RoadConstructorHelper.ApplyLeadingStrights(_roadNetworkNode, tm, 2);
        }
        /// <summary>
        /// Create the road object
        /// </summary>
        /// <param name="roadObject">The base object to add the road to</param>
        /// <param name="sections">The number of sections to use for this road</param>
        private void CreateFiveRoads(RoadBuilder roadObject, int sections)
        {
            float couveSize = 2.5f;

            _roadNetworkNode.OrderRoads();

            IMaterialFrequency materialFrequency = _roadNetworkNode.GetComponent <OverridableMaterialFrequency>();

            if (materialFrequency == null)
            {
                materialFrequency = RoadConstructorHelper.MaterialFrequencySet;
            }

            RoadNetworkNode  roadA, roadB, roadC, roadD, roadE;
            RoadCrossSection rA, rB, rC, rD, rE;

            RoadUnionHelper.DefineCrossSectionOffSet(couveSize, 0, _roadNetworkNode, out roadA, out rA);
            RoadUnionHelper.DefineCrossSectionOffSet(couveSize, 1, _roadNetworkNode, out roadB, out rB);
            RoadUnionHelper.DefineCrossSectionOffSet(couveSize, 2, _roadNetworkNode, out roadC, out rC);
            RoadUnionHelper.DefineCrossSectionOffSet(couveSize, 3, _roadNetworkNode, out roadD, out rD);
            RoadUnionHelper.DefineCrossSectionOffSet(couveSize, 4, _roadNetworkNode, out roadE, out rE);

            int connectionSet = IntersectionManager.Instance.AddLinkedIntersecions(rA, rB, rC, rD, rE);

            _meshSection.AddFiveRoad(connectionSet, _roadNetworkNode, RoadConstructorHelper.GetMainMaterial(materialFrequency));
            _meshSection.UpdateEndPoints(roadObject);

            StreetManager.Instance.AddStreetEnd(_roadNetworkNode.name, _roadNetworkNode.Details.Roads[0].name, RoadConstructorHelper.CrossSection(_roadNetworkNode.Details.Roads[0]), RoadConstructorHelper.Materials(roadA), rA);
            StreetManager.Instance.AddStreetEnd(_roadNetworkNode.name, _roadNetworkNode.Details.Roads[1].name, RoadConstructorHelper.CrossSection(_roadNetworkNode.Details.Roads[1]), RoadConstructorHelper.Materials(roadB), rB);
            StreetManager.Instance.AddStreetEnd(_roadNetworkNode.name, _roadNetworkNode.Details.Roads[2].name, RoadConstructorHelper.CrossSection(_roadNetworkNode.Details.Roads[2]), RoadConstructorHelper.Materials(roadC), rC);
            StreetManager.Instance.AddStreetEnd(_roadNetworkNode.name, _roadNetworkNode.Details.Roads[3].name, RoadConstructorHelper.CrossSection(_roadNetworkNode.Details.Roads[3]), RoadConstructorHelper.Materials(roadD), rD);
            StreetManager.Instance.AddStreetEnd(_roadNetworkNode.name, _roadNetworkNode.Details.Roads[4].name, RoadConstructorHelper.CrossSection(_roadNetworkNode.Details.Roads[4]), RoadConstructorHelper.Materials(roadE), rE);

            List <Guid>      list = IntersectionManager.Instance[connectionSet];
            RoadCrossSection rscA = IntersectionManager.Instance[list[0]];
            RoadCrossSection rscB = IntersectionManager.Instance[list[1]];
            RoadCrossSection rscC = IntersectionManager.Instance[list[2]];
            RoadCrossSection rscD = IntersectionManager.Instance[list[3]];
            RoadCrossSection rscE = IntersectionManager.Instance[list[4]];

            StreetManager.Instance.ReplaceRoadWithId(_roadNetworkNode.name, _roadNetworkNode.Details.Roads[0].name,
                                                     RoadConstructorHelper.CrossSection(_roadNetworkNode.Details.Roads[0]), rscA);

            StreetManager.Instance.ReplaceRoadWithId(_roadNetworkNode.name, _roadNetworkNode.Details.Roads[1].name,
                                                     RoadConstructorHelper.CrossSection(_roadNetworkNode.Details.Roads[1]), rscB);

            StreetManager.Instance.ReplaceRoadWithId(_roadNetworkNode.name, _roadNetworkNode.Details.Roads[2].name,
                                                     RoadConstructorHelper.CrossSection(_roadNetworkNode.Details.Roads[2]), rscC);

            StreetManager.Instance.ReplaceRoadWithId(_roadNetworkNode.name, _roadNetworkNode.Details.Roads[3].name,
                                                     RoadConstructorHelper.CrossSection(_roadNetworkNode.Details.Roads[3]), rscD);

            StreetManager.Instance.ReplaceRoadWithId(_roadNetworkNode.name, _roadNetworkNode.Details.Roads[4].name,
                                                     RoadConstructorHelper.CrossSection(_roadNetworkNode.Details.Roads[4]), rscE);
        }
        /// <summary>
        /// Create the steet layout
        /// </summary>
        public void CreateStreetLayout(int subDivide)
        {
            if (_startRoadId == null)
            {
                return;
            }

            if (_endRoadId == null)
            {
                return;
            }

            RoadCrossSection rA = _startRoadId;
            ICrossSection    crossSectionStart = _startCrossSection;

            if (crossSectionStart == null)
            {
                crossSectionStart = RoadConstructorHelper.CrossSectionDetails;
            }

            RoadCrossSection rB = _endRoadId;
            ICrossSection    crossSectionEnd = _endCrossSection;

            if (crossSectionEnd == null)
            {
                crossSectionEnd = RoadConstructorHelper.CrossSectionDetails;
            }

            IMaterialFrequency materialFrequency = _materialFrequency;

            if (materialFrequency == null)
            {
                materialFrequency = RoadConstructorHelper.MaterialFrequencySet;
            }

            Vector3 len      = rA.Middle - rB.Middle;
            float   mag      = len.magnitude;
            int     sections = (int)(mag / crossSectionStart.RoadWidthValue);

            RoadCrossSection[] array         = new RoadCrossSection[sections + 1];
            string[]           materialNames = new string[sections + 1];

            float   an    = rB.Angle;
            Vector3 start = rB.Middle;

            if (sections < 2)
            {
                Vector3 another = rB.Middle;
                another = rA.Middle;
                RoadCrossSection rn = new RoadCrossSection(another, an, crossSectionStart, materialFrequency);
                _meshSection.AddBasicRoad(IntersectionManager.Instance.AddLinkedIntersecions(rB, rn), RoadConstructorHelper.GetMainMaterial(materialFrequency), 0); // TODO SubDivide
                return;
            }

            Vector3 gap  = len / sections;
            float   mag2 = gap.magnitude;

            for (int i = 0; i < sections + 1; i++)
            {
                ICrossSection    crossSection = CrossSection.Lerp(crossSectionEnd, crossSectionStart, (mag2 * i) / mag);
                RoadCrossSection rn           = new RoadCrossSection(start, an, crossSection, materialFrequency);
                array[i] = rn;
                start   += gap;
            }

            RoadConstructorHelper.SetMaterialsArray(materialNames, materialFrequency);
            for (int i = 0; i < sections; i++)
            {
                _meshSection.AddBasicRoad(IntersectionManager.Instance.AddLinkedIntersecions(array[i], array[i + 1]), materialNames[i], subDivide);
            }
        }
        /// <summary>
        /// Create the terrain for the road
        /// </summary>
        /// <param name="sections">The number of sections</param>
        /// <param name="tm">The terrain modifier</param>
        private void CreateSixRoadsTerrain(int sections, TerrainModifier tm)
        {
            float couveSize = 2.5f;

            IMaterialFrequency materialFrequency = _roadNetworkNode.GetComponent <OverridableMaterialFrequency>();

            if (materialFrequency == null)
            {
                materialFrequency = RoadConstructorHelper.MaterialFrequencySet;
            }

            RoadNetworkNode  roadA, roadB, roadC, roadD, roadE, roadF;
            RoadCrossSection rA, rB, rC, rD, rE, rF;

            RoadUnionHelper.DefineCrossSectionOffSet(couveSize, 0, _roadNetworkNode, out roadA, out rA);
            RoadUnionHelper.DefineCrossSectionOffSet(couveSize, 1, _roadNetworkNode, out roadB, out rB);
            RoadUnionHelper.DefineCrossSectionOffSet(couveSize, 2, _roadNetworkNode, out roadC, out rC);
            RoadUnionHelper.DefineCrossSectionOffSet(couveSize, 3, _roadNetworkNode, out roadD, out rD);
            RoadUnionHelper.DefineCrossSectionOffSet(couveSize, 4, _roadNetworkNode, out roadE, out rE);
            RoadUnionHelper.DefineCrossSectionOffSet(couveSize, 5, _roadNetworkNode, out roadF, out rF);

            int connectionSet = IntersectionManager.Instance.AddLinkedIntersecions(rA, rB, rC, rD, rE, rF);

            DrawDetailsFiveRoad drs = new DrawDetailsFiveRoad(connectionSet, _roadNetworkNode, RoadConstructorHelper.GetMainMaterial(materialFrequency));

            drs.ModifyTerrain(_roadNetworkNode.BuildData, tm);

            RoadConstructorHelper.ApplyLeadingStrights(_roadNetworkNode, tm, 0);
            RoadConstructorHelper.ApplyLeadingStrights(_roadNetworkNode, tm, 1);
            RoadConstructorHelper.ApplyLeadingStrights(_roadNetworkNode, tm, 2);
            RoadConstructorHelper.ApplyLeadingStrights(_roadNetworkNode, tm, 3);
            RoadConstructorHelper.ApplyLeadingStrights(_roadNetworkNode, tm, 4);
            RoadConstructorHelper.ApplyLeadingStrights(_roadNetworkNode, tm, 5);
        }
        /// <summary>
        /// Create the road object
        /// </summary>
        /// <param name="roadObject">The base object to add the road to</param>
        /// <param name="sections">The number of sections to use for this road</param>
        private void CreateCorner(RoadBuilder roadObject, int sections)
        {
            // find the point where the two roads meet
            Vector3 pos = _roadNetworkNode.gameObject.transform.position;

            // create a corne at this postion
            Vector3 newpos = pos;

            float roadAngleA = RoadUnionHelper.AngleClamp(RoadUnionHelper.GetAngleOfRoadClampped(_roadNetworkNode, 0) - (Mathf.PI / 2));
            float roadAngleB = RoadUnionHelper.AngleClamp(RoadUnionHelper.GetAngleOfRoadClampped(_roadNetworkNode, 1) + (Mathf.PI / 2));
            float roadAngleDifference = roadAngleB - roadAngleA;
            float couveSize = 1.85f;
            float x, z;

            float road_A_length = GetLengthOfRoad(0);
            float road_B_length = GetLengthOfRoad(1);

            float minLength = Mathf.Min(road_A_length, road_B_length);

            float offSetDownRoad = RoadConstructorHelper.CrossSectionDetails.RoadWidthValue * couveSize;

            if (offSetDownRoad > minLength / 2)
            {
                offSetDownRoad = minLength / 2;
            }

            RoadNetworkNode oppositeEnd = _roadNetworkNode.Details.Roads[1].GetComponent <RoadNetworkNode>();
            Vector3         roadPointA  = oppositeEnd.GetOffSetDownRoad(pos, (offSetDownRoad));
            Vector3         outA;
            bool            offSetPos   = _roadNetworkNode.GetInnerCorner(0, 1, (offSetDownRoad), out outA);
            Vector3         CornerPoint = outA;

            newpos = CornerPoint;

            // get the gap form point to point
            Vector3 gap = CornerPoint - roadPointA;

            couveSize = offSetPos ? gap.magnitude : 0;
            couveSize = offSetPos ? gap.magnitude : 0;
            bool backward = false;

            Radian currentAngle = new Radian(roadAngleA - (float)(Math.PI / 2));

            roadAngleDifference = MathsHelper.ClampAngle(roadAngleDifference);
            if (roadAngleDifference > Mathf.PI)
            {
                roadAngleDifference = (Mathf.PI * 2) - roadAngleDifference;
                currentAngle        = new Radian(roadAngleB + (float)(Math.PI / 2));
                backward            = true;
            }

            float diff = roadAngleDifference;

            x = Mathf.Sin(currentAngle.Value) * (couveSize);
            z = Mathf.Cos(currentAngle.Value) * (couveSize);

            newpos.x -= x;
            newpos.z += z;

            ICrossSection      crossSectionMiddle = RoadConstructorHelper.CrossSection(_roadNetworkNode);
            IMaterialFrequency materialFrequency  = _roadNetworkNode.gameObject.GetComponent <IMaterialFrequency>();

            if (materialFrequency == null)
            {
                materialFrequency = RoadConstructorHelper.MaterialFrequencySet;
            }

            RoadCrossSection rA    = new RoadCrossSection(newpos, currentAngle.Value, crossSectionMiddle, materialFrequency);
            RoadCrossSection Start = rA;

            float angleStep = Mathf.Abs(diff / sections);

            for (int i = 0; i < sections; i++)
            {
                newpos              = CornerPoint;
                currentAngle.Value += angleStep;

                x         = Mathf.Sin(currentAngle.Value) * (couveSize);
                z         = Mathf.Cos(currentAngle.Value) * (couveSize);
                newpos.x -= x;
                newpos.z += z;

                RoadCrossSection rB = new RoadCrossSection(newpos, currentAngle.Value, crossSectionMiddle, materialFrequency);
                // TODO Sub divide corners - need to update before the add basic road!
                _meshSection.AddBasicRoad(IntersectionManager.Instance.AddLinkedIntersecions(rA, rB), RoadConstructorHelper.GetMainMaterial(materialFrequency), 0);
                rA = rB;
            }

            RoadCrossSection End = rA;

            if (backward)
            {
                StreetManager.Instance.AddStreetEnd(_roadNetworkNode.name, _roadNetworkNode.Details.Roads[0].name, crossSectionMiddle, materialFrequency, End);
                StreetManager.Instance.AddStreetEnd(_roadNetworkNode.name, _roadNetworkNode.Details.Roads[1].name, crossSectionMiddle, materialFrequency, Start);
            }
            else
            {
                StreetManager.Instance.AddStreetEnd(_roadNetworkNode.name, _roadNetworkNode.Details.Roads[1].name, crossSectionMiddle, materialFrequency, End);
                StreetManager.Instance.AddStreetEnd(_roadNetworkNode.name, _roadNetworkNode.Details.Roads[0].name, crossSectionMiddle, materialFrequency, Start);
            }
        }