public class Constants {

    public static final String SPACE = " ";
    public static final String COMMA = ",";
    public static final String CR = "\n";
    public static final String EMPTY_STRING = "";
    public static final String SEMI_COLON=":";
    public static final int BOTTOM_NAVIGATION_HEIGHT=168;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({SCROLL_DOWN, SCROLL_UP})
    public @interface ScrollDirection {
    }

    public static final int SCROLL_DOWN = 0;
    public static final int SCROLL_UP = 1;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({MAP_TAB,FAVORITE})
    public @interface LayoutType {
    }

    public static final int MAP_TAB = 0;
    public static final int FAVORITE = 1;
} public class Utils {

    private static final String LOG_TAG = Utils.class.getSimpleName();

    static int screenHeight = 0;
    static int oldStatusBarFlags;

    public static void logD(final String tag, String message) {
        if (BuildConfig.DEBUG) {
            Log.d(tag, message);
        }
    }

    // http://stackoverflow.com/questions/8710719/generating-an-alphabetic-sequence-in-java
    public static String characterFromInteger(int i) {
        return i < 0 ? "" : characterFromInteger((i / 26) - 1) + (char) (65 + i % 26);
    }

    public void navigateTo() {

    }

    public static CustomSupporMapFragment handleMapFragmentRecreation(FragmentManager fragmentManager, int fragmentId,
                                                                      String fragmentTag) {
        CustomSupporMapFragment mapFragment = (CustomSupporMapFragment) fragmentManager.findFragmentByTag("mapFragment");
        if (mapFragment == null) {
            mapFragment = new CustomSupporMapFragment();
            fragmentManager.beginTransaction()
                    .replace(R.id.mapFragmentContainer, mapFragment, fragmentTag)
                    .commit();
            fragmentManager.executePendingTransactions();

        }
        return mapFragment;
    }

    //  address, postalCode City, Province
    public static String formatAddress(String address, String postalCode, String city, String province) {

        return address
                + Constants.COMMA + Constants.SPACE + postalCode + Constants.SPACE + city
                + Constants.COMMA + Constants.SPACE + province;
    }

    public static String formatPhoneNumber(String phoneNumber) {

        return phoneNumber.substring(0, 3) + Constants.SPACE + phoneNumber.substring(3, 5)
                + Constants.SPACE + phoneNumber.substring(5, 7)
                + Constants.SPACE + phoneNumber.substring(7, 9);


    }

    public static float convertDpToPixel(float dp, Context context) {
        Resources resources = context.getResources();
        DisplayMetrics metrics = resources.getDisplayMetrics();
        float px = dp * ((float) metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT);
        return px;
    }

    public static double meterDistanceBetweenPoints(double lat_a, double lng_a, double lat_b, double lng_b) {
        float pk = (float) (180.f / Math.PI);

        double a1 = lat_a / pk;
        double a2 = lng_a / pk;
        double b1 = lat_b / pk;
        double b2 = lng_b / pk;

        double t1 = Math.cos(a1) * Math.cos(a2) * Math.cos(b1) * Math.cos(b2);
        double t2 = Math.cos(a1) * Math.sin(a2) * Math.cos(b1) * Math.sin(b2);
        double t3 = Math.sin(a1) * Math.sin(b1);
        double tt = Math.acos(t1 + t2 + t3);

        return 6366000 * tt;
    }

    public static Calendar buildCalendar(Date date, int hour, int minute) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
        return calendar;
    }

    public static boolean is24HoursPharmacy(String hours) {

        if (hours == null) return false;
        return hours.equals("24H");
    }

    public static boolean isPharmacyOpen(String hours) {
        Date now = new Date();
        Calendar date = Calendar.getInstance();
        date.setTime(now);
        int day = date.get(Calendar.DAY_OF_WEEK);

        if (hours.equals("24H")) {
            return true;
        } else if (Calendar.SATURDAY == day) {
            Calendar morningOpen = buildCalendar(now, 9, 0);
            Calendar morningClose = buildCalendar(now, 14, 0);
            if (date.after(morningOpen) && date.before(morningClose)) {
                return true;
            }
            return false;

        } else if (Calendar.SUNDAY == day) {
            return false;
        } else {
            Calendar morningOpen = buildCalendar(now, 9, 0);
            Calendar morningClose = buildCalendar(now, 14, 0);
            Calendar eveningOpen = buildCalendar(now, 16, 30);
            Calendar eveningClose = buildCalendar(now, 20, 30);
            if ((date.after(morningOpen) && date.before(morningClose))
                    || (date.after(eveningOpen) && date.before(eveningClose))) {
                return true;
            }
            return false;

        }

    }

    public static Intent startPhoneIntent(Context context, String telephone) {
        String uri = "tel:" + telephone;
        ;
        Intent intent = new Intent(Intent.ACTION_DIAL);
        intent.setData(Uri.parse(uri));
        return intent;
    }

    public static Intent getShareIntent(String name, double dist, String aformatted, String tel) {
        Context context = MyApplication.getContext();
        final String nombre = context.getString(R.string.shared_intent_text_farmacia);
        final String distancia = context.getString(R.string.shared_intent_text_distancia);;
        final String direccion = context.getString(R.string.shared_intent_text_direccion);;
        final String telefono = context.getString(R.string.shared_intent_text_tef);;

        String textToShare = nombre + name + Constants.CR
                + distancia + context.getString(R.string.format_distance, dist/1000) + Constants.CR
                + direccion + aformatted + Constants.CR
                + telefono + tel;

        Intent sendIntent = new Intent();
        sendIntent.setAction(Intent.ACTION_SEND);
        sendIntent.putExtra(Intent.EXTRA_TEXT, textToShare);
        sendIntent.setType("text/plain");
        return sendIntent;

    }

    public static Intent getGoodleDirectionsIntent(LatLng sourceLatLng,
                                                   String sourceAddress,
                                                   LatLng destinationLatLng,
                                                   String destinationAddress) {

        String uri = String.format(Locale.ENGLISH, "http://maps.google.com/maps?saddr=%f,%f(%s)&daddr=%f,%f (%s)",
                sourceLatLng.latitude, sourceLatLng.longitude, sourceAddress,
                destinationLatLng.latitude, destinationLatLng.longitude, destinationAddress);
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
        intent.setClassName("com.google.android.apps.maps", "com.google.android.maps.MapsActivity");
        return intent;
    }

    public static Bitmap getBitmapFromVectorDrawable(Context context, @DrawableRes int drawableResId) {


        Drawable drawable = VectorDrawableCompat.create(context.getResources(), drawableResId, null);
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        Bitmap bitmap = BitmapUtil.toBitmap(drawable, metrics, 48f, 0);
        return bitmap;
    }

    public static Bitmap createScaledBitMapFromVectorDrawable(Context context, VectorDrawableCompat vd, float dimension) {
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        return BitmapUtil.toBitmap(vd, metrics, dimension, 0);


    }

    public static int getDefaultBitmapTextSize() {

        Context context = MyApplication.getContext();
        float scale = context.getResources().getDisplayMetrics().density;
        return (int) (14 * scale);
    }


    public static int getColor(@ColorRes int resId) {

        int color = ContextCompat.getColor(MyApplication.getContext(), resId);
        return color;
    }

    public static boolean isEmptyRequest(String[] selectionArgs) {
        if (selectionArgs[0].replaceAll("\\%", "").equals("")) {
            return true;
        }
        return false;
    }

    /**
     * Called on dismiss in favorite fragment
     *
     * @param phone
     * @return
     */
    public static int changeFavoriteInDb(String phone) {
        Context context = MyApplication.getContext();
        Uri uri = DbContract.FarmaciasEntity.buildFavoritesUriByPhone(phone);
        ContentValues contentValues = new ContentValues();
        contentValues.put(DbContract.FarmaciasEntity.FAVORITE, 0);
        int rowsUpdated = context.getContentResolver().update(uri, contentValues,
                DbContract.FarmaciasEntity.PHONE + " LIKE '%" + phone + "%'",
                null);
        if (rowsUpdated == 1) {
            Utils.logD("changeFavoriteinDb", "rows updates: " + rowsUpdated);

        }
        return rowsUpdated;
    }

    public static String changeFavoriteInDb(boolean oldFavoriteValue, String phone) {
        String snackMessage;
        Context context = MyApplication.getContext();
        if (oldFavoriteValue) {
            snackMessage = context.getString(R.string.ltf_removed_from_favorite);

        } else {
            snackMessage = context.getString(R.string.ltf_added_to_favorite);

        }
        final boolean newFavoriteValue = !oldFavoriteValue;
        Uri uri = DbContract.FarmaciasEntity.buildFarmaciasUriByPhone(phone);
        ContentValues contentValues = new ContentValues();
        contentValues.put(DbContract.FarmaciasEntity.FAVORITE, newFavoriteValue);

//        int rowsUpdated = context.getContentResolver().update(uri, contentValues,
//                DbContract.FarmaciasEntity.PHONE + " LIKE '%" + phone + "%'",
//                null);

        int rowsUpdated = context.getContentResolver().update(uri, contentValues,
                DbContract.FarmaciasEntity.PHONE + " LIKE ? ",
                new String[]{"%" + phone + "%"});

        if (rowsUpdated == 1) {
            Utils.logD("changeFavoriteinDb", "rows updates: " + rowsUpdated);
            return snackMessage;
        }
        return null;


    }

    public static int getScreenHeight(Context c) {

        if (screenHeight == 0) {
            WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
            Display display = wm.getDefaultDisplay();
            Point size = new Point();
            display.getSize(size);
            screenHeight = size.y;
        }

        return screenHeight;
    }

     public static void setLightStatusBar(View view, Activity activity) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            View decor = activity.getWindow().getDecorView();
            oldStatusBarFlags = decor.getSystemUiVisibility();
            int flags = view.getSystemUiVisibility();
            flags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
            view.setSystemUiVisibility(flags);
            activity.getWindow().setStatusBarColor(Color.WHITE);
        }


    }

    //the view used in setting the light status bar needs to dissapear so that the changes takes effect.
    public static void clearLightStatusBar(Activity activity) {


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            View decor = activity.getWindow().getDecorView();
            decor.setSystemUiVisibility(oldStatusBarFlags);
            Window window = activity.getWindow();
            window.setStatusBarColor(ContextCompat.getColor(activity, R.color.colorPrimaryDark));


        }
    }

    //works for changing only the colors of the icons in status bar, the view doesn't need to dissapear from screen
    public static void clearNick(View view) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            int flags = view.getSystemUiVisibility();
            flags &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
            view.setSystemUiVisibility(flags);
        }
    }

    //extracted from materials-intro, not working as expected
    public static void anotherMethod(Activity activity, View someView) {
//        int systemUiVisibility =activity.getWindow().getDecorView().getSystemUiVisibility();
//        int flagLightStatusBar = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
//        if (flag) {
//            //Light background
//            systemUiVisibility |= flagLightStatusBar;
//        } else {
//            //Dark background
//            systemUiVisibility &= ~flagLightStatusBar;
//        }
//        activity.getWindow().getDecorView().setSystemUiVisibility(systemUiVisibility);
        //  someView.setSystemUiVisibility(0); not working
        //  rootView.setSystemUiVisibility(rootView.getSystemUiVisibility() & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); not working
//        View decorView = activity.getWindow().getDecorView();
//        int uiOptions = View.SYSTEM_UI_FLAG_LOW_PROFILE;
//        decorView.setSystemUiVisibility(uiOptions);
//        Window window = activity.getWindow();
//        window.setStatusBarColor(ContextCompat.getColor(activity,R.color.colorPrimaryDark));
//
//// Calling setSystemUiVisibility() with a value of 0 clears
//// all flags.
//        decorView.setSystemUiVisibility(0);


    }


    public static boolean contains(LatLng location, ArrayList<LatLng> polyLoc) {
        if (location == null)
            return false;

        LatLng lastPoint = polyLoc.get(polyLoc.size() - 1);
        boolean isInside = false;
        double x = location.longitude;

        for (LatLng point : polyLoc) {
            double x1 = lastPoint.longitude;
            double x2 = point.longitude;
            double dx = x2 - x1;

            if (Math.abs(dx) > 180.0) {
                // we have, most likely, just jumped the dateline (could do further validation to this effect if needed).  normalise the numbers.
                if (x > 0) {
                    while (x1 < 0)
                        x1 += 360;
                    while (x2 < 0)
                        x2 += 360;
                } else {
                    while (x1 > 0)
                        x1 -= 360;
                    while (x2 > 0)
                        x2 -= 360;
                }
                dx = x2 - x1;
            }

            if ((x1 <= x && x2 > x) || (x1 >= x && x2 < x)) {
                double grad = (point.latitude - lastPoint.latitude) / dx;
                double intersectAtLat = lastPoint.latitude + ((x - x1) * grad);

                if (intersectAtLat > location.latitude)
                    isInside = !isInside;
            }
            lastPoint = point;
        }

        return isInside;
    }


    public static Drawable getDrawable(@DrawableRes int drawableResId) {
        Drawable d = ContextCompat.getDrawable(MyApplication.getContext(), drawableResId);
        return d;
    }

    public static float getDimension(@DimenRes int dimensionResId) {
        return MyApplication.getContext().getResources().getDimension(dimensionResId);
    }


    public static int getStatusPharmacyColor(boolean isOpen) {
        Context context = MyApplication.getContext();
        return isOpen ? ContextCompat.getColor(context, R.color.pharmacy_open) :
                ContextCompat.getColor(context, R.color.pharmacy_close);
    }

} public class ScrollerLinearLayoutManager extends LinearLayoutManager {

    private Context mContext;
    public ScrollerLinearLayoutManager(Context mContext) {
        super(mContext);
        this.mContext =mContext;
    }

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
        //
        LinearSmoothScroller smoothScroller = new LinearSmoothScroller(mContext){
            @Nullable
            @Override
            public PointF computeScrollVectorForPosition(int targetPosition) {
                return ScrollerLinearLayoutManager.this.computeScrollVectorForPosition
                        (targetPosition);
            }

            //1 pixel -> 0.05 ms
            //1000 pixel -> x=50 ms to go over the height of the screen
            @Override
            protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
                return 0.05f;
                //return x /displayMetrics.densityDpi;
            }
        };
        smoothScroller.setTargetPosition(position);
        startSmoothScroll(smoothScroller);
    }
} public class DialogOpeningHoursPharmacy extends DialogFragment {

    private static final String LAYOUT_KEY = "layout";
    private static final String COLOR_KEY = "color";
    int layoutId;
    int backgroundTitleColor;

    public static DialogOpeningHoursPharmacy newInstance(int layoutId) {

        Bundle args = new Bundle();
        args.putInt(LAYOUT_KEY, layoutId);
        DialogOpeningHoursPharmacy fragment = new DialogOpeningHoursPharmacy();
        fragment.setArguments(args);
        return fragment;
    }

    public static DialogOpeningHoursPharmacy newInstance(int layoutId, int colorInt) {

        Bundle args = new Bundle();
        args.putInt(LAYOUT_KEY, layoutId);
        args.putInt(COLOR_KEY, colorInt);
        DialogOpeningHoursPharmacy fragment = new DialogOpeningHoursPharmacy();
        fragment.setArguments(args);
        return fragment;
    }

    public DialogOpeningHoursPharmacy() {


    }


    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        Bundle bundle = getArguments();
        this.layoutId = bundle.getInt(LAYOUT_KEY);
        LayoutInflater inflater = getActivity().getLayoutInflater();
        View v = inflater.inflate(layoutId, null);
        RelativeLayout title = (RelativeLayout) v.findViewById(R.id.titleDialog);
        if (bundle.containsKey(COLOR_KEY)) {
            this.backgroundTitleColor = bundle.getInt(COLOR_KEY);
            title.setBackgroundColor(backgroundTitleColor);
        }


        //    View title = inflater.inflate(R.layout.dialog_openinghours_title,null);
        builder.setView(v);
        builder.setPositiveButton(R.string.dialog_ok_button, null);
        //    builder.setCustomTitle(title);
        builder.setIcon(R.drawable.clock);
        //  builder.setMessage(R.string.dialog_mensaje);


        return builder.create();
    }
} public class SnackBarWrapper {
    private Snackbar snackbar;
    SnackbarBuilder builder;
    CoordinatorLayout rootLayout;

    public SnackBarWrapper(Activity context) {
        builder = new SnackbarBuilder(context)
                .message(R.string.sbw_nuevas_localizaciones)
                .duration(Snackbar.LENGTH_INDEFINITE)
                .actionText(R.string.sbw_actualizar)
                .actionTextColorRes(R.color.blue_200);

        setRootLayout(context);
    }

    public SnackBarWrapper(Activity context, String message,int duration) {

        snackbar = new SnackbarBuilder(context)
                .message(message)
                .duration(duration)
                .build();
        setRootLayout(context);
    }

    private void setRootLayout(Activity context) {
        rootLayout = (CoordinatorLayout) context.findViewById(R.id.coordinatorSnackContainer);
    }
    public void show() {
        rootLayout.setVisibility(View.VISIBLE);
        snackbar.show();

    }
    public void dismiss(){
        rootLayout.setVisibility(View.GONE);
        snackbar.dismiss();
    }
    public void addCallback(SnackbarCallback snackbarCallback) {
        snackbar = builder.snackbarCallback(snackbarCallback).build();
    }

} public class LoaderProvider  {

    private Context mContext;
    private String[] projectionSuggestion = new String[]{DbContract.FarmaciasEntity._ID,
            DbContract.FarmaciasEntity.NAME,
            DbContract.FarmaciasEntity.ADDRESS,
            DbContract.FarmaciasEntity.LOCALITY,
            DbContract.FarmaciasEntity.PROVINCE};

    public LoaderProvider(Context context){
        mContext=context;
    }
    public Loader<Cursor> getPharmacies(){

        return new CursorLoader(mContext,
                DbContract.FarmaciasEntity.CONTENT_URI,
                null,
                null,
                null,
                DbContract.FarmaciasEntity.LOCALITY ) ;

    }

    public  Loader<Cursor> getPharmaciesByName(String name) {
        return new CursorLoader(mContext,
                DbContract.FarmaciasEntity.CONTENT_URI,
                null,
                DbContract.FarmaciasEntity.NAME + " like ?",
                new String[]{"%"+ name + "%"},
                DbContract.FarmaciasEntity.NAME + " ASC LIMIT 50"
        );
    }


     public Loader<Cursor> getPharmaciesByNameQuickSearch(String name) {

        return new CursorLoader(mContext,
                DbContract.FarmaciasEntity.buildFarmaciasUriByNameQuickSearch(name),
                null,
                DbContract.FarmaciasEntity.NAME + " like ?",
                new String[]{"%"+ name + "%"},
                DbContract.FarmaciasEntity.NAME + " ASC LIMIT 50"
        );
    }


    public Loader<Cursor> getFavoritesPharmacies() {
        return new CursorLoader(mContext,
                DbContract.FarmaciasEntity.CONTENT_URI,
                null,
                DbContract.FarmaciasEntity.FAVORITE + "=?",
                new String[]{"1"},
                DbContract.FarmaciasEntity.NAME + " ASC"
        );
    }
} public class Pharmacy extends PharmacyObjectMap implements Parcelable {

    private boolean optionsRow;
    int circleColor;



    public Pharmacy() {
    }

    public int getCircleColor() {
        return circleColor;
    }

    public void setCircleColor(int circleColor) {
        this.circleColor = circleColor;
    }

    public boolean isOptionsRow() {
        return optionsRow;
    }

    public void setOptionsRow(boolean optionsRow) {
        this.optionsRow = optionsRow;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        dest.writeByte(this.optionsRow ? (byte) 1 : (byte) 0);
        dest.writeInt(this.circleColor);
    }

    protected Pharmacy(Parcel in) {
        super(in);
        this.optionsRow = in.readByte() != 0;
        this.circleColor = in.readInt();
    }

    public static final Creator<Pharmacy> CREATOR = new Creator<Pharmacy>() {
        @Override
        public Pharmacy createFromParcel(Parcel source) {
            return new Pharmacy(source);
        }

        @Override
        public Pharmacy[] newArray(int size) {
            return new Pharmacy[size];
        }
    };
} public class ListTabPresenter implements ListTabContract.Presenter<ListTabContract.View>,
        LoaderManager.LoaderCallbacks<Cursor> {

    private static final String LOG_TAG=ListTabPresenter.class.getSimpleName();
    private final LoaderManager mLoaderManager;
    private ListTabContract.View mView;
    private LoaderProvider mLoaderProvider;
    private Geocoder mGeocoder;
    private Location mLocation;
    private List<Pharmacy> mFarmaciasList;
    private int FARMACIAS_LOADER=2;
    Handler mainHandler;

    private PreferencesManager preferencesManager;
    private int mRadio;
    public ListTabPresenter(LoaderProvider loaderProvider, LoaderManager loadermanager,
                            Geocoder geocoder,PreferencesManager preferencesManager
                            ) {

        mLoaderProvider=loaderProvider;
        mLoaderManager=loadermanager;
        mGeocoder=geocoder;
        this.preferencesManager=preferencesManager;
        mRadio=this.preferencesManager.retrieveRadioBusquedaFromSp()*1000;
        mainHandler = new Handler(Looper.getMainLooper());


    }


    @Override
    public void setView(ListTabContract.View view) {
        if (view == null) throw new IllegalArgumentException("You can't set a null view");
        mView=view;
    }

    @Override
    public void detachView() {
        mView=null;
    }

    @Override
    public void onStartLoader() {
        Utils.logD(LOG_TAG,"onStartLoader");
        mView.showLoading();
        mLoaderManager.initLoader(FARMACIAS_LOADER, null, this);
    }

    @Override
    public void setLocation(Location currentLocation) {
        mLocation = currentLocation;
    }

    @Override
    public void onGetAddressFromLocation(Location currentLocation) {
        List<Address> addresses = null;
        try {
            addresses = mGeocoder.getFromLocation(
                    currentLocation.getLatitude(),
                    currentLocation.getLongitude(),
                    1);
        } catch (IOException ioe) {

        }

        if (addresses == null || addresses.size() == 0) {
            Utils.logD(LOG_TAG, "no address found");
            mView.setAddress(null);
        } else {
            Address address = addresses.get(0);
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < address.getMaxAddressLineIndex(); i++) {
                stringBuilder.append(address.getAddressLine(i));
                if (i != address.getMaxAddressLineIndex() - 1) {
                    stringBuilder.append(Constants.COMMA);
                }
            }
            Utils.logD(LOG_TAG, "address found");

            mView.setAddress(stringBuilder.toString());
        }

    }



    @Override
    public void handleClickGo(Pharmacy pharmacy, Location currentLocation, String currentAddress) {
        Intent intent= Utils.getGoodleDirectionsIntent(new LatLng(mLocation.getLatitude(), mLocation.getLongitude()),
                currentAddress,
                new LatLng(pharmacy.getLat(), pharmacy.getLon()),
                pharmacy.getAddressFormatted()
        );
        mView.launchActivity(intent);
    }

    @Override
    public void handleClickCall(String phone) {
        String uri = "tel:" + phone;
        Intent intent = new Intent(Intent.ACTION_DIAL);
        intent.setData(Uri.parse(uri));
        mView.launchActivity(intent);

    }

    @Override
    public void handleClickShare(Pharmacy pharmacy) {
        String name = pharmacy.getName();
        double distance = pharmacy.getDistance() ;
        String address = pharmacy.getAddressFormatted();
        String phone = pharmacy.getPhone();
        Intent intent = Utils.getShareIntent(name, distance, address, phone);
        mView.launchActivity(intent);
    }

    @Override
    public void handleClickFavorite(Pharmacy pharmacy) {
        final String snackMessage = Utils.changeFavoriteInDb(pharmacy.isFavorite(), pharmacy.getPhone());
        if (snackMessage == null) {
            return;
        }
        mView.showSnackBar(snackMessage);
    }

    @Override
    public void onClickOpeningHours(Pharmacy pharmacy) {
        int layoutId = Utils.is24HoursPharmacy(pharmacy.getHours())? R.layout.dialog_opening_hours_24_hours
                :R.layout.dialog_opening_hours_normal;
        int titleBackgroundColor=Utils.getStatusPharmacyColor(pharmacy.isOpen());

        mView.showOpeningHours(layoutId,titleBackgroundColor);
    }

    private void bindView(Cursor data) {
        Utils.logD(LOG_TAG,"bindView");
        mFarmaciasList=new ArrayList<>();

        if (data.isClosed()) return;

        if (data.moveToFirst()) {
            do {

                Pharmacy farmacia = new Pharmacy();

                double latDest = data.getDouble(data.getColumnIndex(DbContract.FarmaciasEntity.LAT));
                double lonDest = data.getDouble(data.getColumnIndex(DbContract.FarmaciasEntity.LON));
                double distance = SphericalUtil.computeDistanceBetween(new LatLng(latDest,lonDest),
                        new LatLng(mLocation.getLatitude(),mLocation.getLongitude()));
               // double distance = Utils.meterDistanceBetweenPoints(latDest, lonDest, mLocation.getLatitude(), mLocation.getLongitude());
                farmacia.setName(data.getString(data.getColumnIndex(DbContract.FarmaciasEntity.NAME)));
                farmacia.setAddress(data.getString(data.getColumnIndex(DbContract.FarmaciasEntity.ADDRESS)));
                farmacia.setLocality(data.getString(data.getColumnIndex(DbContract.FarmaciasEntity.LOCALITY)));
                farmacia.setProvince(data.getString(data.getColumnIndex(DbContract.FarmaciasEntity.PROVINCE)));
                farmacia.setPostal_code(data.getString(data.getColumnIndex(DbContract.FarmaciasEntity.POSTAL_CODE)));
                String phone = data.getString(data.getColumnIndex(DbContract.FarmaciasEntity.PHONE));
                farmacia.setPhone(phone);
                farmacia.setLat(latDest);
                farmacia.setLon(lonDest);
                farmacia.setDistance(distance);
                String hours = data.getString(data.getColumnIndex(DbContract.FarmaciasEntity.HOURS));
                farmacia.setHours(hours);
                farmacia.setOpen(Utils.isPharmacyOpen(hours));
                String addressFormatted = Utils.formatAddress(farmacia.getAddress(),
                        farmacia.getPostal_code(),
                        farmacia.getLocality(),
                        farmacia.getProvince());
                farmacia.setAddressFormatted(addressFormatted);


                boolean favorite;
                int j=data.getInt(data.getColumnIndex(DbContract.FarmaciasEntity.FAVORITE));
                if (j==0){
                    favorite=false;
                } else {
                    favorite=true;
                }

                farmacia.setFavorite(favorite);
                mFarmaciasList.add(farmacia);

            } while (data.moveToNext());
        }
        mFarmaciasList = toFilteredSortedOrderedList(mFarmaciasList);

        mainHandler.post(new Runnable() {
            @Override
            public void run() {
                mView.hideLoading();
                if(mFarmaciasList !=null && mFarmaciasList.size()>0) {
                    mView.showResults(mFarmaciasList);
                } else {
                    mView.showNoResults();
                }
            }
        });





    }
    /**
     * Transformers.mapWithIndex https://github.com/ReactiveX/RxJava/issues/3602
     * rxjava-extras
     *
     * @param list
     * @return
     */
    public List<Pharmacy> toFilteredSortedOrderedList(List<Pharmacy> list) {

        return Observable.from(list)
                .filter(f -> {
                    if (f.getDistance() <mRadio) {
                        return true;
                    }
                    return false;
                })
                .toSortedList()
                .flatMap(s -> Observable.from(s))
                .compose(Transformers.mapWithIndex())
                .map(t -> {
                    t.value().setOrder(Utils.characterFromInteger((int) t.index()));
                    return t.value();
                })
                .toList()
                .toBlocking().first();

    }



    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {

        if (id == FARMACIAS_LOADER) {
            Utils.logD(LOG_TAG, "onCreateLoader List");
            return mLoaderProvider.getPharmacies();
        }
        return null;
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        Utils.logD(LOG_TAG,"onLoadFinished List");
        if (loader.getId() == FARMACIAS_LOADER) {
            new Thread() {
                @Override
                public void run() {
                    bindView(data);

                }
            }.start();
        }
    }


    @Override
    public void onLoaderReset(Loader<Cursor> loader) {

    }
} public class CustomItemAnimator extends DefaultItemAnimator {
    private boolean animateMoves = false;
    public CustomItemAnimator() {
        super();
    }

    public void setAnimateMoves(boolean animateMoves) {
        this.animateMoves = animateMoves;
    }

    @Override
    public boolean animateMove(RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) {
        if (!animateMoves) {
            dispatchMoveFinished(holder);

            return false;
        }
        return super.animateMove(holder, fromX, fromY, toX, toY);
    }
} public class PreferencesManagerImp implements PreferencesManager {

    private final SharedPreferences mPrefs;
    private final SharedPreferences.Editor mEditor;
    private final Context context;
    private static final String FAVORITE_LIST_KEY ="favorite_list_key";
    private static final String COLOR_MAP_KEY ="color_map_key";
    private static final String LOCATION_KEY = "location_key";
    private static final String STREET_KEY ="street_key";
    private static final String SEEKBAR_KEY="seekbar_key";
    private static final String FIRST_EXECUTION_KEY="first_execution_key";
    private static final String CURRENT_ITEM_KEY ="current_item_key";

    public PreferencesManagerImp(Context context) {
        mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
        mEditor = mPrefs.edit();
        this.context = context;
    }



    @Override
    public SharedPreferences getSharedPreferences() {
        return mPrefs;
    }

    @Override
    public String getLocationKey() {
        return LOCATION_KEY;
    }

    @Override
    public int retrieveRadioBusquedaFromSp() {
        return mPrefs.getInt(SEEKBAR_KEY, 4);

    }

    @Override
    public boolean isFirstExecution() {
        return mPrefs.getBoolean(FIRST_EXECUTION_KEY, true);

    }

    @Override
    public void setFirstExecutionFalse() {

        mEditor.putBoolean(FIRST_EXECUTION_KEY, false);
        mEditor.apply();
    }

    public int getCurrentItemTabLayout() {

        return mPrefs.getInt(CURRENT_ITEM_KEY, 0);

    }

    public void setCurrentItemTabLayout(int currentItemTabLayout) {

        mEditor.putInt(CURRENT_ITEM_KEY, currentItemTabLayout);
        mEditor.apply();
    }

    @Override
    public void saveLocation(Location location) {
        //http://stackoverflow.com/questions/3604849/where-to-save-android-gps-latitude-longitude-points
//        mEditor.putLong(LAT_KEY, Double.doubleToLongBits(location.getLatitude()));
//        mEditor.putLong(LON_KEY,Double.doubleToLongBits(location.getLongitude()));
        String locationObject = location.getLatitude() + Constants.SEMI_COLON + location.getLongitude();
        mEditor.putString(LOCATION_KEY, locationObject);
        mEditor.apply();
    }

    @Override
    public Location getLocation() {
        Location location;
        String locationObject = mPrefs.getString(LOCATION_KEY, "0:0");
        String [] coordinates = locationObject.split(":");
        double latitud = Double.parseDouble(coordinates[0]);
        double longitud = Double.parseDouble(coordinates[1]);
        location = new Location(Constants.EMPTY_STRING);
        location.setLatitude(latitud);
        location.setLongitude(longitud);
        return location;

    }

    @Override
    public int getRadio() {
        return mPrefs.getInt(context.getString(R.string.seek_bar_key),2);
    }

    @Override
    public void saveFavoriteList(List<Pharmacy> list) {
        if(list == null) return;

        mEditor.putString(FAVORITE_LIST_KEY,new Gson().toJson(list));
        mEditor.apply();

    }

    @Override
    public List<Pharmacy> getFavorites() {

        if(mPrefs.contains(FAVORITE_LIST_KEY)) {
            String jsonString = mPrefs.getString(FAVORITE_LIST_KEY, null);

            if (jsonString != null) {
                Gson gsonObject = new Gson();
                Pharmacy[] arrayFavorite = gsonObject.fromJson(jsonString, Pharmacy[].class);
                //the list returned by Arrays.asList is inmmutable, we need to create another list based on this one
                return new ArrayList<>(Arrays.asList(arrayFavorite));

            }
        }
        return new ArrayList<>();
    }

    @Override
    public void saveColorMap(HashMap<String, Integer> colorMap) {
        mEditor.putString(COLOR_MAP_KEY,new Gson().toJson(colorMap));
        mEditor.apply();

    }

    @Override
    public HashMap<String, Integer> getColorMap() {
        if(mPrefs.contains(COLOR_MAP_KEY)) {
            String jsonString = mPrefs.getString(COLOR_MAP_KEY, null);
            if(jsonString !=null) {
                java.lang.reflect.Type type = new TypeToken<HashMap<String, Integer>>(){}.getType();
                return  new Gson().fromJson(jsonString,type);
            }
        }
        return null;
    }

    @Override
    public void saveStreet(String street) {
        mEditor.putString(STREET_KEY,street);
        mEditor.apply();
    }

    @Override
    public String getStreet() {
        return mPrefs.getString(STREET_KEY,Constants.EMPTY_STRING);
    }


} public class ListTabAdapter extends RecyclerView.Adapter<ListTabAdapter.MyViewHolder> {

    private List<Pharmacy> mPharmacyList;
    private Context mContext;
    private ListTabAdapterOnClickHandler mClickHandler;
    private static final String LOG_TAG = ListTabAdapter.class.getSimpleName();
    private CustomItemAnimator mCustomItemAnimator;
    private int expandedPosition = RecyclerView.NO_POSITION;
    private Transition expandCollapse = null;
    private static int COLLAPSE = 2;
    private static int EXPAND = 3;
    private RecyclerView mRecyclerView;
    private int lastAnimatedPosition = -1;


    @Constants.ScrollDirection
    int scrollDirection;


    public ListTabAdapter(ListTabFragment fragment,
                          RecyclerView recyclerView, CustomItemAnimator customItemAnimator
    ) {
        mContext = fragment.getActivity();
        mClickHandler = fragment;
        mRecyclerView = recyclerView;
        mCustomItemAnimator = customItemAnimator;


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {

            expandCollapse = new AutoTransition();
            expandCollapse.setDuration(200);
            expandCollapse.setInterpolator(AnimationUtils.loadInterpolator(mContext,
                    android.R.interpolator.linear));
            expandCollapse.addListener(new Transition.TransitionListener() {
                @Override
                public void onTransitionStart(Transition transition) {
                    mRecyclerView.setOnTouchListener(new View.OnTouchListener() {
                        @Override
                        public boolean onTouch(View v, MotionEvent event) {
                            return true;
                        }
                    });
                }

                @Override
                public void onTransitionEnd(Transition transition) {
                    mCustomItemAnimator.setAnimateMoves(true);
                    mRecyclerView.setOnTouchListener(null);

                }

                @Override
                public void onTransitionCancel(Transition transition) {

                }

                @Override
                public void onTransitionPause(Transition transition) {

                }

                @Override
                public void onTransitionResume(Transition transition) {

                }
            });
        }
        //this fragment has a lot to do on initialization, put this down instead of app to avoid
        //the animations to run at first.
        scrollDirection = Constants.SCROLL_DOWN;
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                if (dy > 0) {
                    scrollDirection = Constants.SCROLL_UP;
                    Log.i("RecyclerView scrolled: ", "scroll up!");
                    Log.i("RecyclerView scrolled: ", "dy:" + dy);
                } else {
                    scrollDirection = Constants.SCROLL_DOWN;
                    Log.i("RecyclerView scrolled: ", "scroll down!");
                    Log.i("RecyclerView scrolled: ", "dy:" + dy);
                }
            }
        });

    }

    // mainly used when new coordinates arrive, to enable animations, since now the ui thread
    // not so busy
    public int getScrollDirection() {
        return scrollDirection;
    }

    public void setScrollDirection(int scrollDirection) {
        this.scrollDirection = scrollDirection;
    }

    public void recalculateIsOpenNow() {
        int changes = 0;
        boolean oldStatus,currentStatus;
        Pharmacy pharmacy;
        for (int i = 0; i < mPharmacyList.size(); i++) {
            pharmacy = mPharmacyList.get(i);
            oldStatus = pharmacy.isOpen();
            currentStatus =Utils.isPharmacyOpen(pharmacy.getHours());
            if (oldStatus != currentStatus) {
                changes++;
            }
            pharmacy.setOpen(currentStatus);

        }
        if (changes > 0) {

            setScrollDirection(Constants.SCROLL_UP);
            notifyDataSetChanged();
        }

    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //  Utils.logD(LOG_TAG,"onCreateViewHolder");
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_tab_list, parent, false);

        MyViewHolder holder = new MyViewHolder(view);
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final int position = holder.getAdapterPosition();
                setDelayedTransition();
                mCustomItemAnimator.setAnimateMoves(false);
                if (position == RecyclerView.NO_POSITION) return;
                // collapse any currently expanded items
                if (expandedPosition != RecyclerView.NO_POSITION) {
                    notifyItemChanged(expandedPosition, COLLAPSE);
                }
                if (expandedPosition != position) {
                    expandedPosition = position;
                    notifyItemChanged(position, EXPAND);
                } else {
                    expandedPosition = RecyclerView.NO_POSITION;
                }


            }
        });
        return holder;

    }

    @TargetApi(Build.VERSION_CODES.KITKAT)
    private void setDelayedTransition() {
        TransitionManager.beginDelayedTransition(mRecyclerView, expandCollapse);
    }

    private void setExpanded(ListTabAdapter.MyViewHolder holder, boolean isExpanded) {
        holder.itemView.setActivated(isExpanded);
        holder.llOptionsRow.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
        holder.ivGo.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
        holder.ivPhone.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
        holder.ivClock.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
        holder.ivShare.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
        holder.ivFavorite.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
    }

    @Override
    public void onBindViewHolder(ListTabAdapter.MyViewHolder holder, int position, List<Object> payloads) {

        if ((payloads.contains(EXPAND) || payloads.contains(COLLAPSE))) {
            setExpanded(holder, position == expandedPosition);
        } else {
            onBindViewHolder(holder, position);
        }
    }


    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {

        Utils.logD(LOG_TAG, "onBindViewHolder, position" + position);

        runEnterAnimation(holder.itemView, position);
        bindHolder(holder, position);

    }

    private void runEnterAnimation(View view, int position) {
        if (position >= mPharmacyList.size() - 1) {
            return;
        }

        if (scrollDirection == Constants.SCROLL_UP) {
            Utils.logD(LOG_TAG, "runEnterAnimation_up");
            if (position > lastAnimatedPosition) {
                lastAnimatedPosition = position;
                Utils.logD(LOG_TAG, "lasAnimated,position:" + lastAnimatedPosition + "," + position);
                view.setTranslationY(Utils.getScreenHeight(mContext));
                ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, "translationY", 0);
                //more than this causes the animation to stutter
                objectAnimator.setDuration(600);
                objectAnimator.setInterpolator(new DecelerateInterpolator(3.f));
                objectAnimator.start();
            }
        } else {
            Utils.logD(LOG_TAG, "runEnterAnimation_down");
            if (position < lastAnimatedPosition) {
                Utils.logD(LOG_TAG, "lasAnimated,position" + lastAnimatedPosition + "," + position);
                lastAnimatedPosition = position;
            }
        }
    }

    private void bindHolder(MyViewHolder holder, int position) {
        Pharmacy pharmacy = mPharmacyList.get(position);

        holder.tvName.setText(pharmacy.getName());
        holder.tvStreet.setText(pharmacy.getAddressFormatted());
        holder.tvDistance.setText(mContext.getString(R.string.format_distance, pharmacy.getDistance() / 1000));
        boolean isOpen = pharmacy.isOpen();
        holder.tvOpen.setText(isOpen ? mContext.getString(R.string.rtl_farmacia_abierta)
                : mContext.getString(R.string.rtl_farmacia_cerrada));
        int color;
        if (isOpen) {
            color = getColor(R.color.pharmacy_open);
        } else {
            color = getColor(R.color.pharmacy_close);
        }
        holder.tvOpen.setTextColor(color);


        int favDraResid;
        if (pharmacy.isFavorite()) {
            favDraResid = R.drawable.ic_heart;
        } else {
            favDraResid = R.drawable.ic_heart_outline;
        }
        setFavoriteIcon(holder.ivFavorite, favDraResid, color);
        setTintedVectorDrawable(holder.ivClock, color);
        setTintedVectorDrawable(holder.ivGo, color);
        setTintedVectorDrawable(holder.ivShare, color);
        setTintedVectorDrawable(holder.ivPhone, color);

        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
            final boolean isExpanded = position == expandedPosition;
            setExpanded(holder, isExpanded);
        } else {
            setExpanded(holder, true);
        }

        holder.tvOrder.setBackgroundResource(isOpen ? R.drawable.shape_circle_order_open :
                R.drawable.shape_circle_order_close);
        holder.tvOrder.setText(pharmacy.getOrder());

    }


    private void setFavoriteIcon(ImageView imageView, int favDraResid, int color) {

        imageView.setImageResource(favDraResid);
        setTintedVectorDrawable(imageView, color);
    }

    private void setTintedVectorDrawable(ImageView imageView, int color) {
        //option1. create vector drawable and tint it(this method resize the image
        //  VectorDrawableCompat drawable=VectorDrawableCompat.create(mContext.getResources(),drawableResId,null);
        //  if(drawable==null) return;
        //  drawable.setTint(color);
        //  convert tinted vector drawable to bitmap
        //  Bitmap bitmap= Utils.createScaledBitMapFromVectorDrawable(mContext,drawable,40f);
        //  imageView.setImageBitmap(bitmap);

        // option2: much better, reduce stuttering when scrolling

        DrawableCompat.setTint(imageView.getDrawable(), color);


    }


    @Override
    public int getItemCount() {

        if (mPharmacyList == null) return 0;
        return mPharmacyList.size();
    }

    public void swapData(List<Pharmacy> pharmacyList) {
        mPharmacyList = pharmacyList;
        notifyDataSetChanged();

    }

    private int getColor(@ColorRes int resId) {
        int color = ContextCompat.getColor(mContext, resId);
        return color;
    }

    public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        @BindView(R.id.tvOrder)
        public TextView tvOrder;
        @BindView(R.id.tvName)
        public TextView tvName;
        @BindView(R.id.tvStreet)
        public TextView tvStreet;
        @BindView(R.id.tvDistance)
        public TextView tvDistance;
        @BindView(R.id.tvOpen)
        public TextView tvOpen;
        @BindView(R.id.ivOpeningHours)
        public ImageView ivClock;
        @BindView(R.id.ivPhone)
        public ImageView ivPhone;
        @BindView(R.id.ivShare)
        public ImageView ivShare;
        @BindView(R.id.ivFavorite)
        public ImageView ivFavorite;
        @BindView(R.id.ivGo)
        public ImageView ivGo;
        @BindView(R.id.optionsRow)
        public LinearLayout llOptionsRow;


        public MyViewHolder(View v) {
            super(v);
            ButterKnife.bind(this, v);

            ivPhone.setOnClickListener(this);
            ivShare.setOnClickListener(this);
            ivFavorite.setOnClickListener(this);
            ivGo.setOnClickListener(this);
            ivClock.setOnClickListener(this);

        }

        @Override
        public void onClick(View view) {
            int id = view.getId();
            int position = getAdapterPosition();
            Pharmacy pharmacy = mPharmacyList.get(position);
            switch (id) {

                case R.id.ivPhone:
                    mClickHandler.onClickPhone(pharmacy.getPhone());
                    break;
                case R.id.ivGo:
                    mClickHandler.onClickGo(pharmacy);
                    break;
                case R.id.ivShare:
                    mClickHandler.onClickShare(pharmacy);
                    break;
                case R.id.ivFavorite:
                    mClickHandler.onClickFavorite(pharmacy);
                    break;
                case R.id.ivOpeningHours:
                    mClickHandler.onClickOpeningHours(pharmacy);
                    break;

            }
        }


    }

    public interface ListTabAdapterOnClickHandler {
        void onClickGo(Pharmacy pharmacy);

        void onClickFavorite(Pharmacy pharmacy);

        void onClickPhone(String phone);

        void onClickShare(Pharmacy pharmacy);

        void onClickOpeningHours(Pharmacy pharmacy);
    }
} public interface PreferencesManager {

    SharedPreferences getSharedPreferences();
    String getLocationKey();
    int retrieveRadioBusquedaFromSp();
    boolean isFirstExecution();
    void setFirstExecutionFalse();
    int getCurrentItemTabLayout();
    void setCurrentItemTabLayout(int currentItemTabLayout);
    void saveLocation(Location location);
    Location getLocation();
    int getRadio();
    void saveFavoriteList(List<Pharmacy> list);
    List<Pharmacy> getFavorites();
    void saveColorMap(HashMap<String,Integer> colorMap);
    HashMap<String,Integer> getColorMap();
    void saveStreet(String street);
    String getStreet();

} public interface ListTabContract {

    interface View {
        void showResults(List<Pharmacy> pharmacyList);
        void showNoResults();
        void showLoading();
        void showSnackBar(String message);
        void hideLoading();
        void setAddress(String address);
        void launchActivity(Intent intent);
        void showOpeningHours(int layout,int titleBackgroundColor);

    }

    interface Presenter<V> {

        void setView(V view);
        void detachView();
        void onStartLoader();
        void onGetAddressFromLocation(Location currentLocation);
        void setLocation(Location currentLocation);
        void handleClickGo(Pharmacy pharmacy,Location currentLocation, String currentAddress);
        void handleClickCall(String phone);
        void handleClickShare(Pharmacy pharmacy);
        void handleClickFavorite(Pharmacy pharmacy);
        void onClickOpeningHours(Pharmacy pharmacy);






    }
} public interface MoveListToTop {
    void moveSmoothToTop();
}
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Geocoder;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Parcelable;
import android.support.annotation.Nullable;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.chernandezgil.farmacias.R;
import com.chernandezgil.farmacias.Utilities.Constants;
import com.chernandezgil.farmacias.Utilities.Utils;
import com.chernandezgil.farmacias.customwidget.ScrollerLinearLayoutManager;
import com.chernandezgil.farmacias.customwidget.dialog.DialogOpeningHoursPharmacy;
import com.chernandezgil.farmacias.customwidget.SnackBarWrapper;
import com.chernandezgil.farmacias.data.LoaderProvider;
import com.chernandezgil.farmacias.model.Pharmacy;
import com.chernandezgil.farmacias.presenter.ListTabPresenter;
import com.chernandezgil.farmacias.ui.adapter.item_animator.CustomItemAnimator;
import com.chernandezgil.farmacias.ui.adapter.PreferencesManagerImp;
import com.chernandezgil.farmacias.ui.adapter.ListTabAdapter;
import com.chernandezgil.farmacias.ui.adapter.PreferencesManager;
import com.chernandezgil.farmacias.view.ListTabContract;
import com.chernandezgil.farmacias.view.MoveListToTop;
import com.facebook.stetho.common.Util;
import com.github.andrewlord1990.snackbarbuilder.callback.SnackbarCallback;
import java.lang.reflect.Field;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
package com.chernandezgil.farmacias.ui.fragment;





/**
 * Created by Carlos on 06/08/2016.
 */
public class ListTabFragment extends Fragment implements ListTabContract.View,
        ListTabAdapter.ListTabAdapterOnClickHandler,
        SharedPreferences.OnSharedPreferenceChangeListener,
        MoveListToTop {

    @BindView(R.id.pharmaciesRecyclerView)
    RecyclerView mRecyclerView;
    @BindView(R.id.emptyView)
    RelativeLayout mEmptyView;
    @BindView(R.id.frameRoot)
    FrameLayout mRootView;
    @BindView(R.id.progressBar)
    ProgressBar mProgressBar;
    @BindView(R.id.swipeContainer)
    SwipeRefreshLayout mSwipeContainer;

    private Location mLocation;
    private ListTabPresenter mPresenter;