content: /*
   * Copyright 2016, The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package <%= appPackage %>.taskdetail;
  
  import android.support.annotation.NonNull;
  import android.support.annotation.Nullable;
  
  import <%= appPackage %>.data.Task;
  import <%= appPackage %>.data.source.TasksRepository;
  import <%= appPackage %>.util.schedulers.BaseSchedulerProvider;
  import com.google.common.base.Optional;
  import com.google.common.base.Strings;
  
  import io.reactivex.disposables.CompositeDisposable;
  
  import static com.google.common.base.Preconditions.checkNotNull;
  
  /**
   * Listens to user actions from the UI ({@link TaskDetailFragment}), retrieves the data and updates
   * the UI as required.
   */
  public class TaskDetailPresenter implements TaskDetailContract.Presenter {
  
      @NonNull
      private final TasksRepository mTasksRepository;
  
      @NonNull
      private final TaskDetailContract.View mTaskDetailView;
  
      @NonNull
      private final BaseSchedulerProvider mSchedulerProvider;
  
      @Nullable
      private String mTaskId;
  
      @NonNull
      private CompositeDisposable mCompositeDisposable;
  
      public TaskDetailPresenter(@Nullable String taskId,
                                 @NonNull TasksRepository tasksRepository,
                                 @NonNull TaskDetailContract.View taskDetailView,
                                 @NonNull BaseSchedulerProvider schedulerProvider) {
          this.mTaskId = taskId;
          mTasksRepository = checkNotNull(tasksRepository, "tasksRepository cannot be null!");
          mTaskDetailView = checkNotNull(taskDetailView, "taskDetailView cannot be null!");
          mSchedulerProvider = checkNotNull(schedulerProvider, "schedulerProvider cannot be null");
  
          mCompositeDisposable = new CompositeDisposable();
          mTaskDetailView.setPresenter(this);
      }
  
      @Override
      public void subscribe() {
          openTask();
      }
  
      @Override
      public void unsubscribe() {
          mCompositeDisposable.clear();
      }
  
      private void openTask() {
          if (Strings.isNullOrEmpty(mTaskId)) {
              mTaskDetailView.showMissingTask();
              return;
          }
  
          mTaskDetailView.setLoadingIndicator(true);
          mCompositeDisposable.add(mTasksRepository
                  .getTask(mTaskId)
                  .filter(Optional::isPresent)
                  .map(Optional::get)
                  .subscribeOn(mSchedulerProvider.computation())
                  .observeOn(mSchedulerProvider.ui())
                  .subscribe(
                          // onNext
                          this::showTask,
                          // onError
                          throwable -> {
                          },
                          // onCompleted
                          () -> mTaskDetailView.setLoadingIndicator(false)));
      }
  
      @Override
      public void editTask() {
          if (Strings.isNullOrEmpty(mTaskId)) {
              mTaskDetailView.showMissingTask();
              return;
          }
          mTaskDetailView.showEditTask(mTaskId);
      }
  
      @Override
      public void deleteTask() {
          if (Strings.isNullOrEmpty(mTaskId)) {
              mTaskDetailView.showMissingTask();
              return;
          }
          mTasksRepository.deleteTask(mTaskId);
          mTaskDetailView.showTaskDeleted();
      }
  
      @Override
      public void completeTask() {
          if (Strings.isNullOrEmpty(mTaskId)) {
              mTaskDetailView.showMissingTask();
              return;
          }
          mTasksRepository.completeTask(mTaskId);
          mTaskDetailView.showTaskMarkedComplete();
      }
  
      @Override
      public void activateTask() {
          if (Strings.isNullOrEmpty(mTaskId)) {
              mTaskDetailView.showMissingTask();
              return;
          }
          mTasksRepository.activateTask(mTaskId);
          mTaskDetailView.showTaskMarkedActive();
      }
  
      private void showTask(@NonNull Task task) {
          String title = task.getTitle();
          String description = task.getDescription();
  
          if (Strings.isNullOrEmpty(title)) {
              mTaskDetailView.hideTitle();
          } else {
              mTaskDetailView.showTitle(title);
          }
  
          if (Strings.isNullOrEmpty(description)) {
              mTaskDetailView.hideDescription();
          } else {
              mTaskDetailView.showDescription(description);
          }
          mTaskDetailView.showCompletionStatus(task.isCompleted());
      }
  }
  