package com.jparkie.aizoban.presenters;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.app.FragmentActivity;
import android.util.Pair;
import android.util.SparseBooleanArray;
import com.jparkie.aizoban.BuildConfig;
import com.jparkie.aizoban.controllers.QueryManager;
import com.jparkie.aizoban.controllers.databases.DatabaseService;
import com.jparkie.aizoban.controllers.events.DownloadChapterQueryEvent;
import com.jparkie.aizoban.controllers.factories.DefaultFactory;
import com.jparkie.aizoban.models.Chapter;
import com.jparkie.aizoban.models.databases.RecentChapter;
import com.jparkie.aizoban.models.downloads.DownloadChapter;
import com.jparkie.aizoban.models.downloads.DownloadManga;
import com.jparkie.aizoban.presenters.mapper.MangaMapper;
import com.jparkie.aizoban.utils.wrappers.DownloadChapterSortCursorWrapper;
import com.jparkie.aizoban.utils.wrappers.RequestWrapper;
import com.jparkie.aizoban.views.MangaView;
import com.jparkie.aizoban.views.activities.ChapterActivity;
import com.jparkie.aizoban.views.activities.MangaActivity;
import com.jparkie.aizoban.views.adapters.DownloadChapterListingsAdapter;
import com.jparkie.aizoban.views.fragments.AddToQueueFragment;
import com.jparkie.aizoban.views.fragments.MarkReadFragment;
import com.jparkie.aizoban.views.fragments.ResumeChapterFragment;
import java.util.ArrayList;
import java.util.List;
import de.greenrobot.event.EventBus;
import rx.Observable;
import rx.Observer;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.functions.Func2;
import rx.functions.Func3;
import rx.schedulers.Schedulers;
public class MangaPresenterOfflineImpl implements MangaPresenter {
public static final String TAG = MangaPresenterOfflineImpl.class.getSimpleName();
private static final String REQUEST_PARCELABLE_KEY = TAG + ":" + "RequestParcelableKey";
private static final String POSITION_PARCELABLE_KEY = TAG + ":" + "PositionParcelableKey";
private MangaView mMangaView;
private MangaMapper mMangaMapper;
private DownloadChapterListingsAdapter mDownloadChapterListingsAdapter;
private RequestWrapper mRequest;
private DownloadManga mDownloadManga;
private com.jparkie.aizoban.models.databases.FavouriteManga mFavouriteManga;
private Parcelable mPositionSavedState;
private Subscription mQueryBothMangaAndChaptersSubscription;
private Subscription mQueryFavouriteMangaSubscription;
private Subscription mQueryDeleteMangaSubscription;
private Subscription mQueryRecentChapterSubscription;
public MangaPresenterOfflineImpl(MangaView mangaView, MangaMapper mangaMapper) {
mMangaView = mangaView;
mMangaMapper = mangaMapper;
}
@Override
public void handleInitialArguments(Intent arguments) {
if (arguments != null) {
if (arguments.hasExtra(MangaActivity.REQUEST_ARGUMENT_KEY)) {
mRequest = arguments.getParcelableExtra(MangaActivity.REQUEST_ARGUMENT_KEY);
arguments.removeExtra(MangaActivity.REQUEST_ARGUMENT_KEY);
}
}
}
@Override
public void initializeViews() {
mMangaView.initializeToolbar();
mMangaView.initializeSwipeRefreshLayout();
mMangaView.initializeAbsListView();
mMangaView.initializeDeletionListView();
mMangaView.initializeEmptyRelativeLayout();
}
@Override
public void initializeDataFromUrl() {
mDownloadChapterListingsAdapter = new DownloadChapterListingsAdapter(mMangaView.getContext());
mMangaMapper.registerAdapter(mDownloadChapterListingsAdapter);
initializeFavouriteManga();
}
@Override
public void registerForEvents() {
EventBus.getDefault().register(this);
}
public void onEventMainThread(DownloadChapterQueryEvent event) {
if (event != null) {
deleteDownloadMangaIfNoDownloadChapters();
queryBothMangaAndChaptersFromUrl();
}
}
@Override
public void unregisterForEvents() {
EventBus.getDefault().unregister(this);
}
@Override
public void onResume() {
queryBothMangaAndChaptersFromUrl();
}
@Override
public void saveState(Bundle outState) {
if (mRequest != null) {
outState.putParcelable(REQUEST_PARCELABLE_KEY, mRequest);
}
if (mMangaMapper.getPositionState() != null) {
outState.putParcelable(POSITION_PARCELABLE_KEY, mMangaMapper.getPositionState());
}
}
@Override
public void restoreState(Bundle savedState) {
if (savedState.containsKey(REQUEST_PARCELABLE_KEY)) {
mRequest = savedState.getParcelable(REQUEST_PARCELABLE_KEY);
savedState.remove(REQUEST_PARCELABLE_KEY);
}
if (savedState.containsKey(POSITION_PARCELABLE_KEY)) {
mPositionSavedState = savedState.getParcelable(POSITION_PARCELABLE_KEY);
savedState.remove(POSITION_PARCELABLE_KEY);
}
}
@Override
public void destroyAllSubscriptions() {
if (mQueryBothMangaAndChaptersSubscription != null) {
mQueryBothMangaAndChaptersSubscription.unsubscribe();
mQueryBothMangaAndChaptersSubscription = null;
}
if (mQueryFavouriteMangaSubscription != null) {
mQueryFavouriteMangaSubscription.unsubscribe();
mQueryFavouriteMangaSubscription = null;
}
if (mQueryDeleteMangaSubscription != null) {
mQueryDeleteMangaSubscription.unsubscribe();
mQueryDeleteMangaSubscription = null;
}
if (mQueryRecentChapterSubscription != null) {
mQueryRecentChapterSubscription.unsubscribe();
mQueryRecentChapterSubscription = null;
}
}
@Override
public void releaseAllResources() {
if (mDownloadChapterListingsAdapter != null) {
mDownloadChapterListingsAdapter.setCursor(null);
mDownloadChapterListingsAdapter = null;
}
}
@Override
public void onApplyColorChange(int color) {
if (mDownloadChapterListingsAdapter != null) {
mDownloadChapterListingsAdapter.setColor(color);
}
}
@Override
public void onSwipeRefresh() {
queryBothMangaAndChaptersFromUrl();
}
@Override
public void onChapterClick(int position) {
if (mDownloadChapterListingsAdapter != null) {
DownloadChapter selectedDownloadChapter = (DownloadChapter) mDownloadChapterListingsAdapter.getItem(position);
if (selectedDownloadChapter != null) {
String chapterSource = selectedDownloadChapter.getSource();
String chapterUrl = selectedDownloadChapter.getUrl();
final RequestWrapper chapterRequest = new RequestWrapper(chapterSource, chapterUrl);
if (mQueryRecentChapterSubscription != null) {
mQueryRecentChapterSubscription.unsubscribe();
mQueryRecentChapterSubscription = null;
}
mQueryRecentChapterSubscription = QueryManager
.queryRecentChapterFromRequest(chapterRequest, true)
.map(new Func1<Cursor, Cursor>() {
@Override
public Cursor call(Cursor incomingCursor) {
if (incomingCursor != null && incomingCursor.getCount() != 0) {
return incomingCursor;
}
return null;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Cursor>() {
@Override
public void onCompleted() {
// Do Nothing.
}
@Override
public void onError(Throwable e) {
if (BuildConfig.DEBUG) {
e.printStackTrace();
}
}
@Override
public void onNext(Cursor recentChapterCursor) {
if (recentChapterCursor != null) {
RecentChapter recentChapter = QueryManager.toObject(recentChapterCursor, RecentChapter.class);
if (recentChapter != null) {
if (((FragmentActivity) mMangaView.getContext()).getSupportFragmentManager().findFragmentByTag(ResumeChapterFragment.TAG) == null) {
ResumeChapterFragment resumeChapterFragment = ResumeChapterFragment.newInstance(recentChapter);
resumeChapterFragment.show(((FragmentActivity) mMangaView.getContext()).getSupportFragmentManager(), ResumeChapterFragment.TAG);
}
return;
}
}
Intent chapterIntent = ChapterActivity.constructOfflineChapterActivityIntent(mMangaView.getContext(), chapterRequest, 0);
mMangaView.getContext().startActivity(chapterIntent);
}
});
}
}
}
@Override
public void onFavourite() {
try {
if (mDownloadManga != null) {
if (mFavouriteManga != null) {
QueryManager.deleteObjectToApplicationDatabase(mFavouriteManga);
mFavouriteManga = null;
mMangaView.setFavouriteButton(false);
} else {
mFavouriteManga = DefaultFactory.FavouriteManga.constructDefault();
mFavouriteManga.setSource(mDownloadManga.getSource());
mFavouriteManga.setUrl(mDownloadManga.getUrl());
mFavouriteManga.setName(mDownloadManga.getName());
mFavouriteManga.setThumbnailUrl(mDownloadManga.getThumbnailUrl());
QueryManager.putObjectToApplicationDatabase(mFavouriteManga);
mMangaView.setFavouriteButton(true);
}
}
} catch (Throwable e) {
if (BuildConfig.DEBUG) {
e.printStackTrace();
}
}
}
@Override
public void onOptionRefresh() {
queryBothMangaAndChaptersFromUrl();
mMangaView.scrollToTop();
}
@Override
public void onOptionMarkRead() {
if (((FragmentActivity) mMangaView.getContext()).getSupportFragmentManager().findFragmentByTag(MarkReadFragment.TAG) == null) {
MarkReadFragment markReadFragment = MarkReadFragment.newOfflineInstance(mRequest);
markReadFragment.show(((FragmentActivity) mMangaView.getContext()).getSupportFragmentManager(), MarkReadFragment.TAG);
}
}
@Override
public void onOptionDownload() {
if (((FragmentActivity) mMangaView.getContext()).getSupportFragmentManager().findFragmentByTag(AddToQueueFragment.TAG) == null) {
AddToQueueFragment addToQueueFragment = AddToQueueFragment.newInstance(mRequest);
addToQueueFragment.show(((FragmentActivity) mMangaView.getContext()).getSupportFragmentManager(), AddToQueueFragment.TAG);
}
}
@Override
public void onOptionToTop() {
mMangaView.scrollToTop();
}
@Override
public void onOptionDelete() {
if (mDownloadChapterListingsAdapter != null) {
ArrayList<DownloadChapter> chaptersToDelete = new ArrayList<DownloadChapter>();
SparseBooleanArray checkedItems = mMangaMapper.getCheckedItemPositions();
for (int index = 0; index < mDownloadChapterListingsAdapter.getCount(); index++) {
if (checkedItems.get(index + mMangaView.getHeaderViewsCount())) {
DownloadChapter downloadChapter = (DownloadChapter) mDownloadChapterListingsAdapter.getItem(index);
if (downloadChapter != null) {
chaptersToDelete.add(downloadChapter);
}
}
}
Intent startService = new Intent(mMangaView.getContext(), DatabaseService.class);
startService.putExtra(DatabaseService.INTENT_DELETE_DOWNLOAD_CHAPTERS, chaptersToDelete);
mMangaView.getContext().startService(startService);
}
}
@Override
public void onOptionSelectAll() {
mMangaView.selectAll();
}
@Override
public void onOptionClear() {
mMangaView.clear();
}
private void initializeFavouriteManga() {
if (mQueryFavouriteMangaSubscription != null) {
mQueryFavouriteMangaSubscription.unsubscribe();
mQueryFavouriteMangaSubscription = null;
}
if (mRequest != null) {
mQueryFavouriteMangaSubscription = QueryManager
.queryFavouriteMangaFromRequest(mRequest)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Cursor>() {
@Override
public void onCompleted() {
if (mFavouriteManga != null) {
mMangaView.initializeFavouriteButton(true);
} else {
mMangaView.initializeFavouriteButton(false);
}
}
@Override
public void onError(Throwable e) {
if (BuildConfig.DEBUG) {
e.printStackTrace();
}
}
@Override
public void onNext(Cursor favouriteCursor) {
if (favouriteCursor != null && favouriteCursor.getCount() != 0) {
mFavouriteManga = QueryManager.toObject(favouriteCursor, com.jparkie.aizoban.models.databases.FavouriteManga.class);
}
}
});
}
}
private void queryBothMangaAndChaptersFromUrl() {
if (mQueryBothMangaAndChaptersSubscription != null) {
mQueryBothMangaAndChaptersSubscription.unsubscribe();
mQueryBothMangaAndChaptersSubscription = null;
}
if (mRequest != null) {
mMangaView.showRefreshing();
Observable<Cursor> queryDownloadChaptersFromUrlObservable = QueryManager
.queryDownloadChaptersOfDownloadManga(mRequest, true);
Observable<List<String>> queryChapterUrlsFromUrlObservable = QueryManager
.queryChaptersOfMangaFromRequest(mRequest, false)
.flatMap(new Func1<Cursor, Observable<Chapter>>() {
@Override
public Observable<Chapter> call(Cursor chapterCursor) {
List<Chapter> chapters = QueryManager.toList(chapterCursor, Chapter.class);
return Observable.from(chapters.toArray(new Chapter[chapters.size()]));
}
})
.flatMap(new Func1<Chapter, Observable<String>>() {
@Override
public Observable<String> call(Chapter chapter) {
return Observable.just(chapter.getUrl());
}
})
.toList();
Observable<Cursor> queryMangaFromUrlObservable = QueryManager
.queryDownloadMangaFromRequest(mRequest);
Observable<Cursor> querySortedDownloadChaptersObservable = Observable.zip(queryDownloadChaptersFromUrlObservable, queryChapterUrlsFromUrlObservable,
new Func2<Cursor, List<String>, Cursor>() {
@Override
public Cursor call(Cursor downloadChapterCursor, List<String> sortedChapterUrls) {
return new DownloadChapterSortCursorWrapper(downloadChapterCursor, sortedChapterUrls);
}
});
Observable<List<String>> queryRecentChapterUrlsObservable = QueryManager
.queryRecentChaptersOfMangaFromRequest(mRequest, true)
.flatMap(new Func1<Cursor, Observable<RecentChapter>>() {
@Override
public Observable<RecentChapter> call(Cursor recentChaptersCursor) {
List<RecentChapter> recentChapters = QueryManager.toList(recentChaptersCursor, RecentChapter.class);
return Observable.from(recentChapters.toArray(new RecentChapter[recentChapters.size()]));
}
})
.flatMap(new Func1<RecentChapter, Observable<String>>() {
@Override
public Observable<String> call(RecentChapter recentChapter) {
return Observable.just(recentChapter.getUrl());
}
})
.toList();
mQueryBothMangaAndChaptersSubscription = Observable.zip(queryMangaFromUrlObservable, querySortedDownloadChaptersObservable, queryRecentChapterUrlsObservable,
new Func3<Cursor, Cursor, List<String>, Pair<Pair<Cursor, Cursor>, List<String>>>() {
@Override
public Pair<Pair<Cursor, Cursor>, List<String>> call(Cursor downloadMangaCursor, Cursor downloadChapterCursor, List<String> recentChapterUrls) {
Pair<Cursor, Cursor> cursorPair = Pair.create(downloadMangaCursor, downloadChapterCursor);
return Pair.create(cursorPair, recentChapterUrls);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Pair<Pair<Cursor, Cursor>, List<String>>>() {
@Override
public void onCompleted() {
if (mDownloadManga != null) {
mMangaView.setTitle(mDownloadManga.getName());
mMangaView.setName(mDownloadManga.getName());
mMangaView.setDescription(mDownloadManga.getDescription());
mMangaView.setAuthor(mDownloadManga.getAuthor());
mMangaView.setArtist(mDownloadManga.getArtist());
mMangaView.setGenre(mDownloadManga.getGenre());
mMangaView.setIsCompleted(mDownloadManga.isCompleted());
mMangaView.setThumbnail(mDownloadManga.getThumbnailUrl());
mMangaView.hideEmptyRelativeLayout();
mMangaView.showListViewIfHidden();
}
restorePosition();
mMangaView.hideRefreshing();
}
@Override
public void onError(Throwable e) {
if (BuildConfig.DEBUG) {
e.printStackTrace();
}
mMangaView.hideRefreshing();
}
@Override
public void onNext(Pair<Pair<Cursor, Cursor>, List<String>> pairListPair) {
Pair<Cursor, Cursor> cursorPair = pairListPair.first;
List<String> recentChapterUrls = pairListPair.second;
if (cursorPair != null) {
Cursor downloadMangaCursor = cursorPair.first;
if (downloadMangaCursor != null && downloadMangaCursor.getCount() != 0) {
mDownloadManga = QueryManager.toObject(downloadMangaCursor, DownloadManga.class);
}
Cursor downloadChaptersCursor = cursorPair.second;
if (downloadChaptersCursor != null && downloadChaptersCursor.getCount() != 0) {
mMangaView.hideChapterStatusError();
} else {
mMangaView.showChapterStatusError();
}
if (mDownloadChapterListingsAdapter != null) {
mDownloadChapterListingsAdapter.setCursor(downloadChaptersCursor);
}
}
if (recentChapterUrls != null) {
if (mDownloadChapterListingsAdapter != null) {
mDownloadChapterListingsAdapter.setRecentChapterUrls(recentChapterUrls);
}
}
}
});
}
}
private void restorePosition() {
if (mPositionSavedState != null) {
mMangaMapper.setPositionState(mPositionSavedState);
mPositionSavedState = null;
}
}
private void deleteDownloadMangaIfNoDownloadChapters() {
if (mDownloadManga != null) {
Intent startService = new Intent(mMangaView.getContext(), DatabaseService.class);
startService.putExtra(DatabaseService.INTENT_DELETE_DOWNLOAD_MANGA, mDownloadManga);
mMangaView.getContext().startService(startService);
}
}
}