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.PatternData;
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 * BannerComponent - List of all patterns applied to the banner or the shield.
036 *
037 * @see <a href="https://minecraft.wiki/w/Data_component_format#banner_patterns">Reference</a>
038 *
039 * @author creatorfromhell
040 * @since 0.2.0.0
041 */
042
043public abstract class BannerPatternsComponent<I extends AbstractItemStack<T>, T> implements SerialComponent<I, T> {
044
045  protected final List<PatternData> patterns = new ArrayList<>();
046
047  /**
048   * Represents a component that handles banner patterns for an object.
049   * @since 0.2.0.0
050   */
051  public BannerPatternsComponent() {
052
053  }
054
055  /**
056   * Creates a new BannerPatternsComponent with the provided list of PatternData objects.
057   *
058   * @param patterns The list of PatternData objects to initialize the component with.
059   * @since 0.2.0.0
060   */
061  public BannerPatternsComponent(final List<PatternData> patterns) {
062
063    this.patterns.addAll(patterns);
064  }
065
066  /**
067   * @return the type of component this is.
068   * @since 0.2.0.0
069   */
070  @Override
071  public String identifier() {
072    return "banner_patterns";
073  }
074
075  /**
076   * Converts this component's data to a JSON object.
077   *
078   * @return The JSONObject representing this component's data.
079   * @since 0.2.0.0
080   */
081  @Override
082  public JSONObject toJSON() {
083    final JSONObject json = new JSONObject();
084
085    final JSONArray patternsArray = new JSONArray();
086    for(final PatternData pattern : patterns) {
087
088      final JSONObject patternJson = new JSONObject();
089      patternJson.put("color", pattern.getColor());
090      patternJson.put("pattern", pattern.getPattern());
091      patternsArray.add(patternJson);
092    }
093    json.put("patterns", patternsArray);
094
095    return json;
096  }
097
098  /**
099   * Reads JSON data and converts it back to this component's data.
100   *
101   * @param json The JSONHelper instance of the JSON data.
102   * @param platform The ItemPlatform instance.
103   * @since 0.2.0.0
104   */
105  @Override
106  public void readJSON(final JSONHelper json, final ItemPlatform<I, T, ?> platform) {
107    patterns.clear();
108
109    final JSONArray patternsArray = (JSONArray) json.getObject().get("patterns");
110    if(patternsArray != null) {
111      for(final Object obj : patternsArray) {
112
113        final JSONObject patternJson = (JSONObject) obj;
114        final String color = patternJson.get("color").toString();
115        final String pattern = patternJson.get("pattern").toString();
116        patterns.add(new PatternData(color, pattern));
117      }
118    }
119  }
120
121  /**
122   * Used to determine if some data is equal to this data. This means that it has to be an exact
123   * copy of this data.
124   *
125   * @param component The component to compare.
126   * @return True if similar, otherwise false.
127   * @since 0.2.0.0
128   */
129  @Override
130  public boolean similar(final SerialComponent<?, ?> component) {
131    if(!(component instanceof final BannerPatternsComponent<?, ?> other)) return false;
132
133    return Objects.equals(this.patterns, other.patterns);
134  }
135
136  @Override
137  public int hashCode() {
138    return Objects.hash(patterns);
139  }
140
141  /**
142   * Retrieve the list of PatternData objects associated with this BannerPatternsComponent.
143   *
144   * @return List of PatternData objects representing the patterns.
145   * @since 0.2.0.0
146   */
147  public List<PatternData> patterns() {
148
149    return patterns;
150  }
151
152  /**
153   * Sets the list of patterns for this object by replacing the existing patterns with the provided list.
154   *
155   * @param patterns List of PatternData objects to set as new patterns
156   * @since 0.2.0.0
157   */
158  public void patterns(final List<PatternData> patterns) {
159    this.patterns.clear();
160    this.patterns.addAll(patterns);
161  }
162
163  public void patterns(final PatternData... patterns) {
164    this.patterns.clear();
165    this.patterns.addAll(Arrays.asList(patterns));
166  }
167
168  /**
169   * Adds a pattern to the list of patterns for this BannerPatternsComponent.
170   *
171   * @param pattern The PatternData to add.
172   * @since 0.2.0.0
173   */
174  public void patterns(final PatternData pattern) {
175    this.patterns.add(pattern);
176  }
177}