cs151/hw3/src/model/PhotoAlbumModel.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;
}
}
}