package com.gaiagps.iburn.adapters; import android.content.Context; import android.location.Location; import android.text.Spannable; import android.text.SpannableString; import android.text.style.TextAppearanceSpan; import android.view.View; import android.widget.AdapterView; import android.widget.TextView; import android.widget.Toast; import com.gaiagps.iburn.Constants; import com.gaiagps.iburn.Geo; import com.gaiagps.iburn.R; import com.gaiagps.iburn.api.typeadapter.PlayaDateTypeAdapter; import com.gaiagps.iburn.database.DataProvider; import com.gaiagps.iburn.database.PlayaDatabase; import com.gaiagps.iburn.database.PlayaItemTable; import com.squareup.sqlbrite.SqlBrite; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Locale; /** * Created by davidbrodsky on 8/4/14. */ public class AdapterUtils { public static final ArrayList<String> sEventTypeAbbreviations = new ArrayList<>(); public static final ArrayList<String> sEventTypeNames = new ArrayList<>(); public static final ArrayList<String> sDayAbbreviations = new ArrayList<>(); public static final ArrayList<String> sDayNames = new ArrayList<>(); public static final SimpleDateFormat dayAbbrevFormatter = new SimpleDateFormat("EE M/d", Locale.US); static { // sDayNames.add("All Days"); // sDayAbbreviations.add(null); sDayNames.add("Monday 8/29"); sDayAbbreviations.add("8/29"); sDayNames.add("Tuesday 8/30"); sDayAbbreviations.add("8/30"); sDayNames.add("Wednesday 8/31"); sDayAbbreviations.add("8/31"); sDayNames.add("Thursday 9/1"); sDayAbbreviations.add("9/1"); sDayNames.add("Friday 9/2"); sDayAbbreviations.add("9/2"); sDayNames.add("Saturday 9/3"); sDayAbbreviations.add("9/3"); sDayNames.add("Sunday 9/4"); sDayAbbreviations.add("9/4"); sDayNames.add("Monday 9/5"); sDayAbbreviations.add("9/5"); sDayNames.add("Tuesday 9/6"); sDayAbbreviations.add("9/6"); sEventTypeAbbreviations.add("work"); sEventTypeNames.add("Work"); sEventTypeAbbreviations.add("game"); sEventTypeNames.add("Game"); sEventTypeAbbreviations.add("adlt"); sEventTypeNames.add("Adult"); sEventTypeAbbreviations.add("prty"); sEventTypeNames.add("Party"); sEventTypeAbbreviations.add("perf"); sEventTypeNames.add("Performance"); sEventTypeAbbreviations.add("kid"); sEventTypeNames.add("Kid"); sEventTypeAbbreviations.add("food"); sEventTypeNames.add("Food"); sEventTypeAbbreviations.add("cere"); sEventTypeNames.add("Ceremony"); sEventTypeAbbreviations.add("care"); sEventTypeNames.add("Care"); sEventTypeAbbreviations.add("fire"); sEventTypeNames.add("Fire"); } /** * @return the abbreviation for the current day, if it's during the burn, else the first day of the burn */ public static String getCurrentOrFirstDayAbbreviation() { String todayAbbrev = dayAbbrevFormatter.format(new Date()); if (sDayAbbreviations.contains(todayAbbrev)) return todayAbbrev; return sDayAbbreviations.get(0); } public static String getStringForEventType(String typeAbbreviation) { if (typeAbbreviation == null) return null; if (sEventTypeAbbreviations.contains(typeAbbreviation)) return sEventTypeNames.get(sEventTypeAbbreviations.indexOf(typeAbbreviation)); return null; } public static void setDistanceText(Location deviceLocation, TextView walkTimeView, TextView bikeTimeView, double lat, double lon) { setDistanceText(deviceLocation, null, null, null, walkTimeView, bikeTimeView, lat, lon); } /** * Get stylized distance text describing the difference between the given * device location and a given Latitude and Longitude. The unique * method signature owes itself to the precise data available to * a {@link com.gaiagps.iburn.adapters.PlayaItemCursorAdapter} * * @return a time estimate in minutes. */ public static void setDistanceText(Location deviceLocation, Date nowDate, String startDateStr, String endDateStr, TextView walkTimeView, TextView bikeTimeView, double lat, double lon) { if (deviceLocation != null && lat != 0) { double metersToTarget = Geo.getDistance(lat, lon, deviceLocation); int walkingMinutesToTarget = (int) Geo.getWalkingEstimateMinutes(metersToTarget); int bikingMinutesToTarget = (int) Geo.getBikingEstimateMinutes(metersToTarget); String distanceText; Context context = walkTimeView.getContext(); try { Date startDate = startDateStr != null ? PlayaDateTypeAdapter.iso8601Format.parse(startDateStr) : null; Date endDate = endDateStr != null ? PlayaDateTypeAdapter.iso8601Format.parse(endDateStr) : null; walkTimeView.setText(createSpannableForDistance(context, walkingMinutesToTarget, nowDate, startDate, endDate)); bikeTimeView.setText(createSpannableForDistance(context, bikingMinutesToTarget, nowDate, startDate, endDate)); } catch (ParseException e) { e.printStackTrace(); } // If minutes < startDate || minutes < (endDate - now) walkTimeView.setVisibility(View.VISIBLE); bikeTimeView.setVisibility(View.VISIBLE); } else { walkTimeView.setText(""); walkTimeView.setVisibility(View.GONE); bikeTimeView.setText(""); bikeTimeView.setVisibility(View.GONE); } } private static Spannable createSpannableForDistance(Context context, int minutesToTarget, Date nowDate, Date startDate, Date endDate) { String distanceText; Spannable spanRange; if (minutesToTarget < 1) { distanceText = "<1 m"; spanRange = new SpannableString(distanceText); } else { distanceText = String.format(Locale.US, "%d min", minutesToTarget); spanRange = new SpannableString(distanceText); } if (nowDate != null && startDate != null && endDate != null) { // If a date is given, attempt to do coloring of the time estimate (e.g: green if arrival estimate before start date) long duration = endDate.getTime() - startDate.getTime() / 1000 / 60; //minutes if (startDate.before(nowDate) && endDate.after(nowDate)) { // Event already started long timeLeftMinutes = ( endDate.getTime() - nowDate.getTime() ) / 1000 / 60; //Timber.d("ongoing event ends in " + timeLeftMinutes + " minutes ( " + endDateStr + ") eta " + minutesToTarget + " duration " + duration); if ( (timeLeftMinutes - minutesToTarget) > 0) { // If we'll make at least a quarter of the event, Color it yellow int endSpan = distanceText.indexOf("min") + 3; spanRange = new SpannableString(distanceText); TextAppearanceSpan tas = new TextAppearanceSpan(context, R.style.OrangeText); spanRange.setSpan(tas, 0, endSpan, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } else if (startDate.after(nowDate)) { long timeUntilStartMinutes = ( startDate.getTime() - nowDate.getTime() ) / 1000 / 60; //Timber.d("future event starts in " + timeUntilStartMinutes + " minutes ( " + startDateStr + ") eta " + minutesToTarget + " duration " + duration); if ( (timeUntilStartMinutes - minutesToTarget) > 0) { // If we'll make the event start, Color it green int endSpan = distanceText.indexOf("min") + 3; TextAppearanceSpan tas = new TextAppearanceSpan(context, R.style.GreenText); spanRange.setSpan(tas, 0, endSpan, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } } return spanRange; } public static AdapterView.OnItemLongClickListener mListItemLongClickListener = (parent, v, position, id) -> { int model_id = (Integer) v.getTag(R.id.list_item_related_model); Constants.PlayaItemType itemType = (Constants.PlayaItemType) v.getTag(R.id.list_item_related_model_type); String tableName; switch (itemType) { case ART: tableName = PlayaDatabase.ART; break; case CAMP: tableName = PlayaDatabase.CAMPS; break; case EVENT: tableName = PlayaDatabase.EVENTS; break; default: throw new IllegalStateException("Unknown PLAYA_ITEM"); } final DataProvider[] storedProvider = new DataProvider[1]; DataProvider.getInstance(v.getContext().getApplicationContext()) .doOnNext(provider -> storedProvider[0] = provider) .flatMap(dataProvider -> dataProvider.createQuery(tableName, "SELECT " + PlayaItemTable.favorite + " FROM " + tableName + " WHERE " + PlayaItemTable.id + " = ?", String.valueOf(model_id))) .map(SqlBrite.Query::run) .subscribe(cursor -> { boolean isFavorite = cursor.getInt(0) == 1; storedProvider[0].updateFavorite(PlayaItemTable.favorite, model_id, !isFavorite); Toast.makeText(v.getContext(), String.format("%s Favorites", isFavorite ? "Removed from" : "Added to"), Toast.LENGTH_SHORT).show(); }); return true; }; }