Move methods to move an image up and down to Image.
[Sone.git] / src / main / java / net / pterodactylus / sone / data / impl / DefaultAlbum.java
1 /*
2  * Sone - Album.java - Copyright © 2011–2013 David Roden
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 package net.pterodactylus.sone.data.impl;
19
20 import static com.google.common.base.Preconditions.checkState;
21
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.UUID;
27
28 import net.pterodactylus.sone.data.Album;
29 import net.pterodactylus.sone.data.Image;
30 import net.pterodactylus.sone.data.Sone;
31 import net.pterodactylus.sone.database.AlbumBuilder;
32 import net.pterodactylus.sone.database.ImageBuilder;
33
34 import com.google.common.base.Function;
35 import com.google.common.base.Optional;
36 import com.google.common.base.Predicates;
37 import com.google.common.collect.Collections2;
38
39 /**
40  * Dumb, store-everything-in-memory implementation of an {@link Album}.
41  *
42  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
43  */
44 public class DefaultAlbum extends AbstractAlbum {
45
46         /** The Sone this album belongs to. */
47         private Sone sone;
48
49         /** The parent album. */
50         private final DefaultAlbum parent;
51
52         /** Nested albums. */
53         private final List<Album> albums = new ArrayList<Album>();
54
55         /** The image IDs in order. */
56         final List<String> imageIds = new ArrayList<String>();
57
58         /** The images in this album. */
59         final Map<String, Image> images = new HashMap<String, Image>();
60
61         /** Creates a new album with a random ID. */
62         public DefaultAlbum(Sone sone, DefaultAlbum parent) {
63                 this(UUID.randomUUID().toString(), sone, parent);
64         }
65
66         /**
67          * Creates a new album with the given ID.
68          *
69          * @param id
70          *              The ID of the album
71          */
72         public DefaultAlbum(String id, Sone sone, DefaultAlbum parent) {
73                 super(id);
74                 this.sone = sone;
75                 this.parent = parent;
76         }
77
78         //
79         // ACCESSORS
80         //
81
82         @Override
83         public Sone getSone() {
84                 return sone;
85         }
86
87         @Override
88         public List<Album> getAlbums() {
89                 return new ArrayList<Album>(albums);
90         }
91
92         @Override
93         public List<Image> getImages() {
94                 return new ArrayList<Image>(Collections2.filter(Collections2.transform(imageIds, new Function<String, Image>() {
95
96                         @Override
97                         @SuppressWarnings("synthetic-access")
98                         public Image apply(String imageId) {
99                                 return images.get(imageId);
100                         }
101                 }), Predicates.notNull()));
102         }
103
104         @Override
105         public Image getAlbumImage() {
106                 if (albumImage == null) {
107                         return null;
108                 }
109                 return Optional.fromNullable(images.get(albumImage)).or(images.values().iterator().next());
110         }
111
112         @Override
113         public Album getParent() {
114                 return parent;
115         }
116
117         @Override
118         public AlbumBuilder newAlbumBuilder() {
119                 return new DefaultAlbumBuilder(sone, this) {
120                         @Override
121                         public Album build() throws IllegalStateException {
122                                 Album album = super.build();
123                                 albums.add(album);
124                                 return album;
125                         }
126                 };
127         }
128
129         @Override
130         public ImageBuilder newImageBuilder() throws IllegalStateException {
131                 return new DefaultImageBuilder(sone, this) {
132                         @Override
133                         public Image build() throws IllegalStateException {
134                                 Image image = super.build();
135                                 if (images.isEmpty() && (albumImage == null)) {
136                                         albumImage = image.getId();
137                                 }
138                                 images.put(image.getId(), image);
139                                 imageIds.add(image.getId());
140                                 return image;
141                         }
142                 };
143         }
144
145         @Override
146         public void moveUp() {
147                 int oldIndex = parent.albums.indexOf(this);
148                 parent.albums.remove(this);
149                 parent.albums.add(Math.max(0, oldIndex - 1), this);
150         }
151
152         @Override
153         public void moveDown() {
154                 int oldIndex = parent.albums.indexOf(this);
155                 parent.albums.remove(this);
156                 parent.albums.add(Math.min(parent.albums.size(), oldIndex + 1), this);
157         }
158
159         @Override
160         public void remove() throws IllegalStateException {
161                 checkState(!isRoot(), "can not remove root album");
162                 removeAllAlbums();
163                 removeAllImages();
164                 parent.albums.remove(this);
165         }
166
167         private void removeAllImages() {
168                 for (Image image : images.values()) {
169                         image.remove();
170                 }
171         }
172
173         private void removeAllAlbums() {
174                 for (Album album: albums) {
175                         album.remove();
176                 }
177         }
178
179 }