package com.gaiagps.iburn.adapters;
import android.content.Context;
import android.database.Cursor;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.gaiagps.iburn.Constants;
import com.gaiagps.iburn.CurrentDateProvider;
import com.gaiagps.iburn.DateUtil;
import com.gaiagps.iburn.R;
import com.gaiagps.iburn.api.typeadapter.PlayaDateTypeAdapter;
import com.gaiagps.iburn.database.EventTable;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import timber.log.Timber;
/**
* Bind an event database row to a view with name, distance, and delta time display,
* using the device's location and current time when the adapter was constructed.
* <p>
* TODO: Update device location and delta time periodically
*/
public class EventCursorAdapter extends PlayaItemCursorAdapter<EventCursorAdapter.ViewHolder> {
/** Parsers for start time section header derivation */
private static final DateFormat iso8601Format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
private static final DateFormat humanFormat = new SimpleDateFormat("E ha", Locale.US);
private List<String> startTimeSections;
private List<Integer> startTimeSectionPositions;
static final String[] Projection = new String[]{
EventTable.startTime,
EventTable.startTimePrint,
EventTable.endTime,
EventTable.endTimePrint,
EventTable.allDay,
EventTable.eventType,
EventTable.playaAddress
};
/** Projection when Events are grouped by name */
static final String[] GroupedProjection = new String[]{
EventTable.startTime,
EventTable.startTimePrint,
EventTable.endTime,
EventTable.endTimePrint,
EventTable.allDay,
EventTable.eventType,
EventTable.playaAddress,
"count(" + EventTable.name + ")",
"min(" + EventTable.startTime + ")",
"max(" + EventTable.startTime + ")"
};
private String[] finalProjection;
private boolean areItemsGrouped;
private SimpleDateFormat dayFormatter;
private SimpleDateFormat timeFormatter;
private int eventTypeCol;
private int addressCol;
private int startTimeCol;
private int startTimePrettyCol;
private int endTimeCol;
private int endTimePrettyCol;
private int allDayCol;
public static class ViewHolder extends PlayaItemCursorAdapter.ViewHolder {
TextView typeView;
TextView timeView;
TextView addressView;
String timeLabel;
public ViewHolder(View view) {
super(view);
timeView = (TextView) view.findViewById(R.id.time);
typeView = (TextView) view.findViewById(R.id.type);
addressView = (TextView) view.findViewById(R.id.address);
}
}
Calendar nowPlusOneHrDate = Calendar.getInstance();
Calendar nowDate = Calendar.getInstance();
public EventCursorAdapter(Context context, Cursor c, boolean areItemsGrouped, AdapterListener listener) {
super(context, c, listener);
this.areItemsGrouped = areItemsGrouped;
Date now = CurrentDateProvider.getCurrentDate();
nowDate.setTime(now);
nowPlusOneHrDate.setTime(now);
nowPlusOneHrDate.add(Calendar.HOUR, 1);
if (areItemsGrouped) {
dayFormatter = new SimpleDateFormat("EE M/d", Locale.US);
timeFormatter = new SimpleDateFormat("h:mm a", Locale.US);
}
finalProjection = this.areItemsGrouped ? buildRequiredProjection(GroupedProjection) : buildRequiredProjection(Projection);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.event_list_view_item, parent, false);
ViewHolder vh = new ViewHolder(itemView);
setupClickListeners(vh, Constants.PlayaItemType.EVENT);
return vh;
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, Cursor cursor) {
super.onBindViewHolder(viewHolder, cursor);
if (eventTypeCol == 0) {
eventTypeCol = cursor.getColumnIndexOrThrow(EventTable.eventType);
addressCol = cursor.getColumnIndexOrThrow(EventTable.playaAddress);
startTimeCol = cursor.getColumnIndexOrThrow(EventTable.startTime);
startTimePrettyCol = cursor.getColumnIndexOrThrow(EventTable.startTimePrint);
endTimeCol = cursor.getColumnIndexOrThrow(EventTable.endTime);
endTimePrettyCol = cursor.getColumnIndexOrThrow(EventTable.endTimePrint);
allDayCol = cursor.getColumnIndexOrThrow(EventTable.allDay);
}
try {
if (areItemsGrouped) {
int numEvents = cursor.getInt(finalProjection.length - 3);
String minDate = cursor.getString(finalProjection.length - 2);
String maxDate = cursor.getString(finalProjection.length - 1);
Date firstStartDate = PlayaDateTypeAdapter.iso8601Format.parse(minDate);
Date lastStartDate = PlayaDateTypeAdapter.iso8601Format.parse(maxDate);
if (numEvents > 1) {
viewHolder.timeLabel = dayFormatter.format(firstStartDate) + " - " + dayFormatter.format(lastStartDate);
if (cursor.getInt(cursor.getColumnIndexOrThrow(EventTable.allDay)) == 1) {
viewHolder.timeLabel += " all day";
} else {
viewHolder.timeLabel += " at " + timeFormatter.format(lastStartDate);
}
} else
viewHolder.timeLabel = cursor.getString(startTimePrettyCol);
} else {
if (cursor.getInt(cursor.getColumnIndexOrThrow(EventTable.allDay)) == 1) {
viewHolder.timeLabel = "All " + cursor.getString(cursor.getColumnIndexOrThrow(EventTable.startTimePrint));
} else {
viewHolder.timeLabel = DateUtil.getDateString(context, nowDate.getTime(), nowPlusOneHrDate.getTime(),
cursor.getString(startTimeCol),
cursor.getString(startTimePrettyCol),
cursor.getString(endTimeCol),
cursor.getString(endTimePrettyCol));
}
}
} catch (IllegalArgumentException | ParseException e) {
Timber.e(e, "Failed to bind event");
}
viewHolder.typeView.setText(
AdapterUtils.getStringForEventType(cursor.getString(eventTypeCol)));
if (areItemsGrouped) {
viewHolder.walkTimeView.setVisibility(View.GONE);
viewHolder.bikeTimeView.setVisibility(View.GONE);
}
// if items not grouped, time set by super.onBindViewHolder
viewHolder.timeView.setText(viewHolder.timeLabel);
String playaAddress = cursor.getString(addressCol);
if (!TextUtils.isEmpty(playaAddress)) {
viewHolder.addressView.setText(playaAddress);
viewHolder.addressView.setVisibility(View.VISIBLE);
} else {
viewHolder.addressView.setVisibility(View.GONE);
}
}
@Override
public String[] getRequiredProjection() {
return finalProjection;
}
// <editor-fold desc="SectionIndexer">
@Override
public Object[] getSections() {
if (startTimeSections == null) {
mCursor.moveToFirst();
startTimeSections = new ArrayList<>();
startTimeSectionPositions = new ArrayList<>();
addSectionStringForCursor(mCursor);
startTimeSectionPositions.add(0);
while (mCursor.moveToNext()) {
if (!startTimeSections.get(startTimeSections.size()-1).equals(mCursor.getString(startTimeCol))) {
addSectionStringForCursor(mCursor);
startTimeSectionPositions.add(startTimeSections.size()-1);
}
}
}
return startTimeSections.toArray();
}
private void addSectionStringForCursor(Cursor cursor) {
if (mCursor.getInt(allDayCol) == 1) {
startTimeSections.add("All " + cursor.getString(startTimePrettyCol));
} else {
try {
startTimeSections.add(humanFormat.format(iso8601Format.parse(cursor.getString(startTimeCol))));
} catch (ParseException e) {
startTimeSections.add(cursor.getString(startTimePrettyCol));
}
}
}
private int getSectionForCursorPosition(int position) {
for (int idx = 0; idx < startTimeSectionPositions.size(); idx++) {
if (startTimeSectionPositions.get(idx) > position) return idx - 1;
}
return startTimeSectionPositions.size() - 1;
}
@Override
public int getPositionForSection(int sectionIndex) {
// not needed
return 0;
}
@Override
public int getSectionForPosition(int position) {
if (startTimeSections == null) return 0;
if (position == mCursor.getCount()) return startTimeSections.size() - 1;
return getSectionForCursorPosition(position);
}
// </editor-fold desc="SectionIndexer">
}