188 lines
5.0 KiB
Java
188 lines
5.0 KiB
Java
package model;
|
|
|
|
import strategy.SortingStrategy;
|
|
import iterator.AlbumIterator;
|
|
import iterator.PhotoIterator;
|
|
|
|
import java.util.*;
|
|
|
|
/**
|
|
* A model that represents a photo album.
|
|
* <p>
|
|
* This class is responsible for managing the photos in the album, as well as
|
|
* the sorting strategy used to sort the photos.
|
|
* The model notifies its listeners when the model changes.
|
|
* It also provides methods to add and delete photos,
|
|
* as well as to navigate through the photos.
|
|
*
|
|
* @author Yuri Tatishchev
|
|
* @version 0.1 2025-03-26
|
|
* @see Photo
|
|
* @see SortingStrategy
|
|
* @see AlbumIterator
|
|
* @see PhotoIterator
|
|
* @see ModelChangeListener
|
|
*/
|
|
public class PhotoAlbumModel {
|
|
private List<Photo> photos;
|
|
private SortingStrategy<Photo> sortingStrategy;
|
|
private final List<ModelChangeListener> listeners;
|
|
private AlbumIterator iterator;
|
|
|
|
/**
|
|
* A listener interface for model changes.
|
|
* The method {@link #onModelChanged()} is called when the model changes.
|
|
*/
|
|
public interface ModelChangeListener {
|
|
/**
|
|
* Called when the model changes.
|
|
*/
|
|
void onModelChanged();
|
|
}
|
|
|
|
public PhotoAlbumModel() {
|
|
photos = new ArrayList<>();
|
|
listeners = new ArrayList<>();
|
|
iterator = new PhotoIterator(photos);
|
|
}
|
|
|
|
/**
|
|
* Adds a photo to the album.
|
|
* Resets the iterator and notifies the listeners.
|
|
*
|
|
* @param photo the photo to add
|
|
*/
|
|
public void addPhoto(Photo photo) {
|
|
photos.add(photo);
|
|
sortPhotos();
|
|
notifyListeners();
|
|
}
|
|
|
|
/**
|
|
* Deletes a photo from the album by name.
|
|
* If the deleted photo is the current photo or the album is empty,
|
|
* the iterator is reset.
|
|
*
|
|
* @param name the name of the photo to delete
|
|
*/
|
|
public void deletePhoto(String name) {
|
|
Photo currentPhoto = iterator.current();
|
|
photos.removeIf(photo -> photo.name().equals(name));
|
|
if (photos.isEmpty() || (currentPhoto != null && currentPhoto.name().equals(name))) {
|
|
iterator = new PhotoIterator(photos);
|
|
}
|
|
notifyListeners();
|
|
}
|
|
|
|
/**
|
|
* Sets the sorting strategy for the photos.
|
|
* Sorts the photos using the new strategy and resets the iterator.
|
|
*
|
|
* @param strategy the sorting strategy to set
|
|
*/
|
|
public void setSortingStrategy(SortingStrategy<Photo> strategy) {
|
|
this.sortingStrategy = strategy;
|
|
sortPhotos();
|
|
iterator = new PhotoIterator(photos);
|
|
notifyListeners();
|
|
}
|
|
|
|
private void sortPhotos() {
|
|
if (sortingStrategy != null) {
|
|
photos = sortingStrategy.sort(photos);
|
|
iterator = new PhotoIterator(photos);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds a listener for model changes.
|
|
*
|
|
* @param listener the listener to add
|
|
*/
|
|
public void addListener(ModelChangeListener listener) {
|
|
listeners.add(listener);
|
|
}
|
|
|
|
/**
|
|
* Notifies all listeners that the model has changed,
|
|
* calling the {@link ModelChangeListener#onModelChanged()} method.
|
|
*/
|
|
private void notifyListeners() {
|
|
for (ModelChangeListener listener : listeners) {
|
|
listener.onModelChanged();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns an unmodifiable list of photos in the album.
|
|
*
|
|
* @return an unmodifiable list of photos
|
|
*/
|
|
public List<Photo> getPhotos() {
|
|
return Collections.unmodifiableList(photos);
|
|
}
|
|
|
|
/**
|
|
* Returns the photo in the album that the iterator is currently pointing to.
|
|
*
|
|
* @return the current photo
|
|
*/
|
|
public Photo getCurrentPhoto() {
|
|
try {
|
|
return iterator.current();
|
|
} catch (NoSuchElementException e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns whether there is a next photo in the album.
|
|
*
|
|
* @return {@code true} if there is a next photo, {@code false} otherwise
|
|
*/
|
|
public boolean hasNext() {
|
|
return iterator.hasNext();
|
|
}
|
|
|
|
/**
|
|
* Returns whether there is a previous photo in the album.
|
|
*
|
|
* @return {@code true} if there is a previous photo, {@code false} otherwise
|
|
*/
|
|
public boolean hasPrevious() {
|
|
return iterator.hasPrevious();
|
|
}
|
|
|
|
/**
|
|
* Advances the iterator to the next photo in the album.
|
|
* Notifies the listeners.
|
|
*
|
|
* @return the next photo or {@code null} if there is no next photo
|
|
*/
|
|
public Photo next() {
|
|
try {
|
|
Photo next = iterator.next();
|
|
notifyListeners();
|
|
return next;
|
|
} catch (NoSuchElementException e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Advances the iterator to the previous photo in the album.
|
|
* Notifies the listeners.
|
|
*
|
|
* @return the previous photo or {@code null} if there is no previous photo
|
|
*/
|
|
public Photo previous() {
|
|
try {
|
|
Photo prev = iterator.previous();
|
|
notifyListeners();
|
|
return prev;
|
|
} catch (NoSuchElementException e) {
|
|
return null;
|
|
}
|
|
}
|
|
}
|