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 067// TODO: Are all my sequences only set with id values? (no LatLon/Cas?) @rrh 068public StreetsideSequence(String id) { 069 this.id = id; 070 images = new CopyOnWriteArrayList<>(); 071} 072 073 /** 074 * Adds a new {@link StreetsideAbstractImage} object to the database. 075 * 076 * @param image The {@link StreetsideAbstractImage} object to be added 077 */ 078 public synchronized void add(StreetsideAbstractImage image) { 079 images.add(image); 080 image.setSequence(this); 081 } 082 083 /** 084 * Adds a set of {@link StreetsideAbstractImage} objects to the database. 085 * 086 * @param images The set of {@link StreetsideAbstractImage} objects to be added. 087 */ 088 public synchronized void add(Collection<? extends StreetsideAbstractImage> images) { 089 this.images.addAll(images); 090 images.forEach(img -> img.setSequence(this)); 091 } 092 093 /** 094 * Returns the next {@link StreetsideAbstractImage} in the sequence of a given 095 * {@link StreetsideAbstractImage} object. 096 * 097 * @param image The {@link StreetsideAbstractImage} object whose next image is 098 * going to be returned. 099 * 100 * @return The next {@link StreetsideAbstractImage} object in the sequence. 101 * 102 * @throws IllegalArgumentException if the given {@link StreetsideAbstractImage} object doesn't belong 103 * the this sequence. 104 */ 105 public StreetsideAbstractImage next(StreetsideAbstractImage image) { 106 int i = images.indexOf(image); 107 if (i == -1) { 108 throw new IllegalArgumentException(); 109 } 110 if (i == images.size() - 1) { 111 return null; 112 } 113 return images.get(i + 1); 114 } 115 116 /** 117 * Returns the previous {@link StreetsideAbstractImage} in the sequence of a 118 * given {@link StreetsideAbstractImage} object. 119 * 120 * @param image The {@link StreetsideAbstractImage} object whose previous image is 121 * going to be returned. 122 * 123 * @return The previous {@link StreetsideAbstractImage} object in the sequence. 124 * 125 * @throws IllegalArgumentException if the given {@link StreetsideAbstractImage} object doesn't belong 126 * the this sequence. 127 */ 128 public StreetsideAbstractImage previous(StreetsideAbstractImage image) { 129 int i = images.indexOf(image); 130 if (i < 0) { 131 throw new IllegalArgumentException(); 132 } 133 if (i == 0) { 134 return null; 135 } 136 return images.get(i - 1); 137 } 138 139 /** 140 * Removes a {@link StreetsideAbstractImage} object from the database. 141 * 142 * @param image The {@link StreetsideAbstractImage} object to be removed. 143 */ 144 public void remove(StreetsideAbstractImage image) { 145 images.remove(image); 146 } 147 148 /** 149 * @param id the id to set 150 */ 151 public void setId(String id) { 152 this.id = id; 153 } 154 155 /** 156 * @return the la 157 */ 158 public double getLa() { 159 return la; 160 } 161 162 /** 163 * @param la the la to set 164 */ 165 public void setLa(double la) { 166 this.la = la; 167 } 168 169 /** 170 * @return the lo 171 */ 172 public double getLo() { 173 return lo; 174 } 175 176 /** 177 * @param lo the lo to set 178 */ 179 public void setLo(double lo) { 180 this.lo = lo; 181 } 182 183 /** 184 * Returns the Epoch time when the sequence was captured. 185 * 186 * Negative values mean, no value is set. 187 * 188 * @return A long containing the Epoch time when the sequence was captured. 189 */ 190 public long getCd() { 191 return cd; 192 } 193 194 /** 195 * Returns all {@link StreetsideAbstractImage} objects contained by this 196 * object. 197 * 198 * @return A {@link List} object containing all the 199 * {@link StreetsideAbstractImage} objects that are part of the 200 * sequence. 201 */ 202 public List<StreetsideAbstractImage> getImages() { 203 return images; 204 } 205 206 /** 207 * Returns the unique identifier of the sequence. 208 * 209 * @return A {@code String} containing the unique identifier of the sequence. 210 * null means that the sequence has been created locally for imported 211 * images. 212 */ 213 public String getId() { 214 return id; 215 } 216 217 public UserProfile getUser() { 218 return user; 219 } 220}