// Path: app/src/main/java/br/com/catbag/gifreduxsample/actions/GifActionCreator.java
// public final class GifActionCreator extends BaseActionCreator {
//     public static final String GIF_PLAY = "GIF_PLAY";
//     public static final String GIF_PAUSE = "GIF_PAUSE";
//     public static final String GIF_DOWNLOAD_SUCCESS = "GIF_DOWNLOAD_SUCCESS";
//     public static final String GIF_DOWNLOAD_FAILURE = "GIF_DOWNLOAD_FAILURE";
//     public static final String GIF_DOWNLOAD_START = "GIF_DOWNLOAD_START";
// 
//     private static GifActionCreator sInstance;
// 
//     private GifActionCreator() {
//         MyApp.getFluxxan().inject(this);
//     }
// 
//     public static GifActionCreator getInstance() {
//         if (sInstance == null) {
//             sInstance = new GifActionCreator();
//         }
//         return sInstance;
//     }
// 
//     public void gifDownloadStart(Gif gif) {
//         dispatch(new Action(GIF_DOWNLOAD_START, gif.getUuid()));
//     }
// 
//     public void gifClick(Gif gif) {
//         if (gif.getStatus() == Gif.Status.DOWNLOADED || gif.getStatus() == Gif
//                 .Status.PAUSED) {
//             gifPlay(gif.getUuid());
//         } else if (gif.getStatus() == Gif.Status.LOOPING) {
//             gifPause(gif.getUuid());
//         }
//     }
// 
//     private void gifPlay(String uuid) {
//         dispatch(new Action(GIF_PLAY, uuid));
//     }
// 
//     private void gifPause(String uuid) {
//         dispatch(new Action(GIF_PAUSE, uuid));
//     }
// }
// 
// Path: app/src/main/java/br/com/catbag/gifreduxsample/models/AppState.java
// @SuppressWarnings("PMD.BooleanGetMethodName")
// @Value.Immutable
// @JsonSerialize(as = ImmutableAppState.class)
// @JsonDeserialize(as = ImmutableAppState.class)
// public abstract class AppState {
// 
//     @Value.Default
//     public Map<String, Gif> getGifs() {
//         return new LinkedHashMap<>();
//     }
// 
//     @Value.Default
//     public boolean getHasMoreGifs() {
//         return true;
//     }
// 
//     public String toJson() throws JsonProcessingException {
//         return new ObjectMapper().writeValueAsString(this);
//     }
// 
//     public static AppState fromJson(String json) throws IOException {
//         ObjectMapper mapper = new ObjectMapper();
//         mapper.registerModule(new GuavaModule());
//         return mapper.readValue(json, AppState.class);
//     }
// 
// }
// 
// Path: app/src/main/java/br/com/catbag/gifreduxsample/models/Gif.java
// @SuppressWarnings("PMD.BooleanGetMethodName")
// @Value.Immutable
// @JsonSerialize(as = ImmutableGif.class)
// @JsonDeserialize(as = ImmutableGif.class)
// public abstract class Gif {
// 
//     public enum Status {
//         PAUSED, LOOPING, DOWNLOADING, DOWNLOADED, NOT_DOWNLOADED, DOWNLOAD_FAILED
//     }
// 
//     //abstract method are immutable by default
//     public abstract String getUuid();
// 
//     @Value.Default
//     public String getPath() {
//         return "";
//     }
// 
//     public abstract String getUrl();
//     
//     public abstract String getTitle();
// 
//     @Value.Default
//     public boolean getWatched() {
//         return false;
//     }
// 
//     @Value.Default
//     public Status getStatus() {
//         return Status.NOT_DOWNLOADED;
//     }
// 
//     public String toJson() throws JsonProcessingException {
//         return new ObjectMapper().writeValueAsString(this);
//     }
// 
//     public static Gif fromJson(String json) throws IOException {
//         return new ObjectMapper().readValue(json, Gif.class);
//     }
// 
// }


import android.content.Context;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import br.com.catbag.gifreduxsample.R;
import br.com.catbag.gifreduxsample.actions.GifActionCreator;
import br.com.catbag.gifreduxsample.models.AppState;
import br.com.catbag.gifreduxsample.models.Gif;
import br.com.catbag.gifreduxsample.models.ImmutableGif;
import pl.droidsonroids.gif.GifDrawable;
import static br.com.catbag.gifreduxsample.models.Gif.Status.DOWNLOADING;
import static br.com.catbag.gifreduxsample.models.Gif.Status.DOWNLOAD_FAILED;
import static br.com.catbag.gifreduxsample.models.Gif.Status.LOOPING;
import static br.com.catbag.gifreduxsample.models.Gif.Status.NOT_DOWNLOADED;
import static trikita.anvil.BaseDSL.visibility;
import static trikita.anvil.BaseDSL.withId;
import static trikita.anvil.BaseDSL.xml;
import static trikita.anvil.DSL.backgroundColor;
import static trikita.anvil.DSL.imageDrawable;
import static trikita.anvil.DSL.onClick;
    @Override
    public boolean hasStateChanged(AppState newState, AppState oldState) {
        Gif newGif = newState.getGifs().get(mGif.getUuid());
        return newGif != null && !newGif.equals(mGif);
    }

    @Override
    public void onStateChanged(AppState appState) {
        withGif(appState.getGifs().get(mGif.getUuid()));

        if (mGif.getStatus() == DOWNLOAD_FAILED) {
            mHasRequestedDownload = false;
        }
    }

    @Override
    protected void initialState() {
        super.initialState();
        mGif = ImmutableGif.builder().url("").path("").title("").uuid("")
                .build();
    }

    private void setBackground() {
        if (mGif.getStatus() == DOWNLOAD_FAILED) {
            backgroundColor(ContextCompat.getColor(getContext(), R.color.error));
            return;
        }

        if (mGif.getWatched()) {
            backgroundColor(ContextCompat.getColor(getContext(), R.color.watched));
// Path: app/src/main/java/br/com/catbag/gifreduxsample/actions/GifActionCreator.java
// public final class GifActionCreator extends BaseActionCreator {
//     public static final String GIF_PLAY = "GIF_PLAY";
//     public static final String GIF_PAUSE = "GIF_PAUSE";
//     public static final String GIF_DOWNLOAD_SUCCESS = "GIF_DOWNLOAD_SUCCESS";
//     public static final String GIF_DOWNLOAD_FAILURE = "GIF_DOWNLOAD_FAILURE";
//     public static final String GIF_DOWNLOAD_START = "GIF_DOWNLOAD_START";
// 
//     private static GifActionCreator sInstance;
// 
//     private GifActionCreator() {
//         MyApp.getFluxxan().inject(this);
//     }
// 
//     public static GifActionCreator getInstance() {
//         if (sInstance == null) {
//             sInstance = new GifActionCreator();
//         }
//         return sInstance;
//     }
// 
//     public void gifDownloadStart(Gif gif) {
//         dispatch(new Action(GIF_DOWNLOAD_START, gif.getUuid()));
//     }
// 
//     public void gifClick(Gif gif) {
//         if (gif.getStatus() == Gif.Status.DOWNLOADED || gif.getStatus() == Gif
//                 .Status.PAUSED) {
//             gifPlay(gif.getUuid());
//         } else if (gif.getStatus() == Gif.Status.LOOPING) {
//             gifPause(gif.getUuid());
//         }
//     }
// 
//     private void gifPlay(String uuid) {
//         dispatch(new Action(GIF_PLAY, uuid));
//     }
// 
//     private void gifPause(String uuid) {
//         dispatch(new Action(GIF_PAUSE, uuid));
//     }
// }
// 
// Path: app/src/main/java/br/com/catbag/gifreduxsample/models/AppState.java
// @SuppressWarnings("PMD.BooleanGetMethodName")
// @Value.Immutable
// @JsonSerialize(as = ImmutableAppState.class)
// @JsonDeserialize(as = ImmutableAppState.class)
// public abstract class AppState {
// 
//     @Value.Default
//     public Map<String, Gif> getGifs() {
//         return new LinkedHashMap<>();
//     }
// 
//     @Value.Default
//     public boolean getHasMoreGifs() {
//         return true;
//     }
// 
//     public String toJson() throws JsonProcessingException {
//         return new ObjectMapper().writeValueAsString(this);
//     }
// 
//     public static AppState fromJson(String json) throws IOException {
//         ObjectMapper mapper = new ObjectMapper();
//         mapper.registerModule(new GuavaModule());
//         return mapper.readValue(json, AppState.class);
//     }
// 
// }
// 
// Path: app/src/main/java/br/com/catbag/gifreduxsample/models/Gif.java
// @SuppressWarnings("PMD.BooleanGetMethodName")
// @Value.Immutable
// @JsonSerialize(as = ImmutableGif.class)
// @JsonDeserialize(as = ImmutableGif.class)
// public abstract class Gif {
// 
//     public enum Status {
//         PAUSED, LOOPING, DOWNLOADING, DOWNLOADED, NOT_DOWNLOADED, DOWNLOAD_FAILED
//     }
// 
//     //abstract method are immutable by default
//     public abstract String getUuid();
// 
//     @Value.Default
//     public String getPath() {
//         return "";
//     }
// 
//     public abstract String getUrl();
//     
//     public abstract String getTitle();
// 
//     @Value.Default
//     public boolean getWatched() {
//         return false;
//     }
// 
//     @Value.Default
//     public Status getStatus() {
//         return Status.NOT_DOWNLOADED;
//     }
// 
//     public String toJson() throws JsonProcessingException {
//         return new ObjectMapper().writeValueAsString(this);
//     }
// 
//     public static Gif fromJson(String json) throws IOException {
//         return new ObjectMapper().readValue(json, Gif.class);
//     }
// 
// }


// Path: app/src/main/java/br/com/catbag/gifreduxsample/ui/views/GifView.java
import android.content.Context;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import br.com.catbag.gifreduxsample.R;
import br.com.catbag.gifreduxsample.actions.GifActionCreator;
import br.com.catbag.gifreduxsample.models.AppState;
import br.com.catbag.gifreduxsample.models.Gif;
import br.com.catbag.gifreduxsample.models.ImmutableGif;
import pl.droidsonroids.gif.GifDrawable;
import static br.com.catbag.gifreduxsample.models.Gif.Status.DOWNLOADING;
import static br.com.catbag.gifreduxsample.models.Gif.Status.DOWNLOAD_FAILED;
import static br.com.catbag.gifreduxsample.models.Gif.Status.LOOPING;
import static br.com.catbag.gifreduxsample.models.Gif.Status.NOT_DOWNLOADED;
import static trikita.anvil.BaseDSL.visibility;
import static trikita.anvil.BaseDSL.withId;
import static trikita.anvil.BaseDSL.xml;
import static trikita.anvil.DSL.backgroundColor;
import static trikita.anvil.DSL.imageDrawable;
import static trikita.anvil.DSL.onClick;

    @Override
    public boolean hasStateChanged(AppState newState, AppState oldState) {
        Gif newGif = newState.getGifs().get(mGif.getUuid());
        return newGif != null && !newGif.equals(mGif);
    }

    @Override
    public void onStateChanged(AppState appState) {
        withGif(appState.getGifs().get(mGif.getUuid()));

        if (mGif.getStatus() == DOWNLOAD_FAILED) {
            mHasRequestedDownload = false;
        }
    }

    @Override
    protected void initialState() {
        super.initialState();
        mGif = ImmutableGif.builder().url("").path("").title("").uuid("")
                .build();
    }

    private void setBackground() {
        if (mGif.getStatus() == DOWNLOAD_FAILED) {
            backgroundColor(ContextCompat.getColor(getContext(), R.color.error));
            return;
        }

        if (mGif.getWatched()) {
            backgroundColor(ContextCompat.getColor(getContext(), R.color.watched));
        } else {