/**
   * Adds a fields outline to a player's visualization buffer
   *
   * @param player
   * @param ce
   */
  public void displayFieldOutline(Player player, CuboidEntry ce) {
    Visualization vis = visualizations.get(player.getName());

    if (vis == null) {
      vis = new Visualization();
    }

    // save current outline and clear out the visualization

    List<BlockEntry> oldBlocks = new ArrayList<BlockEntry>(vis.getOutlineBlocks());
    List<BlockEntry> newBlocks = new ArrayList<BlockEntry>();

    int frameType = plugin.getSettingsManager().getVisualizeFrameBlock();

    int offset = ce.selectedCount() > 1 ? 1 : 0;

    int minx = ce.getMinx() - offset;
    int miny = ce.getMiny() - offset;
    int minz = ce.getMinz() - offset;
    int maxx = ce.getMaxx() + offset;
    int maxy = ce.getMaxy() + offset;
    int maxz = ce.getMaxz() + offset;

    // add  the blocks for the new outline

    if (plugin.getSettingsManager().isVisualizationNewStyle()) {
      PlayerEntry data = plugin.getPlayerManager().getPlayerEntry(player.getName());
      int spacing =
          ((Math.max(Math.max((maxx - minx), (maxy - miny)), (maxz - minz)) + 2)
                  / data.getDensity())
              + 1;

      for (int x = minx; x <= maxx; x++) {
        int frame = (x == minx || x == maxx) ? 89 : frameType;

        Location loc = new Location(player.getWorld(), x, miny, maxz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), x, maxy, minz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), x, miny, minz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }
        loc = new Location(player.getWorld(), x, maxy, maxz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }
      }

      for (int y = miny; y <= maxy; y++) {
        int frame = (y == miny || y == maxy) ? 89 : frameType;

        Location loc = new Location(player.getWorld(), minx, y, maxz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), maxx, y, minz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), minx, y, minz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), maxx, y, maxz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }
      }

      for (int z = minz; z <= maxz; z++) {
        int frame = (z == minz || z == maxz) ? 89 : frameType;

        Location loc = new Location(player.getWorld(), minx, maxy, z);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), maxx, miny, z);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), minx, miny, z);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), maxx, maxy, z);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }
      }
    } else {
      for (int x = minx; x <= maxx; x++) {
        int frame = (x == minx || x == maxx) ? 89 : frameType;

        Location loc = new Location(player.getWorld(), x, miny, maxz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), x, maxy, minz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), x, miny, minz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), x, maxy, maxz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
      }

      for (int y = miny; y <= maxy; y++) {
        int frame = (y == miny || y == maxy) ? 89 : frameType;

        Location loc = new Location(player.getWorld(), minx, y, maxz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), maxx, y, minz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), minx, y, minz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), maxx, y, maxz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
      }

      for (int z = minz; z <= maxz; z++) {
        int frame = (z == minz || z == maxz) ? 89 : frameType;

        Location loc = new Location(player.getWorld(), minx, maxy, z);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), maxx, miny, z);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), minx, miny, z);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), maxx, maxy, z);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
      }
    }

    // revert the blocks that are no longer in the new set and should be reverted

    List<BlockEntry> revertible = new ArrayList<BlockEntry>(oldBlocks);
    revertible.removeAll(newBlocks);

    Visualize revert =
        new Visualize(
            revertible, player, true, false, plugin.getSettingsManager().getVisualizeSeconds());

    // visualize all the new blocks that are left to visualize

    List<BlockEntry> missing = new ArrayList<BlockEntry>(newBlocks);
    missing.removeAll(oldBlocks);

    Visualize visualize =
        new Visualize(
            missing, player, false, true, plugin.getSettingsManager().getVisualizeSeconds());

    vis.setOutlineBlocks(newBlocks);
    visualizations.put(player.getName(), vis);
  }