001package net.tnemc.item.component.impl;
002/*
003 * The New Item Library
004 * Copyright (C) 2022 - 2025 Daniel "creatorfromhell" Vidmar
005 *
006 * This program is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * This program is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public License
017 * along with this program; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019 */
020
021import net.tnemc.item.AbstractItemStack;
022import net.tnemc.item.JSONHelper;
023import net.tnemc.item.component.SerialComponent;
024import net.tnemc.item.component.helper.BlockPredicate;
025import net.tnemc.item.platform.ItemPlatform;
026import org.json.simple.JSONArray;
027import org.json.simple.JSONObject;
028
029import java.util.ArrayList;
030import java.util.Arrays;
031import java.util.List;
032import java.util.Objects;
033
034/**
035 * CanPlaceOnComponent
036 *
037 * @see <a href="https://minecraft.wiki/w/Data_component_format#can_place_on">Reference</a>
038 *
039 * @author creatorfromhell
040 * @since 0.2.0.0
041 */
042public abstract class CanPlaceOnComponent<I extends AbstractItemStack<T>, T> implements SerialComponent<I, T> {
043
044  protected final List<BlockPredicate> predicates = new ArrayList<>();
045
046  public CanPlaceOnComponent() {
047
048  }
049
050  public CanPlaceOnComponent(final BlockPredicate predicate) {
051    this.predicates.add(predicate);
052  }
053
054  public CanPlaceOnComponent(final List<BlockPredicate> predicates) {
055    this.predicates.addAll(predicates);
056  }
057
058  @Override
059  public String identifier() {
060    return "can_place_on";
061  }
062
063  @Override
064  public JSONObject toJSON() {
065    final JSONObject json = new JSONObject();
066
067    final JSONArray predicatesArray = new JSONArray();
068    for(final BlockPredicate predicate : predicates) {
069      predicatesArray.add(predicate.toJSON());
070    }
071    json.put("predicates", predicatesArray);
072
073    return json;
074  }
075
076  @Override
077  public void readJSON(final JSONHelper json, final ItemPlatform<I, T, ?> platform) {
078    predicates.clear();
079
080    final JSONArray predicatesArray = (JSONArray) json.getObject().get("predicates");
081    if(predicatesArray != null) {
082      for(final Object obj : predicatesArray) {
083        final JSONObject predicateJson = (JSONObject) obj;
084        final BlockPredicate predicate = new BlockPredicate();
085        predicate.readJSON(new JSONHelper(predicateJson));
086        predicates.add(predicate);
087      }
088    }
089  }
090
091  @Override
092  public boolean similar(final SerialComponent<?, ?> component) {
093    if(!(component instanceof final CanPlaceOnComponent<?, ?> other)) return false;
094
095    return Objects.equals(this.predicates, other.predicates);
096  }
097
098  @Override
099  public int hashCode() {
100    return Objects.hash(predicates);
101  }
102
103  /**
104   * Retrieves the list of predicates associated with this CanBreakComponent.
105   *
106   * @return The list of BlockPredicate objects.
107   * @since 0.2.0.0
108   */
109  public List<BlockPredicate> predicates() {
110
111    return predicates;
112  }
113
114  /**
115   * Modifies the list of predicates associated with this CanBreakComponent by replacing it with a new list.
116   *
117   * @param predicates The new list of BlockPredicate objects to replace the existing list with.
118   * @since 0.2.0.0
119   */
120  public void predicates(final List<BlockPredicate> predicates) {
121    this.predicates.clear();
122    this.predicates.addAll(predicates);
123  }
124
125  /**
126   * Add one or more BlockPredicate objects to the list of predicates associated with this component.
127   *
128   * @param predicates The BlockPredicate objects to add to the list.
129   * @since 0.2.0.0
130   */
131  public void predicates(final BlockPredicate... predicates) {
132    this.predicates.addAll(Arrays.asList(predicates));
133  }
134}