public void addNewPavement(string pavementID, Pavement.pavementSide side, float size)
        {
            int highwayIndex = getHighwayIndex(pavementID);
            if (side == Pavement.pavementSide.left)
            {
                highwayList[highwayIndex].hasLeftSidewalk = true;
                highwayList[highwayIndex].leftSidewalkSize = size;
            }
            else
            {
                highwayList[highwayIndex].hasRightSideWalk = true;
                highwayList[highwayIndex].rightSidewalkSize = size;
            }

            Pavement newPavement = new Pavement(highwayList[getHighwayIndex(pavementID)], terrain, side);
            pavementList.Add(newPavement);
            newPavement.renderPavement();
        }
        public void deletePavement(string pavementID, Pavement.pavementSide side)
        {
            int highwayIndex = getHighwayIndex(pavementID);
            if (side == Pavement.pavementSide.left)
            {
                highwayList[highwayIndex].hasLeftSidewalk = false;
                highwayList[highwayIndex].leftSidewalkSize = 0;
            }
            else
            {
                highwayList[highwayIndex].hasRightSideWalk = false;
                highwayList[highwayIndex].rightSidewalkSize = 0;
            }

            int pavementIndex = pavementList.FindIndex(item => item.Pavementid == pavementID &&
                                               item.side == side);

            UnityEngine.Object.Destroy(pavementList[pavementIndex].PavementObj);
            pavementList.RemoveAt(pavementIndex);
        }
        public void correctPavement(string pavementID, Pavement.pavementSide side)
        {
            List<IntersectionNode> nodes = intersections.FindAll(item => item.wayIds.Contains(pavementID));

            for (int i = 0; i < nodes.Count; i++)
                correctPavementIntersection(nodes[i], pavementID, side);
        }
        private void correctPavementIntersection(IntersectionNode intersection,string wayID, Pavement.pavementSide side)
        {
            Highway highwayOrg, highwayFound;
            Vector3 intersectionPoint;
            Vector2 calculatedIntersection = new Vector2();

            int intersectCondition = -1; //0:start-left, 1:start-right, 2:end-left,3:end-right
            int intersectCondition2 = -1; // 0: start , 1 : left;

            //1. Find the point that given highway intersect with the other highway from the given side
            highwayOrg = highwayList.Find(item => item.id == wayID);
            highwayFound = null;
            int indexOrg = intersection.wayIds.FindIndex(item => item == wayID);
            if (intersection.intersectionTypes[indexOrg] == IntersectionType.front)
            {

                if (side == Pavement.pavementSide.left)
                {
                    intersectionPoint = highwayOrg.leftSideVertexes[0]; //start-left
                    intersectCondition = 0;
                }
                else
                {
                    intersectionPoint = highwayOrg.rightSideVertexes[0]; //start-right
                    intersectCondition = 1;
                }
            }
            else
            {

                if (side == Pavement.pavementSide.left)
                {
                    intersectionPoint = highwayOrg.leftSideVertexes[highwayOrg.leftSideVertexes.Count - 1]; //end - left
                    intersectCondition = 2;
                }
                else
                {
                    intersectionPoint = highwayOrg.rightSideVertexes[highwayOrg.rightSideVertexes.Count - 1]; // end - right
                    intersectCondition = 3;
                }
            }

            //2. For the intersection point compare all other highways in the intersection to Detect the highway we are looking for

            for(int i = 0 ; i < intersection.wayIds.Count ;i++)
            {
                if (intersection.wayIds[i] == wayID)
                    continue;

                highwayFound = highwayList.Find(item => item.id == intersection.wayIds[i]);

                if(intersection.intersectionTypes[i] == IntersectionType.front) //start
                {

                    if (highwayFound.leftSideVertexes[0] == intersectionPoint || highwayFound.rightSideVertexes[0] == intersectionPoint)
                    {
                        intersectCondition2 = 0;
                        break;
                    }
                }

                else //end
                {

                    if (highwayFound.leftSideVertexes[highwayFound.leftSideVertexes.Count - 1] == intersectionPoint ||
                        highwayFound.rightSideVertexes[highwayFound.rightSideVertexes.Count - 1] == intersectionPoint)
                    {
                        intersectCondition2 = 1;
                        break;
                    }
                }
            }

            //3. We found the 2 highways that are intersecting from the side stated. Lets Get appropriate pavement obj and calculate
            //intersection points

            Vector2 p1, p2, p3, p4;
            int pavOrgIndex=-1, pavFoundIndex=-1;

            pavOrgIndex = pavementList.FindIndex(item => item.Pavementid == wayID && item.side == side);

            if(intersectCondition == 1 || intersectCondition == 2)
            {
                if (intersectCondition2 == 0)
                    pavFoundIndex = pavementList.FindIndex(item => item.Pavementid == highwayFound.id && item.side == Pavement.pavementSide.left);
                else if (intersectCondition2 == 1)
                    pavFoundIndex = pavementList.FindIndex(item => item.Pavementid == highwayFound.id && item.side == Pavement.pavementSide.right);
                else
                {
                    Debug.Log("PAVEMENT NOT FOUND EXCEPTION");
                    return;
                }
            }

            if (intersectCondition == 0 || intersectCondition == 3)
            {
                if (intersectCondition2 == 0)
                    pavFoundIndex = pavementList.FindIndex(item => item.Pavementid == highwayFound.id && item.side == Pavement.pavementSide.right);
                else if (intersectCondition2 == 1)
                    pavFoundIndex = pavementList.FindIndex(item => item.Pavementid == highwayFound.id && item.side == Pavement.pavementSide.left);
                else
                {
                    Debug.Log("PAVEMENT NOT FOUND EXCEPTION");
                    return;
                }
            }

            //3.1 Check if other highway has sidewalk at the given side
            if (pavFoundIndex == -1)
            {
                //Debug.Log("No Pavement to Intersect");
                return;
            }

            //3.2 Calculate Points for intersection
            if (intersectCondition == 0) //start-left
            {
                p1 = new Vector2(pavementList[pavOrgIndex].leftSideVertexes[0].x, pavementList[pavOrgIndex].leftSideVertexes[0].z);
                p2 = new Vector2(pavementList[pavOrgIndex].leftSideVertexes[1].x, pavementList[pavOrgIndex].leftSideVertexes[1].z);

                if(intersectCondition2 == 0) // start-right
                {
                    p3 = new Vector2(pavementList[pavFoundIndex].rightSideVertexes[0].x, pavementList[pavFoundIndex].rightSideVertexes[0].z);
                    p4 = new Vector2(pavementList[pavFoundIndex].rightSideVertexes[1].x, pavementList[pavFoundIndex].rightSideVertexes[1].z);

                    Geometry.getInfiniteLineIntersection(ref calculatedIntersection, p1, p2, p3, p4);
                    Vector3 newVertice = new Vector3(calculatedIntersection.x,
                                                 terrain.getTerrainHeight2(calculatedIntersection.y + terrain.terrainInfo.shiftZ, calculatedIntersection.x + terrain.terrainInfo.shiftX),
                                                 calculatedIntersection.y);
                    pavementList[pavFoundIndex].updateMesh(newVertice, Pavement.pavementSide.right,1);
                    pavementList[pavOrgIndex].updateMesh(newVertice, Pavement.pavementSide.left, 0);

                }
                else //end-left
                {
                    int ind = pavementList[pavFoundIndex].leftSideVertexes.Count;
                    p3 = new Vector2(pavementList[pavFoundIndex].leftSideVertexes[ind-2].x, pavementList[pavFoundIndex].leftSideVertexes[ind-2].z);
                    p4 = new Vector2(pavementList[pavFoundIndex].leftSideVertexes[ind-1].x, pavementList[pavFoundIndex].leftSideVertexes[ind-1].z);

                    Geometry.getInfiniteLineIntersection(ref calculatedIntersection, p1, p2, p3, p4);
                    Vector3 newVertice = new Vector3(calculatedIntersection.x,
                                                 terrain.getTerrainHeight2(calculatedIntersection.y + terrain.terrainInfo.shiftZ, calculatedIntersection.x + terrain.terrainInfo.shiftX),
                                                 calculatedIntersection.y);
                    pavementList[pavFoundIndex].updateMesh(newVertice, Pavement.pavementSide.left,ind-2);
                    pavementList[pavOrgIndex].updateMesh(newVertice, Pavement.pavementSide.left, 0);
                }

            }
            else if (intersectCondition == 1) //start-right
            {
                p1 = new Vector2(pavementList[pavOrgIndex].rightSideVertexes[0].x, pavementList[pavOrgIndex].rightSideVertexes[0].z);
                p2 = new Vector2(pavementList[pavOrgIndex].rightSideVertexes[1].x, pavementList[pavOrgIndex].rightSideVertexes[1].z);

                if (intersectCondition2 == 0) // start-left
                {
                    p3 = new Vector2(pavementList[pavFoundIndex].leftSideVertexes[0].x, pavementList[pavFoundIndex].leftSideVertexes[0].z);
                    p4 = new Vector2(pavementList[pavFoundIndex].leftSideVertexes[1].x, pavementList[pavFoundIndex].leftSideVertexes[1].z);

                    Geometry.getInfiniteLineIntersection(ref calculatedIntersection, p1, p2, p3, p4);
                    Vector3 newVertice = new Vector3(calculatedIntersection.x,
                                                 terrain.getTerrainHeight2(calculatedIntersection.y + terrain.terrainInfo.shiftZ, calculatedIntersection.x + terrain.terrainInfo.shiftX),
                                                 calculatedIntersection.y);
                    pavementList[pavFoundIndex].updateMesh(newVertice, Pavement.pavementSide.left, 0);
                    pavementList[pavOrgIndex].updateMesh(newVertice, Pavement.pavementSide.right, 1);

                }
                else //end-right
                {
                    int ind = pavementList[pavFoundIndex].leftSideVertexes.Count;
                    p3 = new Vector2(pavementList[pavFoundIndex].rightSideVertexes[ind - 2].x, pavementList[pavFoundIndex].rightSideVertexes[ind - 2].z);
                    p4 = new Vector2(pavementList[pavFoundIndex].rightSideVertexes[ind - 1].x, pavementList[pavFoundIndex].rightSideVertexes[ind - 1].z);

                    Geometry.getInfiniteLineIntersection(ref calculatedIntersection, p1, p2, p3, p4);
                    Vector3 newVertice = new Vector3(calculatedIntersection.x,
                                                 terrain.getTerrainHeight2(calculatedIntersection.y + terrain.terrainInfo.shiftZ, calculatedIntersection.x + terrain.terrainInfo.shiftX),
                                                 calculatedIntersection.y);
                    pavementList[pavFoundIndex].updateMesh(newVertice, Pavement.pavementSide.right, ind-1);
                    pavementList[pavOrgIndex].updateMesh(newVertice, Pavement.pavementSide.right, 1);

                }

            }
            else if (intersectCondition == 2) //end-left
            {
                int ind = pavementList[pavOrgIndex].leftSideVertexes.Count;
                p1 = new Vector2(pavementList[pavOrgIndex].leftSideVertexes[ind-2].x, pavementList[pavOrgIndex].leftSideVertexes[ind-2].z);
                p2 = new Vector2(pavementList[pavOrgIndex].leftSideVertexes[ind-1].x, pavementList[pavOrgIndex].leftSideVertexes[ind-1].z);

                if (intersectCondition2 == 0) // start-left
                {
                    p3 = new Vector2(pavementList[pavFoundIndex].leftSideVertexes[0].x, pavementList[pavFoundIndex].leftSideVertexes[0].z);
                    p4 = new Vector2(pavementList[pavFoundIndex].leftSideVertexes[1].x, pavementList[pavFoundIndex].leftSideVertexes[1].z);

                    Geometry.getInfiniteLineIntersection(ref calculatedIntersection, p1, p2, p3, p4);
                    Vector3 newVertice = new Vector3(calculatedIntersection.x,
                                                 terrain.getTerrainHeight2(calculatedIntersection.y + terrain.terrainInfo.shiftZ, calculatedIntersection.x + terrain.terrainInfo.shiftX),
                                                 calculatedIntersection.y);
                    pavementList[pavFoundIndex].updateMesh(newVertice, Pavement.pavementSide.left, 0);
                    pavementList[pavOrgIndex].updateMesh(newVertice, Pavement.pavementSide.left, ind-2);
                }
                else //end-right
                {
                    int ind2 = pavementList[pavFoundIndex].rightSideVertexes.Count;
                    p3 = new Vector2(pavementList[pavFoundIndex].rightSideVertexes[ind2 - 2].x, pavementList[pavFoundIndex].rightSideVertexes[ind2 - 2].z);
                    p4 = new Vector2(pavementList[pavFoundIndex].rightSideVertexes[ind2 - 1].x, pavementList[pavFoundIndex].rightSideVertexes[ind2 - 1].z);

                    Geometry.getInfiniteLineIntersection(ref calculatedIntersection, p1, p2, p3, p4);
                    Vector3 newVertice = new Vector3(calculatedIntersection.x,
                                                 terrain.getTerrainHeight2(calculatedIntersection.y + terrain.terrainInfo.shiftZ, calculatedIntersection.x + terrain.terrainInfo.shiftX),
                                                 calculatedIntersection.y);
                    pavementList[pavFoundIndex].updateMesh(newVertice, Pavement.pavementSide.right, ind2-1);
                    pavementList[pavOrgIndex].updateMesh(newVertice, Pavement.pavementSide.left, ind-2);
                }

            }
            else if (intersectCondition == 3) //end-right
            {
                int ind = pavementList[pavOrgIndex].rightSideVertexes.Count;
                p1 = new Vector2(pavementList[pavOrgIndex].rightSideVertexes[ind-2].x, pavementList[pavOrgIndex].rightSideVertexes[ind-2].z);
                p2 = new Vector2(pavementList[pavOrgIndex].rightSideVertexes[ind-1].x, pavementList[pavOrgIndex].rightSideVertexes[ind-1].z);

                if (intersectCondition2 == 0) // start-right
                {
                    p3 = new Vector2(pavementList[pavFoundIndex].rightSideVertexes[0].x, pavementList[pavFoundIndex].rightSideVertexes[0].z);
                    p4 = new Vector2(pavementList[pavFoundIndex].rightSideVertexes[1].x, pavementList[pavFoundIndex].rightSideVertexes[1].z);

                    Geometry.getInfiniteLineIntersection(ref calculatedIntersection, p1, p2, p3, p4);
                    Vector3 newVertice = new Vector3(calculatedIntersection.x,
                                                 terrain.getTerrainHeight2(calculatedIntersection.y + terrain.terrainInfo.shiftZ, calculatedIntersection.x + terrain.terrainInfo.shiftX),
                                                 calculatedIntersection.y);
                    pavementList[pavFoundIndex].updateMesh(newVertice, Pavement.pavementSide.right, 1);
                    pavementList[pavOrgIndex].updateMesh(newVertice, Pavement.pavementSide.right, ind-1);

                }
                else //end-left
                {
                    int ind2 = pavementList[pavFoundIndex].leftSideVertexes.Count;
                    p3 = new Vector2(pavementList[pavFoundIndex].leftSideVertexes[ind2 - 2].x, pavementList[pavFoundIndex].leftSideVertexes[ind2 - 2].z);
                    p4 = new Vector2(pavementList[pavFoundIndex].leftSideVertexes[ind2 - 1].x, pavementList[pavFoundIndex].leftSideVertexes[ind2 - 1].z);

                    Geometry.getInfiniteLineIntersection(ref calculatedIntersection, p1, p2, p3, p4);
                    Vector3 newVertice = new Vector3(calculatedIntersection.x,
                                                 terrain.getTerrainHeight2(calculatedIntersection.y + terrain.terrainInfo.shiftZ, calculatedIntersection.x + terrain.terrainInfo.shiftX),
                                                 calculatedIntersection.y);
                    pavementList[pavFoundIndex].updateMesh(newVertice, Pavement.pavementSide.left, ind2-2);
                    pavementList[pavOrgIndex].updateMesh(newVertice, Pavement.pavementSide.right, ind-1);
                }

            }
        }
        private void generatePavementList()
        {
            DrapeHighway draper = new DrapeHighway();

            for (int i = 0; i < highwayList.Count; i++)
            {
                if (highwayList[i].hasLeftSidewalk)
                {
                    Pavement newPavement = new Pavement(highwayList[i], terrain,Pavement.pavementSide.left);
                    if (newPavement.leftSideVertexes.Count == 0 || newPavement.rightSideVertexes.Count == 0)
                        continue;
                    draper.DrapeRoad(terrain, newPavement.leftSideVertexes, newPavement.rightSideVertexes);
                    pavementList.Add(newPavement);
                }
                if(highwayList[i].hasRightSideWalk)
                {
                    Pavement newPavement = new Pavement(highwayList[i], terrain, Pavement.pavementSide.right);
                    if (newPavement.leftSideVertexes.Count == 0 || newPavement.rightSideVertexes.Count == 0)
                        continue;
                    draper.DrapeRoad(terrain, newPavement.leftSideVertexes, newPavement.rightSideVertexes);
                    pavementList.Add(newPavement);
                }
            }
        }