001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.plugins.streetside;
003
004import java.util.Collection;
005import java.util.List;
006import java.util.concurrent.CopyOnWriteArrayList;
007
008import org.openstreetmap.josm.plugins.streetside.model.UserProfile;
009
010import org.openstreetmap.josm.plugins.streetside.utils.StreetsideUtils;
011
012/**
013 * Class that stores a sequence of {@link StreetsideAbstractImage} objects.
014 *
015 * @author nokutu
016 * @see StreetsideAbstractImage
017 */
018
019public class StreetsideSequence {
020
021
022  /**
023   * Unique identifier. Used only for {@link StreetsideImage} sequences.
024   */
025  private String id;
026  private UserProfile user;
027
028  private double la;
029  private double lo;
030
031  /**
032   * Epoch time when the sequence was created
033   */
034  private long cd;
035
036  /**
037   * The images in the sequence.
038   */
039  private List<StreetsideAbstractImage> images;
040
041  public StreetsideSequence(String id, Long ca) {
042        this.id = id;
043    cd = ca;
044    images = new CopyOnWriteArrayList<>();
045  }
046
047  public StreetsideSequence(String id, double la, double lo) {
048    this.id = id;
049    this.la = la;
050    this.lo = lo;
051    images = new CopyOnWriteArrayList<>();
052  }
053
054  /**
055   * No argument constructor for StreetsideSequence - necessary for JSON serialization
056   */
057  public StreetsideSequence() {
058          images = new CopyOnWriteArrayList<>();
059  }
060
061  public StreetsideSequence(String id, double la, double lo, long ca) {
062        this.id = id;
063        this.la = la;
064        this.lo = lo;
065        cd = ca;
066        images = new CopyOnWriteArrayList<>();
067}
068
069// TODO: Are all my sequences only set with id values? (no LatLon/Cas?) @rrh
070public StreetsideSequence(String id) {
071        this.id = id;
072        images = new CopyOnWriteArrayList<>();
073}
074
075  /**
076   * Adds a new {@link StreetsideAbstractImage} object to the database.
077   *
078   * @param image The {@link StreetsideAbstractImage} object to be added
079   */
080  public synchronized void add(StreetsideAbstractImage image) {
081    images.add(image);
082    image.setSequence(this);
083  }
084
085  /**
086   * Adds a set of {@link StreetsideAbstractImage} objects to the database.
087   *
088   * @param images The set of {@link StreetsideAbstractImage} objects to be added.
089   */
090  @SuppressWarnings("unchecked")
091  public synchronized void add(final Collection<? extends StreetsideAbstractImage> images) {
092    Collection<? extends StreetsideAbstractImage> res = images;
093    res = StreetsideUtils.sortImagesInSequence((List<StreetsideAbstractImage>) images);
094    this.images.addAll(images);
095    images.forEach(img -> img.setSequence(this));
096  }
097
098  /**
099   * Returns the next {@link StreetsideAbstractImage} in the sequence of a given
100   * {@link StreetsideAbstractImage} object.
101   *
102   * @param image The {@link StreetsideAbstractImage} object whose next image is
103   * going to be returned.
104   *
105   * @return The next {@link StreetsideAbstractImage} object in the sequence.
106   *
107   * @throws IllegalArgumentException if the given {@link StreetsideAbstractImage} object doesn't belong
108   * the this sequence.
109   */
110  public StreetsideAbstractImage next(StreetsideAbstractImage image) {
111    int i = images.indexOf(image);
112    if (i == -1) {
113      throw new IllegalArgumentException();
114    }
115    if (i == images.size() - 1) {
116      return null;
117    }
118    return images.get(i + 1);
119  }
120
121  /**
122   * Returns the previous {@link StreetsideAbstractImage} in the sequence of a
123   * given {@link StreetsideAbstractImage} object.
124   *
125   * @param image The {@link StreetsideAbstractImage} object whose previous image is
126   * going to be returned.
127   *
128   * @return The previous {@link StreetsideAbstractImage} object in the sequence.
129   *
130   * @throws IllegalArgumentException if the given {@link StreetsideAbstractImage} object doesn't belong
131   * the this sequence.
132   */
133  public StreetsideAbstractImage previous(StreetsideAbstractImage image) {
134    int i = images.indexOf(image);
135    if (i < 0) {
136      throw new IllegalArgumentException();
137    }
138    if (i == 0) {
139      return null;
140    }
141    return images.get(i - 1);
142  }
143
144  /**
145   * Removes a {@link StreetsideAbstractImage} object from the database.
146   *
147   * @param image The {@link StreetsideAbstractImage} object to be removed.
148   */
149  public void remove(StreetsideAbstractImage image) {
150    images.remove(image);
151  }
152
153  /**
154   * @param id the id to set
155   */
156  public void setId(String id) {
157    this.id = id;
158  }
159
160  /**
161   * @return the la
162   */
163  public double getLa() {
164    return la;
165  }
166
167  /**
168   * @param la the la to set
169   */
170  public void setLa(double la) {
171    this.la = la;
172  }
173
174  /**
175   * @return the lo
176   */
177  public double getLo() {
178    return lo;
179  }
180
181  /**
182   * @param lo the lo to set
183   */
184  public void setLo(double lo) {
185    this.lo = lo;
186  }
187
188  /**
189   * Returns the Epoch time when the sequence was captured.
190   *
191   * Negative values mean, no value is set.
192   *
193   * @return A long containing the Epoch time when the sequence was captured.
194   */
195  public long getCd() {
196    return cd;
197  }
198
199  /**
200   * Returns all {@link StreetsideAbstractImage} objects contained by this
201   * object.
202   *
203   * @return A {@link List} object containing all the
204   * {@link StreetsideAbstractImage} objects that are part of the
205   * sequence.
206   */
207  public List<StreetsideAbstractImage> getImages() {
208    return images;
209  }
210
211  /**
212   * Returns the unique identifier of the sequence.
213   *
214   * @return A {@code String} containing the unique identifier of the sequence.
215   * null means that the sequence has been created locally for imported
216   * images.
217   */
218  public String getId() {
219    return id;
220  }
221
222  public UserProfile getUser() {
223        return user;
224  }
225}