package com.tevinjeffrey.rutgersct.ui.sectioninfo; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Bus; import com.squareup.otto.Subscribe; import com.tevinjeffrey.rmp.common.Parameter; import com.tevinjeffrey.rmp.common.Professor; import com.tevinjeffrey.rmp.common.RMP; import com.tevinjeffrey.rutgersct.database.DatabaseHandler; import com.tevinjeffrey.rutgersct.rutgersapi.RetroRutgers; import com.tevinjeffrey.rutgersct.rutgersapi.model.Course.Section; import com.tevinjeffrey.rutgersct.rutgersapi.model.Course.Section.Instructors; import com.tevinjeffrey.rutgersct.rutgersapi.model.Request; import com.tevinjeffrey.rutgersct.rutgersapi.model.Subject; import com.tevinjeffrey.rutgersct.ui.base.BasePresenter; import com.tevinjeffrey.rutgersct.database.DatabaseUpdateEvent; import com.tevinjeffrey.rutgersct.utils.AndroidMainThread; import com.tevinjeffrey.rutgersct.utils.BackgroundThread; import com.tevinjeffrey.rutgersct.utils.RxUtils; import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; import java.util.Iterator; import javax.inject.Inject; import rx.Observable; import rx.Scheduler; import rx.Subscriber; import rx.Subscription; import rx.android.schedulers.AndroidSchedulers; import rx.functions.Action0; import rx.functions.Action1; import rx.functions.Func1; import rx.schedulers.Schedulers; public class SectionInfoPresenterImpl extends BasePresenter implements SectionInfoPresenter { private final String TAG = this.getClass().getSimpleName(); @Inject RMP rmp; @Inject DatabaseHandler mDatabaseHandler; @Inject RetroRutgers mRetroRutgers; @Inject Bus mBus; @Inject @AndroidMainThread Scheduler mMainThread; @Inject @BackgroundThread Scheduler mBackgroundThread; private final Section mSection; private Subscription mSubscription; public SectionInfoPresenterImpl(Section section) { this.mSection = section; } public void setFabState(boolean animate) { if (getView() != null) { boolean sectionTracked = mDatabaseHandler.isSectionTracked(mSection.getRequest()); getView().showSectionTracked(sectionTracked, animate); } } public void toggleFab() { boolean sectionTracked = mDatabaseHandler.isSectionTracked(mSection.getRequest()); if (sectionTracked) { removeSection(mSection.getRequest()); } else { Answers.getInstance().logCustom(new CustomEvent("Tracked Section") .putCustomAttribute("Subject", mSection.getCourse().getEnclosingSubject().getDescription()) .putCustomAttribute("Course", mSection.getCourse().getTrueTitle())); addSection(mSection.getRequest()); } } @Override public void removeSection(Request request) { mDatabaseHandler.removeSectionFromDb(request); } @Override public void addSection(Request request) { mDatabaseHandler.addSectionToDb(request); } public void loadRMP() { final Iterable<Instructors> professorsNotFound = new ArrayList<>(mSection.getInstructors()); cancePreviousSubscription(); Subscriber<Professor> subscriber = new Subscriber<Professor>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { e.printStackTrace(); } @Override public void onNext(Professor professor) { if (getView() != null) getView().addRMPProfessor(professor); } }; mSubscription = buildSearchParameters(mSection) .flatMap(new Func1<Parameter, Observable<Professor>>() { @Override public Observable<Professor> call(Parameter parameter) { return rmp.getProfessor(parameter); } }) //Should need this to busness code. .doOnNext(new Action1<Professor>() { @Override public void call(Professor professor) { for (final Iterator<Instructors> iterator = professorsNotFound.iterator(); iterator.hasNext(); ) { Instructors i = iterator.next(); if (StringUtils.getJaroWinklerDistance(i.getLastName(), professor.getLastName()) > .70 || StringUtils.getJaroWinklerDistance(i.getLastName(), professor.getFirstName()) > .70) { iterator.remove(); } } } }) .subscribeOn(mBackgroundThread) .observeOn(mMainThread) .doOnTerminate(new Action0() { @Override public void call() { if (getView() != null) { getView().showRatingsLayout(); getView().hideRatingsLoading(); for (Instructors i : professorsNotFound) { getView().addErrorProfessor(i.getName()); } } } }) .subscribe(subscriber); } private Observable<Parameter> buildSearchParameters(final Section section) { return Observable.from(section.getInstructors()) .filter(filterGenericInstructors()) .flatMap(new Func1<Instructors, Observable<Parameter>>() { @Override public Observable<Parameter> call(Instructors instructor) { String university = "rutgers"; String department = getMatchingSubject().getDescription(); String location = mSection.getRequest().getLocations().get(0); String courseNumber = section.getCourse().getCourseNumber(); String firstName = instructor.getFirstName(); String lastName = instructor.getLastName(); final Parameter params = new Parameter(university, department, location, courseNumber, firstName, lastName); return Observable.just(params); } public Subject getMatchingSubject() { return mRetroRutgers .getSubjectFromJson(section.getCourse().getSubject()); } }); } @NonNull private Func1<Instructors, Boolean> filterGenericInstructors() { return new Func1<Instructors, Boolean>() { @Override public Boolean call(Instructors instructors) { return !instructors.getLastName().equals("STAFF"); } }; } private void cancePreviousSubscription() { RxUtils.unsubscribeIfNotNull(mSubscription); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } @Override public void onPause() { super.onPause(); mBus.unregister(this); } @Override public void onResume() { mBus.register(this); } @Subscribe public void onDbUpdateEvent(DatabaseUpdateEvent event) { setFabState(true); } @Nullable public SectionInfoView getView() { return (SectionInfoView) super.getView(); } @Override public String toString() { return TAG; } }