/*
 * Copyright (c) 2015 PocketHub
 *
 * 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 com.github.pockethub.android.ui.issue;

import android.util.Log;

import com.github.pockethub.android.rx.RxProgress;
import com.meisolsson.githubsdk.core.ServiceGenerator;
import com.meisolsson.githubsdk.model.Milestone;
import com.meisolsson.githubsdk.model.Page;
import com.meisolsson.githubsdk.model.Repository;
import com.github.pockethub.android.R;
import com.github.pockethub.android.ui.BaseProgressDialog;
import com.github.pockethub.android.ui.BaseActivity;
import com.github.pockethub.android.util.ToastUtils;
import com.meisolsson.githubsdk.service.issues.IssueMilestoneService;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

import static java.lang.String.CASE_INSENSITIVE_ORDER;

/**
 * Dialog helper to display a list of milestones to select one from
 */
public class MilestoneDialog extends BaseProgressDialog {

    private static final String TAG = "MilestoneDialog";

    private ArrayList<Milestone> repositoryMilestones;

    private final int requestCode;

    private final BaseActivity activity;

    private final Repository repository;

    /**
     * Create dialog helper to display milestones
     *
     * @param activity
     * @param requestCode
     * @param repository
     */
    public MilestoneDialog(final BaseActivity activity,
            final int requestCode, final Repository repository) {
        super(activity);
        this.activity = activity;
        this.requestCode = requestCode;
        this.repository = repository;
    }

    private void load(final Milestone selectedMilestone) {
        getPageAndNext(1)
                .flatMap(page -> Observable.fromIterable(page.items()))
                .toSortedList((m1, m2) -> CASE_INSENSITIVE_ORDER.compare(m1.title(), m2.title()))
                .compose(RxProgress.bindToLifecycle(activity, R.string.loading_milestones))
                .subscribe(milestones -> {
                    repositoryMilestones = (ArrayList) milestones;

                    show(selectedMilestone);
                }, error -> {
                    Log.e(TAG, "Exception loading milestones", error);
                    ToastUtils.show(activity, error, R.string.error_milestones_load);
                });
    }

    private Observable<Page<Milestone>> getPageAndNext(int i) {
        return ServiceGenerator.createService(activity, IssueMilestoneService.class)
                .getRepositoryMilestones(repository.owner().login(), repository.name(), i)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .flatMapObservable(response -> {
                    Page<Milestone> page = response.body();
                    if (page.next() == null) {
                        return Observable.just(page);
                    }

                    return Observable.just(page)
                            .concatWith(getPageAndNext(page.next()));
                });
    }

    /**
     * Show dialog with given milestone selected
     *
     * @param selectedMilestone
     */
    public void show(Milestone selectedMilestone) {
        if (repositoryMilestones == null) {
            load(selectedMilestone);
            return;
        }

        int checked = -1;
        if (selectedMilestone != null) {
            for (int i = 0; i < repositoryMilestones.size(); i++) {
                if (selectedMilestone.number() == repositoryMilestones.get(i).number()) {
                    checked = i;
                    break;
                }
            }
        }
        MilestoneDialogFragment.show(activity, requestCode,
                activity.getString(R.string.select_milestone), null,
                repositoryMilestones, checked);
    }
}

@@ -1272,16 +1272,44 @@
 rvable;%0A
+import io.reactivex.Single;%0A
 import i
@@ -1655,64 +1655,8 @@
 %22;%0A%0A
-    private ArrayList%3CMilestone%3E repositoryMilestones;%0A%0A
     
@@ -1767,24 +1767,84 @@
 epository;%0A%0A
+    private final Single%3CList%3CMilestone%3E%3E milestoneSingle;%0A%0A
     /**%0A    
@@ -2241,81 +2241,34 @@
 ry;%0A
-    %7D%0A%0A    private void load(final Milestone selectedMilestone) %7B%0A       
+%0A        milestoneSingle =
  get
@@ -2565,351 +2565,14 @@
    .
-subscribe(milestones -%3E %7B%0A                    repositoryMilestones = (ArrayList) milestones;%0A%0A                    show(selectedMilestone);%0A                %7D, error -%3E %7B%0A                    Log.e(TAG, %22Exception loading milestones%22, error);%0A                    ToastUtils.show(activity, error, R.string.error_milestones_load);%0A                %7D
+cache(
 );%0A 
@@ -3469,112 +3469,54 @@
     
-if (repositoryMilestones == null) %7B%0A            load(selectedMilestone);%0A            return;
+milestoneSingle.subscribe(milestones -%3E %7B
 %0A    
-    %7D%0A%0A
     
@@ -3537,16 +3537,20 @@
 d = -1;%0A
+    
         
@@ -3594,16 +3594,20 @@
         
+    
 for (int
@@ -3618,27 +3618,17 @@
  0; i %3C 
-repositoryM
+m
 ilestone
@@ -3640,24 +3640,28 @@
 e(); i++) %7B%0A
+    
             
@@ -3698,27 +3698,17 @@
 er() == 
-repositoryM
+m
 ilestone
@@ -3748,16 +3748,20 @@
         
+    
 checked 
@@ -3789,15 +3789,23 @@
     
+ 
+   
 break;%0A
+    
     
@@ -3822,32 +3822,36 @@
   %7D%0A            
+    
 %7D%0A        %7D%0A    
@@ -3836,34 +3836,42 @@
       %7D%0A        
+ 
-%7D%0A
+   %7D%0A    
         Mileston
@@ -3914,16 +3914,20 @@
 stCode,%0A
+    
         
@@ -4007,19 +4007,29 @@
     
-repositoryM
+    new ArrayList%3C%3E(m
 iles
@@ -4033,16 +4033,17 @@
 lestones
+)
 , checke
@@ -4046,16 +4046,191 @@
 ecked);%0A
+        %7D, error -%3E %7B%0A            Log.e(TAG, %22Exception loading milestones%22, error);%0A            ToastUtils.show(activity, error, R.string.error_milestones_load);%0A        %7D);%0A
     %7D%0A%7D%0A

Improve logic flow of loading milestones