package org.rudirect.android.adapter;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.jgrapht.GraphPath;
import org.rudirect.android.R;
import org.rudirect.android.activity.RouteActivity;
import org.rudirect.android.data.constants.RUDirectApplication;
import org.rudirect.android.data.model.BusRouteEdge;
import org.rudirect.android.data.model.BusStop;
import org.rudirect.android.data.model.DirectionsItem;
import org.rudirect.android.interfaces.ViewHolderClickListener;
import org.rudirect.android.ui.holder.DirectionsRouteViewHolder;
import org.rudirect.android.ui.holder.DirectionsStopViewHolder;
import org.rudirect.android.util.DirectionsUtil;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class DirectionsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int INNER_BUS_STOP = 0, OUTER_BUS_STOP = 1, BUS_ROUTE = 2;
private Activity activity;
private ArrayList<DirectionsItem> items;
public DirectionsAdapter(Activity activity, GraphPath<BusStop, BusRouteEdge> path) {
this.activity = activity;
List<BusRouteEdge> busStopEdges = path.getEdgeList();
items = new ArrayList<>();
long time = new Date().getTime();
// Set initial wait time
time += calcWaitTime((int) DirectionsUtil.getInitialWait());
// Add origin bus stop and initial route
items.add(new DirectionsItem(OUTER_BUS_STOP, busStopEdges.get(0).getSourceBusStop().getTitle(),
busStopEdges.get(0).getSourceBusStop().getTag(), getTimeInHHMM(time), R.drawable.ic_bus_stop_circle));
items.add(new DirectionsItem(BUS_ROUTE, busStopEdges.get(0).getRouteName()
+ " (Bus #" + busStopEdges.get(0).getVehicleId() + ")", busStopEdges.get(0).getRouteTag(), null, 0));
// Iterate through all the edges
for (int i = 0; i < busStopEdges.size() - 1; i++) {
// Set travel time
time += calcWaitTime((int) busStopEdges.get(i).getTravelTime());
// Handle vehicle transfers
if (items.get(items.size() - 1).getTitle().equals(busStopEdges.get(i).getTargetBusStop().getTitle())) {
if (!busStopEdges.get(i).getRouteName().equals(busStopEdges.get(i + 1).getRouteName())
|| !busStopEdges.get(i).getVehicleId().equals(busStopEdges.get(i + 1).getVehicleId())) {
items.remove(items.get(items.size() - 1));
items.add(new DirectionsItem(OUTER_BUS_STOP, busStopEdges.get(i).getTargetBusStop().getTitle(),
busStopEdges.get(i).getTargetBusStop().getTag(), getTimeInHHMM(time), R.drawable.ic_bus_stop_circle));
items.add(new DirectionsItem(BUS_ROUTE, busStopEdges.get(i + 1).getRouteName()
+ " (Bus #" + busStopEdges.get(i + 1).getVehicleId() + ")", busStopEdges.get(i + 1).getRouteTag(), null, 0));
}
continue;
}
// Add inner bus stop
items.add(new DirectionsItem(INNER_BUS_STOP, busStopEdges.get(i).getTargetBusStop().getTitle(),
busStopEdges.get(i).getTargetBusStop().getTag(), getTimeInHHMM(time), android.R.color.transparent));
}
// Add destination bus stop
time += calcWaitTime((int) busStopEdges.get(busStopEdges.size() - 1).getTravelTime());
items.add(new DirectionsItem(OUTER_BUS_STOP, busStopEdges.get(busStopEdges.size() - 1).getTargetBusStop().getTitle(),
busStopEdges.get(busStopEdges.size() - 1).getTargetBusStop().getTag(), getTimeInHHMM(time), R.drawable.ic_bus_stop_circle));
}
public DirectionsAdapter() {
this.items = null;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
View v;
// Set view and viewholder
if (viewType == BUS_ROUTE) {
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_directions_route, parent, false);
return new DirectionsRouteViewHolder(v, new ViewHolderClickListener() {
public void onClick(View v, int position) { /* Do nothing */ }
});
} else {
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_directions_stop, parent, false);
DirectionsStopViewHolder viewHolder = new DirectionsStopViewHolder(v, new ViewHolderClickListener() {
public void onClick(View v, int position) { /* Do nothing */ }
});
// Stylize outer bus stop
if (viewType == OUTER_BUS_STOP) {
Context context = RUDirectApplication.getContext();
viewHolder.title.setTypeface(null, Typeface.BOLD);
viewHolder.title.setTextColor(ContextCompat.getColor(context, android.R.color.black));
viewHolder.title.setTextSize(20);
viewHolder.time.setTypeface(null, Typeface.BOLD);
viewHolder.time.setTextColor(ContextCompat.getColor(context, android.R.color.black));
viewHolder.time.setTextSize(20);
}
return viewHolder;
}
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, int position) {
DirectionsItem item = items.get(position);
if (viewHolder instanceof DirectionsStopViewHolder) {
DirectionsStopViewHolder busStopViewHolder = (DirectionsStopViewHolder) viewHolder;
busStopViewHolder.title.setText(item.getTitle());
busStopViewHolder.icon.setImageResource(item.getIconId());
busStopViewHolder.time.setText(item.getTime());
} else if (viewHolder instanceof DirectionsRouteViewHolder) {
DirectionsRouteViewHolder routeViewHolder = (DirectionsRouteViewHolder) viewHolder;
routeViewHolder.route.setText(item.getTitle());
routeViewHolder.route.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Setup intent
Context context = RUDirectApplication.getContext();
Intent intent = new Intent(activity, RouteActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(context.getString(R.string.bus_tag_message), items.get(viewHolder.getLayoutPosition()).getTag());
intent.putExtra(context.getString(R.string.page_clicked_from_message), "Directions Selector");
// Start new activity to show bus stops
activity.startActivity(intent);
activity.overridePendingTransition(R.anim.abc_grow_fade_in_from_bottom, 0);
}
});
}
}
@Override
public int getItemViewType(int position) {
return items.get(position).getItemType();
}
@Override
public int getItemCount() {
if (items != null) {
return items.size();
}
return 0;
}
// Takes a time in millis and returns the time in HH:MM format
private String getTimeInHHMM(long time) {
return DateFormat.getTimeInstance(DateFormat.SHORT).format(new Date(time));
}
// Calculate the initial wait time / travel time
private int calcWaitTime(int time) {
if (time == 0) { // Handle cases where the initial wait time is 0
return 500;
} else {
return time * (int) DateUtils.MINUTE_IN_MILLIS;
}
}
}