// Path: app/src/main/java/br/ufs/demos/rxmvp/playground/core/behaviours/BehavioursCoordinator.java
// public class BehavioursCoordinator<T> implements FlowableTransformer<T, T> {
// 
//     private AssignEmptyState<T> dealWithEmptyState;
//     private AssignErrorState<T> assignErrorState;
//     private LoadingCoordination<T> loadingCoordinator;
//     private NetworkingErrorFeedback<T> networkingErrorFeedback;
//     private RefreshToogle<T> refreshToogle;
// 
//     public BehavioursCoordinator(AssignEmptyState<T> dealWithEmptyState,
//                                  AssignErrorState<T> assignErrorState,
//                                  LoadingCoordination<T> loadingCoordinator,
//                                  NetworkingErrorFeedback<T> networkingErrorFeedback,
//                                  RefreshToogle<T> refreshToogle) {
// 
//         this.dealWithEmptyState = dealWithEmptyState;
//         this.assignErrorState = assignErrorState;
//         this.loadingCoordinator = loadingCoordinator;
//         this.networkingErrorFeedback = networkingErrorFeedback;
//         this.refreshToogle = refreshToogle;
//     }
// 
//     @Override public Publisher<T> apply(Flowable<T> upstream) {
//         return upstream
//                 .compose(dealWithEmptyState)
//                 .compose(assignErrorState)
//                 .compose(loadingCoordinator)
//                 .compose(refreshToogle)
//                 .compose(networkingErrorFeedback);
//     }
// }
// 
// Path: app/src/main/java/br/ufs/demos/rxmvp/playground/core/lifecycles/LifecycleStrategist.java
// public class LifecycleStrategist {
// 
//     private DisposeStrategy strategy;
// 
//     public LifecycleStrategist(LifecycleOwner owner, DisposeStrategy strategy) {
//         this.strategy = strategy;
//         owner.getLifecycle().addObserver(strategy);
//     }
// 
//     public void applyStrategy(Disposable toDispose) {
//         strategy.addDisposable(toDispose);
//     }
// 
// }
// 
// Path: app/src/main/java/br/ufs/demos/rxmvp/playground/trivia/domain/FactAboutNumber.java
// public class FactAboutNumber {
// 
//     public String number;
//     public String fact;
// 
//     private FactAboutNumber(String number, String fact) {
//         this.number = number;
//         this.fact = fact;
//     }
// 
//     public static FactAboutNumber of(String number, String fact) {
//         return new FactAboutNumber(number, fact);
//     }
// }
// 
// Path: app/src/main/java/br/ufs/demos/rxmvp/playground/trivia/domain/GetRandomFacts.java
// public interface GetRandomFacts {
// 
//     Flowable<FactAboutNumber> fetchTrivia();
// 
// }
// 
// Path: app/src/main/java/br/ufs/demos/rxmvp/playground/trivia/presentation/models/FactViewModel.java
// public interface FactViewModel {
// 
//     int TYPE_TWO_LABELS = 0;
//     int TYPE_SINGLE_LABEL = 1;
// 
//     CharSequence formattedFact();
// 
//     int viewType();
// 
// }
// 
// Path: app/src/main/java/br/ufs/demos/rxmvp/playground/util/DomainToViewModel.java
// public interface DomainToViewModel<Data, ViewModel> {
// 
//     ViewModel translate(Data data);
// 
// }


import br.ufs.demos.rxmvp.playground.core.behaviours.BehavioursCoordinator;
import br.ufs.demos.rxmvp.playground.core.lifecycles.LifecycleStrategist;
import br.ufs.demos.rxmvp.playground.trivia.domain.FactAboutNumber;
import br.ufs.demos.rxmvp.playground.trivia.domain.GetRandomFacts;
import br.ufs.demos.rxmvp.playground.trivia.presentation.models.FactViewModel;
import br.ufs.demos.rxmvp.playground.util.DomainToViewModel;
import io.reactivex.Flowable;
import io.reactivex.disposables.Disposable;
package br.ufs.demos.rxmvp.playground.trivia.presentation;


/**
 * Created by bira on 6/29/17.
 */

public class FactsPresenter {

    private GetRandomFacts usecase;
    private DisplayFactsView view;
    private BehavioursCoordinator<FactAboutNumber> coordinator;
    private LifecycleStrategist strategist;
    private DomainToViewModel<FactAboutNumber, FactViewModel> mapper;

    public FactsPresenter(GetRandomFacts usecase,
                          DisplayFactsView view,
                          BehavioursCoordinator<FactAboutNumber> coordinator,
                          LifecycleStrategist strategist,
                          DomainToViewModel<FactAboutNumber, FactViewModel> mapper) {

        this.usecase = usecase;
        this.view = view;
        this.coordinator = coordinator;
        this.strategist = strategist;
        this.mapper = mapper;
    }

    public void fetchRandomFacts() {
        Flowable<FactViewModel> dataFlow =
                usecase.fetchTrivia()
                        .compose(coordinator)
                        .map(fact -> mapper.translate(fact));

        Disposable toDispose = view.subscribeInto(dataFlow);
// Path: app/src/main/java/br/ufs/demos/rxmvp/playground/core/behaviours/BehavioursCoordinator.java
// public class BehavioursCoordinator<T> implements FlowableTransformer<T, T> {
// 
//     private AssignEmptyState<T> dealWithEmptyState;
//     private AssignErrorState<T> assignErrorState;
//     private LoadingCoordination<T> loadingCoordinator;
//     private NetworkingErrorFeedback<T> networkingErrorFeedback;
//     private RefreshToogle<T> refreshToogle;
// 
//     public BehavioursCoordinator(AssignEmptyState<T> dealWithEmptyState,
//                                  AssignErrorState<T> assignErrorState,
//                                  LoadingCoordination<T> loadingCoordinator,
//                                  NetworkingErrorFeedback<T> networkingErrorFeedback,
//                                  RefreshToogle<T> refreshToogle) {
// 
//         this.dealWithEmptyState = dealWithEmptyState;
//         this.assignErrorState = assignErrorState;
//         this.loadingCoordinator = loadingCoordinator;
//         this.networkingErrorFeedback = networkingErrorFeedback;
//         this.refreshToogle = refreshToogle;
//     }
// 
//     @Override public Publisher<T> apply(Flowable<T> upstream) {
//         return upstream
//                 .compose(dealWithEmptyState)
//                 .compose(assignErrorState)
//                 .compose(loadingCoordinator)
//                 .compose(refreshToogle)
//                 .compose(networkingErrorFeedback);
//     }
// }
// 
// Path: app/src/main/java/br/ufs/demos/rxmvp/playground/core/lifecycles/LifecycleStrategist.java
// public class LifecycleStrategist {
// 
//     private DisposeStrategy strategy;
// 
//     public LifecycleStrategist(LifecycleOwner owner, DisposeStrategy strategy) {
//         this.strategy = strategy;
//         owner.getLifecycle().addObserver(strategy);
//     }
// 
//     public void applyStrategy(Disposable toDispose) {
//         strategy.addDisposable(toDispose);
//     }
// 
// }
// 
// Path: app/src/main/java/br/ufs/demos/rxmvp/playground/trivia/domain/FactAboutNumber.java
// public class FactAboutNumber {
// 
//     public String number;
//     public String fact;
// 
//     private FactAboutNumber(String number, String fact) {
//         this.number = number;
//         this.fact = fact;
//     }
// 
//     public static FactAboutNumber of(String number, String fact) {
//         return new FactAboutNumber(number, fact);
//     }
// }
// 
// Path: app/src/main/java/br/ufs/demos/rxmvp/playground/trivia/domain/GetRandomFacts.java
// public interface GetRandomFacts {
// 
//     Flowable<FactAboutNumber> fetchTrivia();
// 
// }
// 
// Path: app/src/main/java/br/ufs/demos/rxmvp/playground/trivia/presentation/models/FactViewModel.java
// public interface FactViewModel {
// 
//     int TYPE_TWO_LABELS = 0;
//     int TYPE_SINGLE_LABEL = 1;
// 
//     CharSequence formattedFact();
// 
//     int viewType();
// 
// }
// 
// Path: app/src/main/java/br/ufs/demos/rxmvp/playground/util/DomainToViewModel.java
// public interface DomainToViewModel<Data, ViewModel> {
// 
//     ViewModel translate(Data data);
// 
// }


// Path: app/src/main/java/br/ufs/demos/rxmvp/playground/trivia/presentation/FactsPresenter.java
import br.ufs.demos.rxmvp.playground.core.behaviours.BehavioursCoordinator;
import br.ufs.demos.rxmvp.playground.core.lifecycles.LifecycleStrategist;
import br.ufs.demos.rxmvp.playground.trivia.domain.FactAboutNumber;
import br.ufs.demos.rxmvp.playground.trivia.domain.GetRandomFacts;
import br.ufs.demos.rxmvp.playground.trivia.presentation.models.FactViewModel;
import br.ufs.demos.rxmvp.playground.util.DomainToViewModel;
import io.reactivex.Flowable;
import io.reactivex.disposables.Disposable;

package br.ufs.demos.rxmvp.playground.trivia.presentation;


/**
 * Created by bira on 6/29/17.
 */

public class FactsPresenter {

    private GetRandomFacts usecase;
    private DisplayFactsView view;
    private BehavioursCoordinator<FactAboutNumber> coordinator;
    private LifecycleStrategist strategist;
    private DomainToViewModel<FactAboutNumber, FactViewModel> mapper;

    public FactsPresenter(GetRandomFacts usecase,
                          DisplayFactsView view,
                          BehavioursCoordinator<FactAboutNumber> coordinator,
                          LifecycleStrategist strategist,
                          DomainToViewModel<FactAboutNumber, FactViewModel> mapper) {

        this.usecase = usecase;
        this.view = view;
        this.coordinator = coordinator;
        this.strategist = strategist;
        this.mapper = mapper;
    }

    public void fetchRandomFacts() {
        Flowable<FactViewModel> dataFlow =
                usecase.fetchTrivia()
                        .compose(coordinator)
                        .map(fact -> mapper.translate(fact));

        Disposable toDispose = view.subscribeInto(dataFlow);
        strategist.applyStrategy(toDispose);