// Path: app/src/main/java/com/github/blazsolar/chuck/data/api/JokesService.java
// public interface JokesService {
// 
//     @GET("/jokes/random")
//     Observable<Response<Joke>> randomJoke();
// 
// }
// 
// Path: app/src/main/java/com/github/blazsolar/chuck/data/api/model/Joke.java
// public class Joke implements Parcelable {
// 
//     private long id;
//     private String joke;
//     private String[] categories;
// 
//     public Joke() {
//     }
// 
//     public Joke(long id, String joke, String[] categories) {
//         this.id = id;
//         this.joke = joke;
//         this.categories = categories;
//     }
// 
//     private Joke(Parcel in) {
//         id = in.readLong();
//         joke = in.readString();
// 
//         int cnt = in.readInt();
//         if (cnt > -1) {
//             categories = new String[cnt];
//             in.readStringArray(categories);
//         }
//     }
// 
//     public long getId() {
//         return id;
//     }
// 
//     public String getJoke() {
//         return joke;
//     }
// 
//     public String[] getCategories() {
//         return categories;
//     }
// 
//     @Override
//     public int describeContents() {
//         return 0;
//     }
// 
//     @Override
//     public void writeToParcel(Parcel dest, int flags) {
//         dest.writeLong(id);
//         dest.writeString(joke);
// 
//         if (categories != null) {
//             dest.writeInt(categories.length);
//             dest.writeStringArray(categories);
//         } else {
//             dest.writeInt(-1);
//         }
//     }
// 
//     public static final Creator<Joke> CREATOR = new Creator<Joke>() {
// 
//         @Override
//         public Joke createFromParcel(Parcel source) {
//             return new Joke(source);
//         }
// 
//         @Override
//         public Joke[] newArray(int size) {
//             return new Joke[size];
//         }
//     };
// }
// 
// Path: app/src/main/java/com/github/blazsolar/chuck/data/api/model/Response.java
// public class Response<T> {
// 
//     private String type;
//     private T value;
// 
//     public Response() {
//     }
// 
//     public Response(T value) {
//         this.value = value;
//     }
// 
//     public T getValue() {
//         return value;
//     }
// }
// 
// Path: app/src/main/java/com/github/blazsolar/chuck/data/rx/EndObserver.java
// public abstract class EndObserver<T> implements Observer<T> {
// 
//     @Override
//     public void onCompleted() {
//         onEnd();
//     }
// 
//     @Override
//     public void onError(Throwable e) {
//         onEnd();
//     }
// 
//     public abstract void onEnd();
// }


import java.io.IOException;
import javax.inject.Inject;
import rx.Observable;
import rx.Observer;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;
import rx.subjects.PublishSubject;
import com.github.blazsolar.chuck.data.api.JokesService;
import com.github.blazsolar.chuck.data.api.model.Joke;
import com.github.blazsolar.chuck.data.api.model.Response;
import com.github.blazsolar.chuck.data.rx.EndObserver;
package com.github.blazsolar.chuck.data;




/**
 * Created by Blaz Solar on 23/08/14.
 */
public class JokesDatabase {

    private JokesService mJokesService;

    private PublishSubject<Joke> mJokeRequest;

    @Inject public JokesDatabase(JokesService jokesService) {
        mJokesService = jokesService;
    }

    public Subscription loadJoke(Observer<Joke> observer) {

        if (mJokeRequest != null) {
            // There is already request in progress. Joint it.
            return mJokeRequest.subscribe(observer);
        }

        mJokeRequest = PublishSubject.create();

        Subscription subscription = mJokeRequest.subscribe(observer);

        mJokeRequest.subscribe(new EndObserver<Joke>() {

            @Override
            public void onEnd() {
                mJokeRequest = null;
            }

            @Override
            public void onNext(Joke joke) {
                // do nothing
            }
        });

        mJokesService.randomJoke()
                .flatMap(new Func1<Response<Joke>, Observable<Joke>>() {
                    @Override
                    public Observable<Joke> call(Response<Joke> jokeResponse) {
                        if (jokeResponse != null && jokeResponse.getValue() != null) {
                            return Observable.just(jokeResponse.getValue());
                        } else {
// Path: app/src/main/java/com/github/blazsolar/chuck/data/api/JokesService.java
// public interface JokesService {
// 
//     @GET("/jokes/random")
//     Observable<Response<Joke>> randomJoke();
// 
// }
// 
// Path: app/src/main/java/com/github/blazsolar/chuck/data/api/model/Joke.java
// public class Joke implements Parcelable {
// 
//     private long id;
//     private String joke;
//     private String[] categories;
// 
//     public Joke() {
//     }
// 
//     public Joke(long id, String joke, String[] categories) {
//         this.id = id;
//         this.joke = joke;
//         this.categories = categories;
//     }
// 
//     private Joke(Parcel in) {
//         id = in.readLong();
//         joke = in.readString();
// 
//         int cnt = in.readInt();
//         if (cnt > -1) {
//             categories = new String[cnt];
//             in.readStringArray(categories);
//         }
//     }
// 
//     public long getId() {
//         return id;
//     }
// 
//     public String getJoke() {
//         return joke;
//     }
// 
//     public String[] getCategories() {
//         return categories;
//     }
// 
//     @Override
//     public int describeContents() {
//         return 0;
//     }
// 
//     @Override
//     public void writeToParcel(Parcel dest, int flags) {
//         dest.writeLong(id);
//         dest.writeString(joke);
// 
//         if (categories != null) {
//             dest.writeInt(categories.length);
//             dest.writeStringArray(categories);
//         } else {
//             dest.writeInt(-1);
//         }
//     }
// 
//     public static final Creator<Joke> CREATOR = new Creator<Joke>() {
// 
//         @Override
//         public Joke createFromParcel(Parcel source) {
//             return new Joke(source);
//         }
// 
//         @Override
//         public Joke[] newArray(int size) {
//             return new Joke[size];
//         }
//     };
// }
// 
// Path: app/src/main/java/com/github/blazsolar/chuck/data/api/model/Response.java
// public class Response<T> {
// 
//     private String type;
//     private T value;
// 
//     public Response() {
//     }
// 
//     public Response(T value) {
//         this.value = value;
//     }
// 
//     public T getValue() {
//         return value;
//     }
// }
// 
// Path: app/src/main/java/com/github/blazsolar/chuck/data/rx/EndObserver.java
// public abstract class EndObserver<T> implements Observer<T> {
// 
//     @Override
//     public void onCompleted() {
//         onEnd();
//     }
// 
//     @Override
//     public void onError(Throwable e) {
//         onEnd();
//     }
// 
//     public abstract void onEnd();
// }


// Path: app/src/main/java/com/github/blazsolar/chuck/data/JokesDatabase.java
import java.io.IOException;
import javax.inject.Inject;
import rx.Observable;
import rx.Observer;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;
import rx.subjects.PublishSubject;
import com.github.blazsolar.chuck.data.api.JokesService;
import com.github.blazsolar.chuck.data.api.model.Joke;
import com.github.blazsolar.chuck.data.api.model.Response;
import com.github.blazsolar.chuck.data.rx.EndObserver;

package com.github.blazsolar.chuck.data;




/**
 * Created by Blaz Solar on 23/08/14.
 */
public class JokesDatabase {

    private JokesService mJokesService;

    private PublishSubject<Joke> mJokeRequest;

    @Inject public JokesDatabase(JokesService jokesService) {
        mJokesService = jokesService;
    }

    public Subscription loadJoke(Observer<Joke> observer) {

        if (mJokeRequest != null) {
            // There is already request in progress. Joint it.
            return mJokeRequest.subscribe(observer);
        }

        mJokeRequest = PublishSubject.create();

        Subscription subscription = mJokeRequest.subscribe(observer);

        mJokeRequest.subscribe(new EndObserver<Joke>() {

            @Override
            public void onEnd() {
                mJokeRequest = null;
            }

            @Override
            public void onNext(Joke joke) {
                // do nothing
            }
        });

        mJokesService.randomJoke()
                .flatMap(new Func1<Response<Joke>, Observable<Joke>>() {
                    @Override
                    public Observable<Joke> call(Response<Joke> jokeResponse) {
                        if (jokeResponse != null && jokeResponse.getValue() != null) {
                            return Observable.just(jokeResponse.getValue());
                        } else {
                            return Observable.error(new IOException("Empty value"));