public enum EventCatalog {
    // Event 0000: List Characters
    e0000("e0000"),
    // Event 0001: List Comic Details
    e0001("e0001"),
    // Event 0002: Search character
    e0002("e0002");

    private String mValue;

    EventCatalog(String status) {
        this.mValue = status;
    }

    public static EventCatalog fromString(String value) {
        if (value != null) {
            for (EventCatalog b : EventCatalog.values()) {
                if (value.equalsIgnoreCase(b.mValue)) {
                    return b;
                }
            }
        }
        return null;
    }

    @Override
    public String toString() {
        if (this.mValue == null) {
            return "";
        }
        return this.mValue;
    }
} public interface TaskExecutor {
    public void executeOnSuccessTask(Object payload);

    public void executeOnErrorTask(Object payload);
} public class Item implements Serializable {

    private String resourceURI;
    private String name;
    private String thumbnailUrl;

    public String getResourceURI() {
        return resourceURI;
    }

    public void setResourceURI(String resourceURI) {
        this.resourceURI = resourceURI;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getThumbnailUrl() {
        return this.thumbnailUrl;
    }

    public void setThumbnailUrl(String thumbnailUrl) {
        this.thumbnailUrl = thumbnailUrl;
    }
} public class NotificationCenter {

    public static final String TAG = "NotificationCenter";

    // Event 0000: Get GCM Token
    private static Set<TaskExecutor> mSubEvent0000 = new HashSet<>();
    // Event 0001: List Comic Details
    private static Set<TaskExecutor> mSubEvent0001 = new HashSet<>();
    // Event 0002: Search character
    private static Set<TaskExecutor> mSubEvent0002 = new HashSet<>();

    public static void notify(EventCatalog event, ResponseWrapper response) {
        for (TaskExecutor tasker : NotificationCenter.getSubscriberList(event)) {
            switch (response.getType()) {
                case SUCCESS:
                    tasker.executeOnSuccessTask(response.getPayload());
                    break;
                case ERROR:
                    tasker.executeOnErrorTask(response.getPayload());
                    break;
            }
        }
    }

    public static class RegistrationCenter {
        public static void registerForEvent(EventCatalog event, TaskExecutor subscriber) {
            NotificationCenter.getSubscriberList(event).add(subscriber);
        }

        public static void unregisterForEvent(EventCatalog event, TaskExecutor subscriber) {
            NotificationCenter.getSubscriberList(event).remove(subscriber);
        }
    }

    private static Set<TaskExecutor> getSubscriberList(EventCatalog event) {
        switch (event) {
            case e0000:
                return NotificationCenter.mSubEvent0000;
            case e0001:
                return NotificationCenter.mSubEvent0001;
            case e0002:
                return NotificationCenter.mSubEvent0002;
        }
        return null;
    }
} public class Postman {

    public static final String TAG = "Postman";

    @Inject
    RestTemplate mRequestService;
    @Inject
    RequestUtil mRequestUtil;

    public Postman() {
        DaggerWrapper.getComponent().inject(this);
    }

    public void listCharacters(Context context, String query, int limit, int offset) {
        this.mRequestService.setUrl(mRequestUtil.buildBasicUrl(context, context.getString(R.string.MARVEL_SERVICE_LIST_CHARACTERS), query, limit, offset));
        this.mRequestService.setBody(EventCatalog.e0000, Request.Method.GET);
        this.mRequestService.execute(context);
    }

    public void listComicDetails(String resourceURI, Context context) {
        if (!"".equals(resourceURI) && context != null) {
            this.mRequestService.setUrl(this.mRequestUtil.parseExistentRequest(resourceURI, context));
            this.mRequestService.setBody(EventCatalog.e0001, Request.Method.GET);
            this.mRequestService.execute(context);
        }
    }

    public void cancelRequests() {
        mRequestService.cancelRequests();
    }
} public class MarvelRequestParser {

    public static String getItemThumbnailUrl(JSONObject object) throws JSONException {
        Gson gson = new Gson();
        return gson.fromJson(((JSONObject) object.getJSONObject("data").getJSONArray("results").get(0)).getJSONObject("thumbnail").toString(), Thumbnail.class).getUrl();
    }

    public static String getResourceUri(JSONObject object) throws JSONException {
        return ((JSONObject) object.getJSONObject("data").getJSONArray("results").get(0)).getString("resourceURI");
    }

    public static String getName(JSONObject object) throws JSONException {
        return ((JSONObject) object.getJSONObject("data").getJSONArray("results").get(0)).getString("name");
    }

    public static String getTitle(JSONObject object) throws JSONException {
        return ((JSONObject) object.getJSONObject("data").getJSONArray("results").get(0)).getString("title");
    }

} public enum LayoutType {

    SMALL_VERTICAL(0),
    LARGE_VERTICAL(1),
    SMALL_HORIZONTAL(2),
    LARGE_HORIZONTAL(3);

    private int mValue;

    LayoutType(int value) {
        this.mValue = value;
    }

    public static LayoutType fromInteger(int value) {
        for (LayoutType b : LayoutType.values()) {
            if (value == b.mValue) {
                return b;
            }
        }
        return null;
    }

    public int toInteger() {
        return this.mValue;
    }
} public class ImageWarehouse implements Callback {

    private static final String TAG = "ImageWarehouse";

    private String mDirectory;
    private String mFileName;
    private ImageView mContainer;
    @Inject
    App mApplication;

    public ImageWarehouse(String fileName, ImageView container, String directory) {
        this.mFileName = fileName;
        this.mContainer = container;
        this.mDirectory = directory;
        this.getStorageDir();
    }

    @Override
    public void onSuccess() {
        if (this.isExternalStorageWritable()) {
            final Bitmap bitmap = ((BitmapDrawable) this.mContainer.getDrawable()).getBitmap();
            new AsyncTask<Void, Void, File>() {
                @Override
                protected File doInBackground(Void... params) {
                    File file = null;
                    try {
                        file = new File(ImageWarehouse.this.getStorageDir().getPath().concat("/").concat(ImageWarehouse.this.mFileName.concat(Constants.MEDIA_EXTENSION)));
                        file.createNewFile();
                        FileOutputStream ostream = new FileOutputStream(file);
                        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, ostream);
                        ostream.close();
                    } catch (Exception e) {
                        Log.e(TAG, "External Storage is not available");
                    }
                    return file;
                }
            }.execute();
        } else {
            Log.e(TAG, "External Storage is not available");
        }
    }

    @Override
    public void onError() {

    }

    public boolean isExternalStorageWritable() {
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            return true;
        }
        return false;
    }

    public File getStorageDir() {
        File file = new File(Environment.getExternalStorageDirectory(), Constants.MEDIA_DIRECTORY.concat(this.mDirectory));
        if (!file.mkdirs()) {
        }
        return file;
    }
} public class StaticResourceProvider {

    @Inject
    App mApplication;

    public StaticResourceProvider() {
        App.getComponent().inject(this);
    }

    public Picasso getPicasso() {
        return Picasso.with(this.mApplication.getContext());
    }

    public MaterialDialog.Builder getDialogBuilder(Context context) {
        return new MaterialDialog.Builder(context);
    }
} public interface Publisher {

    public void registerSubscriber(Subscriber subscriber);
    public void removeSubscriber(Subscriber subscriber);
    public void notifyEvent(Object... params);

} public interface Subscriber {

    public void onEventListener(Object... params);

} public class App extends Application {

    private static App mApp = null;
    private static MainComponent component;

    @Override
    public void onCreate() {
        super.onCreate();
        this.mApp = this;
        this.component = DaggerMainComponent
                .builder()
                .moduleUtil(new ModuleUtil(this))
                .build();
    }

    public static Application getApplication() {
        return mApp;
    }

    public Context getContext() {
        if (mApp == null) {
            return new Application();
        }
        return mApp.getApplicationContext();
    }

    public static MainComponent getComponent() {
        return component;
    }
} public class Constants {

    public static final String MEDIA_DIRECTORY = "/Marvel/Media/";
    public static final String MEDIA_CHARACTER= "Characters/";
    public static final String MEDIA_COLLECTIONS= "Collections/";
    public static final String MEDIA_EXTENSION = ".jpeg";

    public static class ActivityCommunication {
        public static final String ACTCOMM_CHARACTER = "ACTCOMMCHARACTER";
        public static final String ACTCOMM_COLLECTIONS = "ACTCOMMCOLLECTIONS";
        public static final String ACTCOMM_COLLECTIONS_STARTPOSITION = "ACTCOMMCOLLECTIONSSTARTPOSITION";
    }

}
import android.os.Environment;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import org.json.JSONObject;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import br.com.hole19.marvel.R;
import br.com.hole19.marvel.comm.model.EventCatalog;
import br.com.hole19.marvel.comm.model.TaskExecutor;
import br.com.hole19.marvel.comm.model.marvel.Item;
import br.com.hole19.marvel.comm.post_office.NotificationCenter;
import br.com.hole19.marvel.comm.post_office.Postman;
import br.com.hole19.marvel.comm.util.MarvelRequestParser;
import br.com.hole19.marvel.ui.commons.model.LayoutType;
import br.com.hole19.marvel.ui.commons.util.ImageWarehouse;
import br.com.hole19.marvel.ui.commons.util.StaticResourceProvider;
import br.com.hole19.marvel.ui.commons.util.patterns.Publisher;
import br.com.hole19.marvel.ui.commons.util.patterns.Subscriber;
import br.com.hole19.marvel.ui.infrastructure.App;
import br.com.hole19.marvel.ui.infrastructure.Constants;
package br.com.hole19.marvel.ui.commons.adapter;






/**
 * Created by edgar on 29-Apr-16.
 */
public class AdapterItem extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Publisher {

    private static final String TAG = "AdapterItem";
    private static final int MAX_THREADS = 10;
    private static int THREAD_NUMBER = 0;

    private List<Item> mDataSet;

    private List<ViewHolder.ItemViewHolder> mHolders = new ArrayList<>();
    private Map<String, ViewHolder.ItemViewHolder> mURIViewHolder;
    private LayoutType mViewType;
    @Inject
    ViewHolderFactory mViewHolderFactory;
    @Inject
    StaticResourceProvider resourceManager;