app/src/main/java/com/itachi1706/busarrivalsg/RecyclerViews/FavouritesRecyclerAdapter.java
package com.itachi1706.busarrivalsg.RecyclerViews;
import android.app.AlertDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.material.snackbar.Snackbar;
import com.itachi1706.busarrivalsg.BusLocationMapsActivity;
import com.itachi1706.busarrivalsg.BusLocationMapsDialogFragment;
import com.itachi1706.busarrivalsg.BusServicesAtStopRecyclerActivity;
import com.itachi1706.busarrivalsg.Database.BusStopsDB;
import com.itachi1706.busarrivalsg.R;
import com.itachi1706.busarrivalsg.Services.BusStorage;
import com.itachi1706.busarrivalsg.gsonObjects.sgLTA.BusStopJSON;
import com.itachi1706.busarrivalsg.objects.BusServices;
import com.itachi1706.busarrivalsg.objects.BusStatus;
import com.itachi1706.busarrivalsg.util.BusesUtil;
import com.itachi1706.busarrivalsg.util.StaticVariables;
import com.itachi1706.helperlib.helpers.LogHelper;
import com.itachi1706.helperlib.helpers.PrefHelper;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Created by Kenneth on 31/10/2015.
* for SingBuses in package com.itachi1706.busarrivalsg.RecyclerViews
*/
public class FavouritesRecyclerAdapter extends RecyclerView.Adapter<FavouritesRecyclerAdapter.FavouritesViewHolder> {
/**
* This recycler adapter is used in the internal retrieve all bus services from main activity's favourites list
*/
private List<BusServices> items;
private final AppCompatActivity activity;
private final boolean serverTime;
private String currentTime;
public FavouritesRecyclerAdapter(List<BusServices> objectList, AppCompatActivity activity, boolean useServerTime){
this.items = objectList;
this.activity = activity;
this.serverTime = useServerTime;
}
public void updateAdapter(List<BusServices> newObjects, String currentTime){
this.items = newObjects;
this.currentTime = currentTime;
notifyDataSetChanged();
}
public boolean moveItem(int from, int to) {
if (from < to) {
for (int i = from; i < to; i++) {
Collections.swap(items, i, i + 1);
}
} else {
for (int i = from; i > to; i--) {
Collections.swap(items, i, i - 1);
}
}
notifyItemMoved(from, to);
final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext());
BusStorage.updateBusJSON(sp, (ArrayList<BusServices>) items);
return true;
}
@NonNull
@Override
public FavouritesViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View busServiceView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recyclerview_bus_numbers, parent, false);
return new FavouritesViewHolder(busServiceView);
}
@Override
public void onBindViewHolder(FavouritesViewHolder holder, int position) {
BusServices i = items.get(position);
holder.busOperator.setText(i.getOperator());
holder.busOperator.setTextColor(BusesUtil.INSTANCE.getOperatorColor(activity, i.getOperator()));
holder.busNumber.setText(i.getServiceNo());
holder.stopName.setVisibility(View.VISIBLE);
holder.stopName.setText(i.getStopName().trim() + " (" + i.getStopID().trim() + ")");
if (!i.isObtainedNextData()) {
processing(holder.busArrivalNow);
processing(holder.busArrivalNext);
processing(holder.busArrivalSub);
return;
}
if (!i.isSvcStatus()) {
holder.operatingStatus.setText(activity.getString(R.string.service_not_operational));
holder.operatingStatus.setTextColor(Color.RED);
notArriving(holder.busArrivalNow, holder.wheelchairNow, holder.busTypeNow);
notArriving(holder.busArrivalNext, holder.wheelchairNext, holder.busTypeNext);
notArriving(holder.busArrivalSub, holder.wheelchairSub, holder.busTypeSub);
return;
}
holder.operatingStatus.setText(activity.getString(R.string.service_operational));
holder.operatingStatus.setTextColor(PrefHelper.isNightModeEnabled(activity) ? Color.GREEN : ContextCompat.getColor(activity, R.color.dark_green));
//Current Bus
if (i.getCurrentBus().getEstimatedArrival() == null) notArriving(holder.busArrivalNow, holder.wheelchairNow, holder.busTypeNow);
else {
long est = StaticVariables.INSTANCE.parseLTAEstimateArrival(i.getCurrentBus().getEstimatedArrival(), serverTime, currentTime);
String arrivalStatusNow;
if (est == -9999)
arrivalStatusNow = "-";
else if (est <= 0)
arrivalStatusNow = "Arr";
else if (est == 1)
arrivalStatusNow = est + "";
else
arrivalStatusNow = est + "";
holder.busArrivalNow.setText(arrivalStatusNow);
BusesUtil.INSTANCE.applyColorLoad(holder.busArrivalNow, i.getCurrentBus().getLoad());
holder.wheelchairNow.setVisibility(View.INVISIBLE);
if (i.getCurrentBus().isWheelChairAccessible())
holder.wheelchairNow.setVisibility(View.VISIBLE);
holder.busTypeNow.setVisibility(View.INVISIBLE);
if (!arrivalStatusNow.equalsIgnoreCase("-")) {
holder.busTypeNow.setText(BusesUtil.INSTANCE.getType(i.getCurrentBus().getBusType()));
holder.busTypeNow.setVisibility(View.VISIBLE);
}
holder.busArrivalNow.setOnClickListener(new ArrivalButton(i, i.getStopID(), i.getServiceNo(), StaticVariables.CUR));
}
//2nd Bus (Next Bus)
if (i.getNextBus().getEstimatedArrival() == null) notArriving(holder.busArrivalNext, holder.wheelchairNext, holder.busTypeNext);
else {
long est = StaticVariables.INSTANCE.parseLTAEstimateArrival(i.getNextBus().getEstimatedArrival(), serverTime, currentTime);
String arrivalStatusNext;
if (est == -9999)
arrivalStatusNext = "-";
else if (est <= 0)
arrivalStatusNext = "Arr";
else if (est == 1)
arrivalStatusNext = est + "";
else
arrivalStatusNext = est + "";
holder.busArrivalNext.setText(arrivalStatusNext);
BusesUtil.INSTANCE.applyColorLoad(holder.busArrivalNext, i.getNextBus().getLoad());
holder.wheelchairNext.setVisibility(View.INVISIBLE);
if (i.getNextBus().isWheelChairAccessible())
holder.wheelchairNext.setVisibility(View.VISIBLE);
holder.busTypeNext.setVisibility(View.INVISIBLE);
if (!arrivalStatusNext.equalsIgnoreCase("-")) {
holder.busTypeNext.setText(BusesUtil.INSTANCE.getType(i.getNextBus().getBusType()));
holder.busTypeNext.setVisibility(View.VISIBLE);
}
holder.busArrivalNext.setOnClickListener(new ArrivalButton(i, i.getStopID(), i.getServiceNo(), StaticVariables.NEXT));
}
//3rd bus (Subsequent Bus)
if (i.getSubsequentBus() == null){
comingSoon(holder.busArrivalSub);
return;
}
if (i.getSubsequentBus().getEstimatedArrival() == null) notArriving(holder.busArrivalSub, holder.wheelchairSub, holder.busTypeSub);
else {
long est = StaticVariables.INSTANCE.parseLTAEstimateArrival(i.getSubsequentBus().getEstimatedArrival(), serverTime, currentTime);
String arrivalStatusSub;
if (est == -9999)
arrivalStatusSub = "-";
else if (est <= 0)
arrivalStatusSub = "Arr";
else if (est == 1)
arrivalStatusSub = est + "";
else
arrivalStatusSub = est + "";
holder.busArrivalSub.setText(arrivalStatusSub);
BusesUtil.INSTANCE.applyColorLoad(holder.busArrivalSub, i.getSubsequentBus().getLoad());
holder.wheelchairSub.setVisibility(View.INVISIBLE);
if (i.getSubsequentBus().isWheelChairAccessible())
holder.wheelchairSub.setVisibility(View.VISIBLE);
holder.busTypeSub.setVisibility(View.INVISIBLE);
if (!arrivalStatusSub.equalsIgnoreCase("-")) {
holder.busTypeSub.setText(BusesUtil.INSTANCE.getType(i.getSubsequentBus().getBusType()));
holder.busTypeSub.setVisibility(View.VISIBLE);
}
holder.busArrivalSub.setOnClickListener(new ArrivalButton(i, i.getStopID(), i.getServiceNo(), StaticVariables.SUB));
}
}
private void comingSoon(TextView view){
view.setText(R.string.feature_coming_soon);
view.setTextColor(Color.GRAY);
}
private void processing(TextView view){
view.setText("...");
view.setTextColor(Color.GRAY);
}
private void notArriving(TextView view, ImageView wheelchair, TextView busType){
view.setText("-");
view.setTextColor(Color.GRAY);
wheelchair.setVisibility(View.INVISIBLE);
busType.setVisibility(View.INVISIBLE);
view.setOnClickListener(new UnavailableButton());
}
@Override
public int getItemCount() {
return items.size();
}
public boolean removeFavourite(final int position) {
final BusServices item = items.get(position);
String message = activity.getString(R.string.dialog_message_remove_from_fav_with_stop_name, item.getServiceNo(), item.getStopName(), item.getStopID());
// Companion addition
final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext());
/*switch (sp.getString("companionDevice", "none")) {
}*/
AlertDialog alert = new AlertDialog.Builder(activity).setTitle(R.string.dialog_title_remove_from_fav)
.setMessage(message)
.setPositiveButton(android.R.string.yes, (dialog, which) -> {
//Remove from favourites
for (int i = 0; i < items.size(); i++){
BusServices s = items.get(i);
if (s.getStopID().equalsIgnoreCase(item.getStopID()) && s.getServiceNo().equalsIgnoreCase(item.getServiceNo())) {
items.remove(i);
break;
}
}
BusStorage.updateBusJSON(sp, (ArrayList<BusServices>) items);
notifyItemRemoved(position);
Toast.makeText(activity.getApplicationContext(), R.string.toast_message_remove_from_fav, Toast.LENGTH_SHORT).show();
}).setNegativeButton(android.R.string.no, null).create();
alert.setOnDismissListener(dialogInterface -> notifyItemChanged(position));
alert.show();
return true;
}
class FavouritesViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
TextView busOperator, busNumber, operatingStatus, stopName;
TextView busTypeNow, busTypeNext, busTypeSub;
Button busArrivalNow, busArrivalNext, busArrivalSub;
ImageView wheelchairNow, wheelchairNext, wheelchairSub;
FavouritesViewHolder(View v){
super(v);
busOperator = v.findViewById(R.id.tvBusOperator);
busNumber = v.findViewById(R.id.tvBusService);
busArrivalNow = v.findViewById(R.id.btnBusArrivalNow);
busArrivalNext = v.findViewById(R.id.btnBusArrivalNext);
busArrivalSub = v.findViewById(R.id.btnBusArrivalSub);
operatingStatus = v.findViewById(R.id.tvBusStatus);
stopName = v.findViewById(R.id.tvBusStopName);
wheelchairNow = v.findViewById(R.id.ivWheelchairNow);
wheelchairNext = v.findViewById(R.id.ivWheelchairNext);
wheelchairSub = v.findViewById(R.id.ivWheelchairSub);
busTypeNow = v.findViewById(R.id.tvBusTypeNow);
busTypeNext = v.findViewById(R.id.tvBusTypeNext);
busTypeSub = v.findViewById(R.id.tvBusTypeSub);
wheelchairNow.setVisibility(View.INVISIBLE);
wheelchairNext.setVisibility(View.INVISIBLE);
wheelchairSub.setVisibility(View.INVISIBLE);
busTypeNow.setVisibility(View.INVISIBLE);
busTypeNext.setVisibility(View.INVISIBLE);
busTypeSub.setVisibility(View.INVISIBLE);
v.setOnLongClickListener(this);
v.setOnClickListener(this);
busArrivalNext.setOnLongClickListener(this);
busArrivalNow.setOnLongClickListener(this);
busArrivalSub.setOnLongClickListener(this);
}
@Override
public void onClick(View v) {
int position = this.getLayoutPosition();
final BusServices item = items.get(position);
LogHelper.d("Size", "" + items.size());
Intent serviceIntent = new Intent(activity, BusServicesAtStopRecyclerActivity.class);
serviceIntent.putExtra("stopCode", item.getStopID());
serviceIntent.putExtra("stopName", item.getStopName());
activity.startActivity(serviceIntent);
}
@Override
public boolean onLongClick(View v) {
int position = this.getLayoutPosition();
final BusServices item = items.get(position);
final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext());
if (sp.getBoolean("showFavHint", true)) {
String message = activity.getString(R.string.snackbar_message_remove_from_fav_with_stop_name, item.getServiceNo());
Snackbar.make(v, message, Snackbar.LENGTH_SHORT).setAction("Hide Tips", view -> sp.edit().putBoolean("showFavHint", false).apply()).show();
}
return false;
}
}
private static class UnavailableButton implements View.OnClickListener {
@Override
public void onClick(View v) {
new AlertDialog.Builder(v.getContext()).setTitle(R.string.dialog_title_bus_timing_unavailable)
.setMessage(R.string.dialog_message_bus_timing_unavailable)
.setPositiveButton(R.string.dialog_action_positive_close, null).show();
}
}
private class ArrivalButton implements View.OnClickListener{
private double longitude, latitude;
private String stopCode, serviceNo;
private final BusServices busObj;
private final int state;
ArrivalButton(BusServices busObj, String busStopCode, String svcNo, int state) {
BusStatus status = (state == StaticVariables.CUR) ? busObj.getCurrentBus() :
(state == StaticVariables.NEXT) ? busObj.getNextBus() : busObj.getSubsequentBus();
this.state = state;
this.busObj = busObj;
this.longitude = status.getLongitude();
this.latitude = status.getLatitude();
this.stopCode = busStopCode.trim();
this.serviceNo = svcNo.trim();
}
@Override
public void onClick(View v) {
if (longitude == -1000 || latitude == -1000){
//Error, invalid location
new AlertDialog.Builder(activity).setTitle(R.string.dialog_title_bus_location_unavailable)
.setMessage(R.string.dialog_message_bus_location_unavailable)
.setPositiveButton(R.string.dialog_action_positive_close, null).show();
return;
}
if (longitude == -11 && latitude == -11){
new AlertDialog.Builder(activity).setTitle(R.string.dialog_title_bus_timing_unavailable)
.setMessage(R.string.dialog_message_bus_timing_unavailable)
.setPositiveButton(R.string.dialog_action_positive_close, null).show();
return;
}
if (latitude == 0 && longitude == 0) {
new AlertDialog.Builder(activity).setTitle("Bus Service in Depot")
.setMessage("The Bus Service is currently still in the depot so no location can be obtained!")
.setPositiveButton("Close", null).show();
return;
}
//Check if Google Play Services is enabled
int code = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(activity);
if (code != ConnectionResult.SUCCESS){
GoogleApiAvailability.getInstance().getErrorDialog(activity, code, 0);
return;
}
Intent mapsIntent = new Intent(activity, BusLocationMapsActivity.class);
mapsIntent.putExtra("busCode", stopCode);
mapsIntent.putExtra("busSvcNo", serviceNo);
// 3 Bus statuses
mapsIntent.putExtra("lat1", busObj.getCurrentBus().getLatitude());
mapsIntent.putExtra("lng1", busObj.getCurrentBus().getLongitude());
mapsIntent.putExtra("arr1", busObj.getCurrentBus().getEstimatedArrival());
mapsIntent.putExtra("lat2", busObj.getNextBus().getLatitude());
mapsIntent.putExtra("lng2", busObj.getNextBus().getLongitude());
mapsIntent.putExtra("arr2", busObj.getNextBus().getEstimatedArrival());
mapsIntent.putExtra("lat3", busObj.getSubsequentBus().getLatitude());
mapsIntent.putExtra("lng3", busObj.getSubsequentBus().getLongitude());
mapsIntent.putExtra("arr3", busObj.getSubsequentBus().getEstimatedArrival());
mapsIntent.putExtra("type1", busObj.getCurrentBus().getBusType());
mapsIntent.putExtra("type2", busObj.getNextBus().getBusType());
mapsIntent.putExtra("type3", busObj.getSubsequentBus().getBusType());
mapsIntent.putExtra("sTime", currentTime);
mapsIntent.putExtra("state", state);
//Get Bus stop longitude and latitude
BusStopsDB db = new BusStopsDB(activity);
BusStopJSON busStop = db.getBusStopByBusStopCode(stopCode);
if (busStop != null) {
mapsIntent.putExtra("buslat", busStop.getLatitude());
mapsIntent.putExtra("buslng", busStop.getLongitude());
}
if (!PreferenceManager.getDefaultSharedPreferences(v.getContext()).getBoolean("mapPopup", true))
activity.startActivity(mapsIntent);
else {
final BusLocationMapsDialogFragment dialog = new BusLocationMapsDialogFragment();
dialog.setArguments(mapsIntent.getExtras());
dialog.show(activity.getSupportFragmentManager(), "123");
}
}
}
}