/**
   * Adds a section of road with 2 lanes that travels in the directions east and west
   *
   * @param x the x coordinate where to add the road
   * @param y the y coordinate where to add the road
   * @param map the map to add the road to
   * @param mapGridGUIDecorator the GUI decorator associated with this map
   * @param mapGridPane the gridPane that would need to be updated with the new view
   * @param imgView the associated image to place in the x,y cell
   */
  private void addRoadEW(
      int x,
      int y,
      Map map,
      MapGridGUIDecorator mapGridGUIDecorator,
      GridPane mapGridPane,
      ImageView imgView) {
    Coordinate coord = new Coordinate(x, y);
    Road road = new Road(coord, coord);
    try {
      road.addLane(new Lane(coord, coord, MapDirection.EAST));
      road.addLane(new Lane(coord, coord, MapDirection.WEST));
      map.addRoad(road);
      StackPane sp = mapGridGUIDecorator.redrawCell(x, y, mapGridPane);

      sp.setOnMouseClicked(
          click -> {
            ComponentType currentFocused = MapMakerController.getCurrentFocused();
            if (currentFocused == ComponentType.INTERSECTION) {
              addIntersection(x, y, map, mapGridGUIDecorator, mapGridPane, intersectionImgView);
            } else if (currentFocused == ComponentType.ROADNS) {
              addRoadNS(x, y, map, mapGridGUIDecorator, mapGridPane, roadNSImgView);
            } else if (currentFocused == ComponentType.GRASS) {
              addGrass(x, y, map, mapGridGUIDecorator, mapGridPane, grassImgView);
            }
          });

      // put focus back on RoadEW
      MapMakerController.setPreviousFocused(MapMakerController.getCurrentFocused());
      MapMakerController.setCurrentFocused(ComponentType.ROADEW);
      imgView.requestFocus();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  /**
   * Build the map that the user drew into a complete and connected map
   *
   * @param map the map that the user built
   * @return a fixed map that has all roads and intersections connected
   * @throws Exception
   */
  private Map buildAndSaveMap(Map map) throws Exception {
    System.out.println("Building and saving map...");
    int width = map.getWidth();
    int height = map.getHeight();
    Map fixed = new Map(width, height);

    for (int y = 0; y < height; y++) {
      for (int x = 0; x < width; x++) {
        Component current = map.getGrid().get(x, y);
        if (current instanceof Intersection) {
          Coordinate location = new Coordinate(x, y);
          Intersection i = new Intersection(location);
          fixed.addIntersection(i);
          deleteFromOldMap(map, location, location);
        } else if (current instanceof Road) {
          Road road = (Road) current;
          Coordinate lastKnownCoord = road.getEndLocation();

          if (road.runsVertically()) {
            if (lastKnownCoord.getY() != height - 1) {
              Component next = map.getGrid().get(x, y++);
              while (next != null && next instanceof Road) {
                lastKnownCoord = ((Road) next).getEndLocation();
                if (y == height) break;
                next = map.getGrid().get(x, y++);
              }
              y = road.getStartLocation().getY(); // go back to the row we started at
            }
            Coordinate start = road.getStartLocation();
            Coordinate end = lastKnownCoord;
            Road newRoad = new Road(start, end);
            newRoad.addLane(new Lane(end, start, MapDirection.NORTH));
            newRoad.addLane(new Lane(start, end, MapDirection.SOUTH));
            fixed.addRoad(newRoad);
            deleteFromOldMap(map, start, end);
          } else {
            if (lastKnownCoord.getX() != width - 1) {
              Component next = map.getGrid().get(x++, y);
              while (next != null && next instanceof Road) {
                lastKnownCoord = ((Road) next).getEndLocation();
                if (x == width) break;
                next = map.getGrid().get(x++, y);
              }
              x =
                  x
                      - 2; // we overshot by 1, so go back, and loop will increment, so go back
                           // another
            }
            Coordinate start = road.getStartLocation();
            Coordinate end = lastKnownCoord;
            Road newRoad = new Road(start, end);
            newRoad.addLane(new Lane(start, end, MapDirection.EAST));
            newRoad.addLane(new Lane(end, start, MapDirection.WEST));
            fixed.addRoad(newRoad);
            deleteFromOldMap(map, start, end);
          }
        }
      }
    }

    assignIntersectionsToRoads(fixed);
    return fixed;
  }