/**
   * Saves the Reinforcement to the Database. Should only be called from SaveManager.
   *
   * @param The Reinforcement to save.
   */
  public void saveReinforcement(Reinforcement rein) {
    reconnectAndReinitialize();

    int dur = rein.getDurability();
    boolean insecure = false;
    String groupName = null;
    int mature = rein.getMaturationTime();
    Location loc = rein.getLocation();
    int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ();
    String world = loc.getWorld().getName();
    if (rein instanceof PlayerReinforcement) {
      PlayerReinforcement pRein = (PlayerReinforcement) rein;
      insecure = pRein.isInsecure();
      groupName = pRein.getGroup().getName();
    }
    try {
      PreparedStatement updateRein = db.prepareStatement(this.updateRein);
      updateRein.setInt(1, dur);
      updateRein.setBoolean(2, insecure);
      updateRein.setString(3, groupName);
      updateRein.setInt(4, mature);
      updateRein.setInt(5, x);
      updateRein.setInt(6, y);
      updateRein.setInt(7, z);
      updateRein.setString(8, world);
      updateRein.execute();
    } catch (SQLException e) {
      Citadel.Log(
          String.format(
              "The Null Group Exception that is being followed has to deal with the group name: %s,"
                  + " at location: %d, %d, %d, at world: %s",
              groupName, x, y, z, world));
      e.printStackTrace();
    }
  }
  /**
   * Deletes a Reinforcement from the database. Should only be called within SaveManager
   *
   * @param The Reinforcement to delete.
   */
  public void deleteReinforcement(Reinforcement rein) {
    reconnectAndReinitialize();

    Location loc = rein.getLocation();
    int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ();
    String world = loc.getWorld().getName();
    try {
      PreparedStatement removeRein = db.prepareStatement(this.removeRein);
      removeRein.setInt(1, x);
      removeRein.setInt(2, y);
      removeRein.setInt(3, z);
      removeRein.setString(4, world);
      removeRein.execute();
    } catch (SQLException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
  /**
   * Inserts a reinforcement into the Database. Should only be called from SaveManager.
   *
   * @param The Reinforcement to save.
   */
  public void insertReinforcement(Reinforcement rein) {
    reconnectAndReinitialize();

    if (rein instanceof PlayerReinforcement) {
      Location loc = rein.getLocation();
      int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ();
      String world = loc.getWorld().getName();
      Material mat = rein.getMaterial();
      int dur = rein.getDurability();
      int maturationTime = rein.getMaturationTime();
      boolean insecure = false;
      String group = null;
      String reinType = "";
      String lore = "";
      PlayerReinforcement pRein = (PlayerReinforcement) rein;
      insecure = pRein.isInsecure();
      ItemMeta meta = pRein.getStackRepresentation().getItemMeta();
      if (meta.hasLore()) for (String xx : meta.getLore()) lore += xx + "\n";
      else lore = null;
      group = pRein.getGroup().getName();
      reinType = "PlayerReinforcement";
      try {
        PreparedStatement insertReinID = db.prepareStatement(this.insertReinID);
        insertReinID.setInt(1, x);
        insertReinID.setInt(2, y);
        insertReinID.setInt(3, z);
        String formatChunk = formatChunk(loc);
        insertReinID.setString(4, formatChunk);
        insertReinID.setString(5, world);
        insertReinID.execute();

        int id = getLastReinId();

        PreparedStatement addRein = db.prepareStatement(this.addRein);
        addRein.setInt(1, mat.getId());
        addRein.setInt(2, dur);
        addRein.setBoolean(3, insecure);
        addRein.setInt(4, maturationTime);
        addRein.setString(5, lore);
        addRein.setInt(6, id);
        addRein.setString(7, reinType);
        addRein.setString(8, group);
        addRein.execute();
      } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    } else if (rein instanceof NaturalReinforcement) {
      Location loc = rein.getLocation();
      int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ();
      String world = loc.getWorld().getName();
      Material mat = rein.getMaterial();
      int dur = rein.getDurability();
      String chunk_id = loc.getChunk().toString();
      int maturationTime = rein.getMaturationTime();
      boolean insecure = false;
      String group = NameLayerPlugin.getSpecialAdminGroup();
      String reinType = "NaturalReinforcement";
      String lore = "";
      lore = null;
      try {
        PreparedStatement insertReinID = db.prepareStatement(this.insertReinID);
        insertReinID.setInt(1, x);
        insertReinID.setInt(2, y);
        insertReinID.setInt(3, z);
        String formatChunk = formatChunk(loc);
        insertReinID.setString(4, formatChunk);
        insertReinID.setString(5, world);
        insertReinID.execute();

        int id = getLastReinId();

        PreparedStatement addRein = db.prepareStatement(this.addRein);
        addRein.setInt(1, mat.getId());
        addRein.setInt(2, dur);
        addRein.setBoolean(3, insecure);
        addRein.setInt(4, maturationTime);
        addRein.setString(5, lore);
        addRein.setInt(6, id);
        addRein.setString(7, reinType);
        addRein.setString(8, group);
        addRein.execute();
      } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    } else if (rein instanceof MultiBlockReinforcement) {
      MultiBlockReinforcement mbRein = (MultiBlockReinforcement) rein;
      Location loc = mbRein.getLocation();
      try {
        PreparedStatement insertReinID = db.prepareStatement(this.insertReinID);
        // add all the locations into the db.
        for (Location lo : mbRein.getLocations()) {
          insertReinID.setInt(1, lo.getBlockX());
          insertReinID.setInt(2, lo.getBlockY());
          insertReinID.setInt(3, lo.getBlockZ());
          String formatChunk = formatChunk(lo);
          insertReinID.setString(4, formatChunk);
          insertReinID.setString(5, lo.getWorld().getName());
          insertReinID.addBatch();
        }
        insertReinID.executeBatch();

        int id = getLastReinId();

        PreparedStatement addRein = db.prepareStatement(this.addRein);
        addRein.setInt(1, -1);
        addRein.setInt(2, mbRein.getDurability());
        addRein.setBoolean(3, false);
        addRein.setInt(4, mbRein.getMaturationTime());
        addRein.setString(5, null);
        addRein.setInt(6, id);
        addRein.setString(7, "MultiBlockReinforcement");
        addRein.setString(8, mbRein.getGroup().getName());
        addRein.execute();
      } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }