package org.horaapps.leafpic.data;
import android.content.Context;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.util.Log;
import org.horaapps.leafpic.adapters.MediaAdapter;
import org.horaapps.leafpic.data.base.FilterMode;
import org.horaapps.leafpic.data.base.MediaComparators;
import org.horaapps.leafpic.data.base.SortingMode;
import org.horaapps.leafpic.data.base.SortingOrder;
import org.horaapps.leafpic.data.providers.MediaStoreProvider;
import org.horaapps.leafpic.data.providers.StorageProvider;
import org.horaapps.leafpic.util.ContentHelper;
import org.horaapps.leafpic.util.PreferenceUtil;
import org.horaapps.leafpic.util.StringUtils;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
/**
* Created by dnld on 26/04/16.
*/
public class Album implements Serializable {
private String name = null;
private String path = null;
private long id = -1;
private int count = -1;
private int currentMediaIndex = 0;
private boolean selected = false;
public AlbumSettings settings = null;
private ArrayList<Media> media;
private ArrayList<Media> selectedMedias;
private Album() {
media = new ArrayList<Media>();
selectedMedias = new ArrayList<Media>();
}
public Album(Context context, String path, long id, String name, int count) {
this();
this.path = path;
this.name = name;
this.count = count;
this.id = id;
settings = AlbumSettings.getSettings(context, this);
}
public Album(Context context, @NotNull File mediaPath) {
super();
File folder = mediaPath.getParentFile();
this.path = folder.getPath();
this.name = folder.getName();
settings = AlbumSettings.getSettings(context, this);
updatePhotos(context);
setCurrentPhoto(mediaPath.getAbsolutePath());
}
/**
* used for open an image from an unknown content storage
*
* @param context context
* @param mediaUri uri of the media to display
*/
public Album(Context context, Uri mediaUri) {
super();
media.add(0, new Media(context, mediaUri));
setCurrentPhotoIndex(0);
}
public static Album getEmptyAlbum() {
Album album = new Album();
album.settings = AlbumSettings.getDefaults();
return album;
}
public ArrayList<Media> getMedia() {
ArrayList<Media> mediaArrayList = new ArrayList<Media>();
switch (getFilterMode()) {
case ALL:
mediaArrayList = media;
default:
break;
case GIF:
for (Media media1 : media)
if (media1.isGif()) mediaArrayList.add(media1);
break;
case IMAGES:
for (Media media1 : media)
if (media1.isImage()) mediaArrayList.add(media1);
break;
case VIDEO:
for (Media media1 : media)
if (media1.isVideo()) mediaArrayList.add(media1);
break;
}
return mediaArrayList;
}
public void updatePhotos(Context context) {
media = getMedia(context);
sortPhotos();
setCount(media.size());
}
private void updatePhotos(Context context, FilterMode filterMode) {
ArrayList<Media> media = getMedia(context), mediaArrayList = new ArrayList<Media>();
switch (filterMode) {
case ALL:
mediaArrayList = media;
default:
break;
case GIF:
for (Media media1 : media)
if (media1.isGif()) mediaArrayList.add(media1);
break;
case IMAGES:
for (Media media1 : media)
if (media1.isImage()) mediaArrayList.add(media1);
break;
case VIDEO:
for (Media media1 : media)
if (media1.isVideo()) mediaArrayList.add(media1);
break;
}
this.media = mediaArrayList;
sortPhotos();
setCount(this.media.size());
}
private ArrayList<Media> getMedia(Context context) {
PreferenceUtil SP = PreferenceUtil.getInstance(context);
ArrayList<Media> mediaArrayList = new ArrayList<Media>();
// TODO: 18/08/16
if (isFromMediaStore()) {
mediaArrayList.addAll(
MediaStoreProvider.getMedia(
context, id, SP.getBoolean("set_include_video", true)));
} else {
mediaArrayList.addAll(StorageProvider.getMedia(
getPath(), SP.getBoolean("set_include_video", true)));
}
return mediaArrayList;
}
public ArrayList<Media> getSelectedMedia() {
return selectedMedias;
}
public Media getSelectedMedia(int index) {
return selectedMedias.get(index);
}
private boolean isFromMediaStore() {
return id != -1;
}
public void setName(String name) {
this.name = name;
}
public void setPath(String path) {
this.path = path;
}
public long getId() {
return this.id;
}
public ArrayList<String> getParentsFolders() {
ArrayList<String> result = new ArrayList<String>();
File f = new File(getPath());
while(f != null && f.canRead()) {
result.add(f.getPath());
f = f.getParentFile();
}
return result;
}
public boolean isPinned(){ return settings.isPinned(); }
public void filterMedias(Context context, FilterMode filter) {
settings.setFilterMode(filter);
updatePhotos(context, filter);
}
public boolean addMedia(@Nullable Media media) {
if(media == null) return false;
this.media.add(media);
return true;
}
public boolean hasCustomCover() {
return settings.getCoverPath() != null;
}
void setSelected(boolean selected) {
this.selected = selected;
}
public boolean isSelected() {
return selected;
}
public Media getMedia(int index) { return media.get(index); }
public void setCurrentPhotoIndex(int index){ currentMediaIndex = index; }
public void setCurrentPhotoIndex(Media m){ setCurrentPhotoIndex(media.indexOf(m)); }
public Media getCurrentMedia() { return getMedia(currentMediaIndex); }
public int getCurrentMediaIndex() { return currentMediaIndex; }
public String getName() {
return name;
}
public String getPath() {
return path;
}
private void setCount(int count) {
this.count = count;
}
public int getCount() {
return count;
}
public boolean isHidden() {
return new File(getPath(), ".nomedia").exists();
}
public Media getCoverAlbum() {
if (hasCustomCover())
return new Media(settings.getCoverPath());
if (media.size() > 0)
return media.get(0);
return new Media();
}
public void removeCoverAlbum(Context context) {
settings.changeCoverPath(context, null);
}
public void setSelectedPhotoAsPreview(Context context) {
if (selectedMedias.size() > 0)
settings.changeCoverPath(context, selectedMedias.get(0).getPath());
}
private void setCurrentPhoto(String path) {
for (int i = 0; i < media.size(); i++)
if (media.get(i).getPath().equals(path)) currentMediaIndex = i;
}
public int getSelectedCount() {
return selectedMedias.size();
}
public boolean areMediaSelected() { return getSelectedCount() != 0;}
public void selectAllPhotos() {
for (int i = 0; i < media.size(); i++) {
if (!media.get(i).isSelected()) {
media.get(i).setSelected(true);
selectedMedias.add(media.get(i));
}
}
}
private int toggleSelectPhoto(int index) {
if (media.get(index) != null) {
media.get(index).setSelected(!media.get(index).isSelected());
if (media.get(index).isSelected())
selectedMedias.add(media.get(index));
else
selectedMedias.remove(media.get(index));
}
return index;
}
public int toggleSelectPhoto(Media m) {
return toggleSelectPhoto(media.indexOf(m));
}
public void setDefaultSortingMode(Context context, SortingMode column) {
settings.changeSortingMode(context, column);
}
public boolean renameCurrentMedia(Context context, String newName) {
boolean success = false;
try {
File from = new File(getCurrentMedia().getPath());
File to = new File(StringUtils.getPhotoPathRenamed(getCurrentMedia().getPath(), newName));
if (success = ContentHelper.moveFile(context, from, to)) {
scanFile(context, new String[]{ to.getAbsolutePath(), from.getAbsolutePath() });
getCurrentMedia().setPath(to.getAbsolutePath());
}
} catch (Exception e) { e.printStackTrace(); }
return success;
}
public boolean moveCurrentMedia(Context context, String targetDir) {
boolean success = false;
try {
String from = getCurrentMedia().getPath();
if (success = moveMedia(context, from, targetDir)) {
scanFile(context, new String[]{ from, StringUtils.getPhotoPathMoved(getCurrentMedia().getPath(), targetDir) });
media.remove(getCurrentMediaIndex());
setCount(media.size());
}
} catch (Exception e) { e.printStackTrace(); }
return success;
}
public int moveSelectedMedia(Context context, String targetDir) {
int n = 0;
try
{
for (int i = 0; i < selectedMedias.size(); i++) {
if (moveMedia(context, selectedMedias.get(i).getPath(), targetDir)) {
String from = selectedMedias.get(i).getPath();
scanFile(context, new String[]{ from, StringUtils.getPhotoPathMoved(selectedMedias.get(i).getPath(), targetDir) },
new MediaScannerConnection.OnScanCompletedListener() {
@Override
public void onScanCompleted(String s, Uri uri) {
Log.d("scanFile", "onScanCompleted: " + s);
}
});
media.remove(selectedMedias.get(i));
n++;
}
}
} catch (Exception e) { e.printStackTrace(); }
setCount(media.size());
return n;
}
private boolean moveMedia(Context context, String source, String targetDir) {
File from = new File(source);
File to = new File(targetDir);
return ContentHelper.moveFile(context, from, to);
}
public void setDefaultSortingAscending(Context context, SortingOrder sortingOrder) {
settings.changeSortingOrder(context, sortingOrder);
}
/**
* On longpress, it finds the last or the first selected image before or after the targetIndex
* and selects them all.
*
* @param targetIndex
* @param adapter
*/
public void selectAllPhotosUpTo(int targetIndex, MediaAdapter adapter) {
int indexRightBeforeOrAfter = -1;
int indexNow;
for (Media sm : selectedMedias) {
indexNow = media.indexOf(sm);
if (indexRightBeforeOrAfter == -1) indexRightBeforeOrAfter = indexNow;
if (indexNow > targetIndex) break;
indexRightBeforeOrAfter = indexNow;
}
if (indexRightBeforeOrAfter != -1) {
for (int index = Math.min(targetIndex, indexRightBeforeOrAfter); index <= Math.max(targetIndex, indexRightBeforeOrAfter); index++) {
if (media.get(index) != null) {
if (!media.get(index).isSelected()) {
media.get(index).setSelected(true);
selectedMedias.add(media.get(index));
adapter.notifyItemChanged(index);
}
}
}
}
}
public int getIndex(Media m) { return media.indexOf(m); }
public void clearSelectedPhotos() {
for (Media m : media)
m.setSelected(false);
selectedMedias.clear();
}
public void sortPhotos() {
Collections.sort(media, MediaComparators.getComparator(settings.getSortingMode(), settings.getSortingOrder()));
}
public boolean copySelectedPhotos(Context context, String folderPath) {
boolean success = true;
for (Media media : selectedMedias)
if(!copyPhoto(context, media.getPath(), folderPath))
success = false;
return success;
}
public boolean copyPhoto(Context context, String olderPath, String folderPath) {
boolean success = false;
try {
File from = new File(olderPath);
File to = new File(folderPath);
if (success = ContentHelper.copyFile(context, from, to))
scanFile(context, new String[]{ StringUtils.getPhotoPathMoved(getCurrentMedia().getPath(), folderPath) });
} catch (Exception e) { e.printStackTrace(); }
return success;
}
public boolean deleteCurrentMedia(Context context) {
boolean success = deleteMedia(context, getCurrentMedia());
if (success) {
media.remove(getCurrentMediaIndex());
setCount(media.size());
}
return success;
}
private boolean deleteMedia(Context context, Media media) {
boolean success;
File file = new File(media.getPath());
if (success = ContentHelper.deleteFile(context, file))
scanFile(context, new String[]{ file.getAbsolutePath() });
return success;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Album) {
return getPath().equals(((Album) obj).getPath());
}
return super.equals(obj);
}
public boolean deleteSelectedMedia(Context context) {
boolean success = true;
for (Media selectedMedia : selectedMedias) {
if (deleteMedia(context, selectedMedia))
media.remove(selectedMedia);
else success = false;
}
if (success) {
clearSelectedPhotos();
setCount(media.size());
}
return success;
}
private boolean found_id_album = false;
public boolean renameAlbum(final Context context, String newName) {
found_id_album = false;
boolean success;
File dir = new File(StringUtils.getAlbumPathRenamed(getPath(), newName));
if (success = ContentHelper.mkdir(context, dir)) {
for (final Media m : media) {
File from = new File(m.getPath());
File to = new File(StringUtils.getPhotoPathRenamedAlbumChange(m.getPath(), newName));
if (ContentHelper.moveFile(context, from, to)) {
scanFile(context, new String[]{from.getAbsolutePath() });
scanFile(context, new String[]{ to.getAbsolutePath() }, new MediaScannerConnection.OnScanCompletedListener() {
@Override
public void onScanCompleted(String s, Uri uri) {
// TODO: 05/08/16 it sucks! look for a better solution
if (!found_id_album) {
id = MediaStoreProvider.getAlbumId(context, s);
found_id_album = true;
}
Log.d(s, "onScanCompleted: "+s);
m.setPath(s); m.setUri(uri.toString());
}
});
} else success = false;
}
}
if(success) {
path = dir.getAbsolutePath();
name = newName;
// NOTE: the following line doesn't work
//id = MediaStoreProvider.getAlbumId(context, media.getValue(0).getPath());
}
return success;
}
public void scanFile(Context context, String[] path) { MediaScannerConnection.scanFile(context, path, null, null); }
public void scanFile(Context context, String[] path, MediaScannerConnection.OnScanCompletedListener onScanCompletedListener) {
MediaScannerConnection.scanFile(context, path, null, onScanCompletedListener);
}
public FilterMode getFilterMode() {
return settings != null ? settings.getFilterMode() : FilterMode.ALL;
}
}