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