io.github.runassudo.ptoffline.utils.TransportrUtils.java Source code

Java tutorial

Introduction

Here is the source code for io.github.runassudo.ptoffline.utils.TransportrUtils.java

Source

/*    Transportr
 *    Copyright (C) 2013 - 2016 Torsten Grote
 *
 *    This program is Free Software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as
 *    published by the Free Software Foundation, either version 3 of the
 *    License, or (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package io.github.runassudo.ptoffline.utils;

import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.v4.content.ContextCompat;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import org.apmem.tools.layouts.FlowLayout;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import io.github.runassudo.ptoffline.FavLocation;
import io.github.runassudo.ptoffline.Preferences;
import io.github.runassudo.ptoffline.R;
import io.github.runassudo.ptoffline.WrapLocation;
import io.github.runassudo.ptoffline.activities.MainActivity;
import io.github.runassudo.ptoffline.activities.MapActivity;
import io.github.runassudo.ptoffline.data.RecentsDB;
import io.github.runassudo.ptoffline.fragments.DeparturesFragment;
import io.github.runassudo.ptoffline.fragments.DirectionsFragment;
import io.github.runassudo.ptoffline.fragments.NearbyStationsFragment;
import io.github.runassudo.ptoffline.ui.LineView;
import io.github.runassudo.ptoffline.pte.NetworkProvider.Optimize;
import io.github.runassudo.ptoffline.pte.NetworkProvider.WalkSpeed;
import io.github.runassudo.ptoffline.pte.dto.Line;
import io.github.runassudo.ptoffline.pte.dto.Location;
import io.github.runassudo.ptoffline.pte.dto.LocationType;
import io.github.runassudo.ptoffline.pte.dto.Product;
import io.github.runassudo.ptoffline.pte.dto.Stop;
import io.github.runassudo.ptoffline.pte.dto.Trip;
import io.github.runassudo.ptoffline.pte.dto.Trip.Leg;

import static io.github.runassudo.ptoffline.WrapLocation.WrapType.GPS;
import static io.github.runassudo.ptoffline.WrapLocation.WrapType.HOME;
import static io.github.runassudo.ptoffline.WrapLocation.WrapType.MAP;
import static io.github.runassudo.ptoffline.data.RecentsDB.getFavLocationList;

public class TransportrUtils {

    static private void addLineBox(Context context, ViewGroup lineLayout, Line line, int index,
            boolean check_duplicates) {
        if (check_duplicates) {
            // loop through all line boxes in the linearLayout
            for (int i = 0; i < lineLayout.getChildCount(); ++i) {
                // check if current line box is the same as the one we are about to add
                if (line.label != null && line.label.equals(((LineView) lineLayout.getChildAt(i)).getLabel())) {
                    // lines are equal, so bail out from here and don't add new line box
                    return;
                }
            }
        }

        LineView lineView = new LineView(context);
        lineView.setLine(line);

        // set margin, because setting in in xml does not work
        FlowLayout.LayoutParams llp = new FlowLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        llp.setMargins(0, 5, 15, 5);
        lineView.setLayoutParams(llp);

        lineLayout.addView(lineView, index);
    }

    static public void addLineBox(Context context, ViewGroup lineLayout, Line line) {
        addLineBox(context, lineLayout, line, lineLayout.getChildCount());
    }

    static public void addLineBox(Context context, ViewGroup lineLayout, Line line, int index) {
        addLineBox(context, lineLayout, line, index, false);
    }

    static public void addWalkingBox(Context context, ViewGroup lineLayout, int index) {
        ImageView v = (ImageView) LayoutInflater.from(context).inflate(R.layout.walking_box, lineLayout, false);

        // set margin, because setting in in xml does not work
        FlowLayout.LayoutParams llp = new FlowLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        llp.setMargins(0, 5, 15, 5);
        v.setLayoutParams(llp);

        lineLayout.addView(v, index);
    }

    static public void addWalkingBox(Context context, ViewGroup lineLayout) {
        addWalkingBox(context, lineLayout, lineLayout.getChildCount());
    }

    static public void setArrivalTimes(Context context, TextView timeView, TextView delayView, Stop stop) {
        if (stop.getArrivalTime() == null)
            return;

        Date time = new Date(stop.getArrivalTime().getTime());

        if (stop.isArrivalTimePredicted() && stop.getArrivalDelay() != null) {
            long delay = stop.getArrivalDelay();
            time.setTime(time.getTime() - delay);
            delayView.setText(getDelayText(delay));
        }
        timeView.setText(DateUtils.getTime(context, time));
    }

    static public void setDepartureTimes(Context context, TextView timeView, TextView delayView, Stop stop) {
        if (stop.getDepartureTime() == null)
            return;

        Date time = new Date(stop.getDepartureTime().getTime());

        if (stop.isDepartureTimePredicted() && stop.getDepartureDelay() != null) {
            long delay = stop.getDepartureDelay();
            time.setTime(time.getTime() - delay);
            delayView.setText(getDelayText(delay));
        }
        timeView.setText(DateUtils.getTime(context, time));
    }

    static private String getDelayText(long delay) {
        if (delay > 0) {
            return "+" + Long.toString(delay / 1000 / 60);
        } else if (delay < 0) {
            return Long.toString(delay / 1000 / 60);
        } else {
            return null;
        }
    }

    static private String tripToSubject(Context context, Trip trip, boolean tag) {
        String str = "";

        if (tag)
            str += "[" + context.getResources().getString(R.string.app_name) + "] ";

        str += DateUtils.getTime(context, trip.getFirstDepartureTime()) + " ";
        str += getLocName(trip.from);
        str += "  ";
        str += getLocName(trip.to) + " ";
        str += DateUtils.getTime(context, trip.getLastArrivalTime());
        str += " (" + DateUtils.getDate(context, trip.getFirstDepartureTime()) + ")";

        return str;
    }

    static private String tripToString(Context context, Trip trip) {
        String str = context.getString(R.string.times_include_delays) + "\n\n";

        for (Leg leg : trip.legs) {
            str += legToString(context, leg) + "\n\n";
        }

        return str;
    }

    static public String legToString(Context context, Leg leg) {
        String str = "";
        String apos = "";

        str += DateUtils.getTime(context, leg.getDepartureTime()) + " ";
        str += getLocName(leg.departure);

        if (leg instanceof Trip.Public) {
            Trip.Public pub = (Trip.Public) leg;
            if (pub.line != null && pub.line.label != null) {
                str += " (" + pub.line.label;
                if (pub.destination != null)
                    str += "  " + getLocName(pub.destination);
                str += ")";
            }
            // show departure position if existing
            if (pub.getDeparturePosition() != null) {
                str += " - " + context.getString(R.string.position) + ": " + pub.getDeparturePosition().name;
            }
            // remember arrival position if existing
            if (pub.getArrivalPosition() != null) {
                apos += " - " + context.getString(R.string.position) + ": " + pub.getArrivalPosition().name;
            }
        } else if (leg instanceof Trip.Individual) {
            Trip.Individual ind = (Trip.Individual) leg;
            str += " (" + context.getString(R.string.walk) + " ";
            if (ind.distance > 0)
                str += ind.distance + context.getResources().getString(R.string.meter) + " ";
            if (ind.min > 0)
                str += ind.min + context.getResources().getString(R.string.min);
            str += ")";
        }

        str += "\n";
        str += DateUtils.getTime(context, leg.getArrivalTime()) + " ";
        str += getLocName(leg.arrival);
        str += apos;

        return str;
    }

    static public String productToString(Context context, Product p) {
        if (p == Product.HIGH_SPEED_TRAIN)
            return context.getString(R.string.product_high_speed_train);
        else if (p == Product.REGIONAL_TRAIN)
            return context.getString(R.string.product_regional_train);
        else if (p == Product.SUBURBAN_TRAIN)
            return context.getString(R.string.product_suburban_train);
        else if (p == Product.SUBWAY)
            return context.getString(R.string.product_subway);
        else if (p == Product.TRAM)
            return context.getString(R.string.product_tram);
        else if (p == Product.BUS)
            return context.getString(R.string.product_bus);
        else if (p == Product.FERRY)
            return context.getString(R.string.product_ferry);
        else if (p == Product.CABLECAR)
            return context.getString(R.string.product_cablecar);
        else if (p == Product.ON_DEMAND)
            return context.getString(R.string.product_on_demand);
        else
            return "";

    }

    static public int getDrawableForProduct(Product p) {
        int image_res = R.drawable.product_bus;

        switch (p) {
        case HIGH_SPEED_TRAIN:
            image_res = R.drawable.product_high_speed_train;
            break;
        case REGIONAL_TRAIN:
            image_res = R.drawable.product_regional_train;
            break;
        case SUBURBAN_TRAIN:
            image_res = R.drawable.product_suburban_train;
            break;
        case SUBWAY:
            image_res = R.drawable.product_subway;
            break;
        case TRAM:
            image_res = R.drawable.product_tram;
            break;
        case BUS:
            image_res = R.drawable.product_bus;
            break;
        case FERRY:
            image_res = R.drawable.product_ferry;
            break;
        case CABLECAR:
            image_res = R.drawable.product_cablecar;
            break;
        case ON_DEMAND:
            image_res = R.drawable.product_on_demand;
            break;
        }

        return image_res;
    }

    static public void share(Context context, Trip trip) {
        //noinspection deprecation
        Intent sendIntent = new Intent().setAction(Intent.ACTION_SEND)
                .putExtra(Intent.EXTRA_SUBJECT, tripToSubject(context, trip, true))
                .putExtra(Intent.EXTRA_TEXT, tripToString(context, trip)).setType("text/plain")
                .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
        context.startActivity(
                Intent.createChooser(sendIntent, context.getResources().getText(R.string.share_trip_via)));
    }

    static public void intoCalendar(Context context, Trip trip) {
        Intent intent = new Intent(Intent.ACTION_EDIT).setType("vnd.android.cursor.item/event")
                .putExtra("beginTime", trip.getFirstDepartureTime().getTime())
                .putExtra("endTime", trip.getLastArrivalTime().getTime())
                .putExtra("title", trip.from.name + "  " + trip.to.name)
                .putExtra("description", TransportrUtils.tripToString(context, trip));
        if (trip.from.place != null)
            intent.putExtra("eventLocation", trip.from.place);
        context.startActivity(intent);
    }

    static public void presetDirections(Context context, Location from, Location via, Location to) {
        Intent intent = new Intent(context, MainActivity.class);
        intent.setAction(DirectionsFragment.TAG);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        intent.putExtra("from", new WrapLocation(from));
        intent.putExtra("via", new WrapLocation(via));
        intent.putExtra("to", new WrapLocation(to));
        intent.putExtra("search", false);

        context.startActivity(intent);
    }

    static public void findDirections(Context context, Location from, Location via, Location to, Date date) {
        Intent intent = new Intent(context, MainActivity.class);
        intent.setAction(DirectionsFragment.TAG);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        intent.putExtra("from", new WrapLocation(from));
        intent.putExtra("via", new WrapLocation(via));
        intent.putExtra("to", new WrapLocation(to));
        intent.putExtra("search", true);
        if (date != null) {
            intent.putExtra("date", date);
        }

        context.startActivity(intent);
    }

    static public void findDirections(Context context, Location from, Location via, Location to) {
        findDirections(context, from, via, to, null);
    }

    static public void findDepartures(Context context, Location loc) {
        Intent intent = new Intent(context, MainActivity.class);
        intent.setAction(DeparturesFragment.TAG);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        intent.putExtra("location", loc);

        context.startActivity(intent);
    }

    static public void findNearbyStations(Context context, Location loc) {
        Intent intent = new Intent(context, MainActivity.class);
        intent.setAction(NearbyStationsFragment.TAG);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        intent.putExtra("location", loc);

        context.startActivity(intent);
    }

    static public void showMap(Context context) {
        Intent intent = new Intent(context, MapActivity.class);
        intent.setAction(MapActivity.SHOW_AREA);

        context.startActivity(intent);
    }

    static public void showLocationsOnMap(Context context, ArrayList<Location> loc_list, Location my_loc) {
        // show station on internal map
        Intent intent = new Intent(context, MapActivity.class);
        intent.setAction(MapActivity.SHOW_LOCATIONS);
        intent.putExtra(MapActivity.LOCATIONS, loc_list);
        if (my_loc != null) {
            intent.putExtra(MapActivity.LOCATION, my_loc);
        }
        context.startActivity(intent);
    }

    static public void showLocationsOnMap(Context context, ArrayList<Location> loc_list) {
        showLocationsOnMap(context, loc_list, null);
    }

    static public void showLocationOnMap(Context context, Location loc, Location loc2) {
        ArrayList<Location> loc_list = new ArrayList<>(1);
        loc_list.add(loc);

        showLocationsOnMap(context, loc_list, loc2);
    }

    static public void showTripOnMap(Context context, Trip trip) {
        Intent intent = new Intent(context, MapActivity.class);
        intent.setAction(MapActivity.SHOW_TRIP);
        intent.putExtra(MapActivity.TRIP, trip);
        context.startActivity(intent);
    }

    static public void startGeoIntent(Context context, Location loc) {
        String lat = Double.toString(loc.lat / 1E6);
        String lon = Double.toString(loc.lon / 1E6);

        String uri1 = "geo:0,0?q=" + lat + "," + lon;
        String uri2;

        try {
            uri2 = "(" + URLEncoder.encode(TransportrUtils.getLocName(loc), "utf-8") + ")";
        } catch (UnsupportedEncodingException e) {
            uri2 = "(" + TransportrUtils.getLocName(loc) + ")";
        }

        Uri geo = Uri.parse(uri1 + uri2);

        Log.d(context.getClass().getCanonicalName(), "Starting geo intent: " + geo.toString());

        // show station on external map
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setData(geo);
        if (intent.resolveActivity(context.getPackageManager()) != null) {
            context.startActivity(intent);
        }
    }

    static public int computeDistance(Location location1, Location location2) {
        if (location1 == null || location2 == null)
            return -1;
        if (!location1.hasLocation() || !location2.hasLocation())
            return -1;

        android.location.Location loc1 = new android.location.Location("");
        loc1.setLatitude(location1.lat / 1E6);
        loc1.setLongitude(location1.lon / 1E6);

        android.location.Location loc2 = new android.location.Location("");
        loc2.setLatitude(location2.lat / 1E6);
        loc2.setLongitude(location2.lon / 1E6);

        return Math.round(loc1.distanceTo(loc2));
    }

    static public void copyToClipboard(Context context, String text) {
        ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
        ClipData clip = ClipData.newPlainText("label", text);
        clipboard.setPrimaryClip(clip);
    }

    static public String getLocName(Location l) {
        if (l == null) {
            return "";
        } else if (l.type.equals(LocationType.COORD)) {
            return getCoordinationName(l.getLatAsDouble(), l.getLonAsDouble());
        } else if (l.uniqueShortName() != null) {
            return l.uniqueShortName();
        } else {
            return "";
        }
    }

    static public String getFullLocName(Location l) {
        if (l.hasName()) {
            return l.place == null ? l.uniqueShortName() : l.name + ", " + l.place;
        } else {
            return getLocName(l);
        }
    }

    static public String getCoordinationName(double lat, double lon) {
        String latStr;
        try {
            latStr = String.valueOf(lat).substring(0, 7);
        } catch (StringIndexOutOfBoundsException e) {
            latStr = String.valueOf(lat);
        }

        String lonStr;
        try {
            lonStr = String.valueOf(lon).substring(0, 7);
        } catch (StringIndexOutOfBoundsException e) {
            lonStr = String.valueOf(lon);
        }

        return latStr + "/" + lonStr;
    }

    static public Drawable getTintedDrawable(Context context, boolean dark, Drawable drawable) {
        if (dark) {
            drawable.setColorFilter(ContextCompat.getColor(context, R.color.drawableTintDark),
                    PorterDuff.Mode.SRC_IN);
        } else {
            drawable.setColorFilter(ContextCompat.getColor(context, R.color.drawableTintLight),
                    PorterDuff.Mode.SRC_IN);
        }
        return drawable.mutate();
    }

    static public Drawable getTintedDrawable(Context context, Drawable drawable) {
        if (Preferences.darkThemeEnabled(context)) {
            return getTintedDrawable(context, true, drawable);
        } else {
            return getTintedDrawable(context, false, drawable);
        }
    }

    static public Drawable getTintedDrawable(Context context, boolean dark, int res) {
        return getTintedDrawable(context, dark, ContextCompat.getDrawable(context, res));
    }

    static public Drawable getTintedDrawable(Context context, int res) {
        return getTintedDrawable(context, ContextCompat.getDrawable(context, res));
    }

    static private Drawable getToolbarDrawable(Context context, Drawable drawable) {
        if (drawable != null) {
            drawable.setColorFilter(ContextCompat.getColor(context, R.color.drawableTintDark),
                    PorterDuff.Mode.SRC_IN);
            drawable.setAlpha(255);
            drawable.mutate();
        }
        return drawable;
    }

    static public Drawable getToolbarDrawable(Context context, int res) {
        return getToolbarDrawable(context, ContextCompat.getDrawable(context, res));
    }

    static public void fixToolbarIcon(Context context, MenuItem item) {
        item.setIcon(getToolbarDrawable(context, item.getIcon()));
    }

    static private int getButtonIconColor(Context context, boolean on) {
        if (Preferences.darkThemeEnabled(context)) {
            if (on)
                return ContextCompat.getColor(context, R.color.drawableTintDark);
            else
                return ContextCompat.getColor(context, R.color.drawableTintLight);
        } else {
            if (on)
                return Color.BLACK;
            else
                return ContextCompat.getColor(context, R.color.drawableTintLight);
        }
    }

    static public int getButtonIconColor(Context context) {
        return getButtonIconColor(context, true);
    }

    static public Drawable getDrawableForLocation(Context context, WrapLocation w, boolean is_fav) {
        if (w == null || w.getLocation() == null)
            return null;
        Location l = w.getLocation();

        if (w.getType() == HOME || l.equals(RecentsDB.getHome(context))) {
            return getTintedDrawable(context, R.drawable.ic_action_home);
        } else if (w.getType() == GPS) {
            return getTintedDrawable(context, R.drawable.ic_gps);
        } else if (w.getType() == MAP) {
            return getTintedDrawable(context, R.drawable.ic_action_location_map);
        } else if (is_fav) {
            return getTintedDrawable(context, R.drawable.ic_action_star);
        } else {
            if (l.type.equals(LocationType.ADDRESS)) {
                return getTintedDrawable(context, R.drawable.ic_location_address);
            } else if (l.type.equals(LocationType.POI)) {
                return getTintedDrawable(context, R.drawable.ic_action_about);
            } else if (l.type.equals(LocationType.STATION)) {
                return getTintedDrawable(context, R.drawable.ic_tab_stations);
            } else if (l.type.equals(LocationType.COORD)) {
                return getTintedDrawable(context, R.drawable.ic_gps);
            } else {
                return null;
            }
        }
    }

    static public Drawable getDrawableForLocation(Context context, Location l) {
        if (l == null)
            return getTintedDrawable(context, R.drawable.ic_location);

        List<WrapLocation> fav_list = getFavLocationList(context, FavLocation.LOC_TYPE.FROM, false);
        WrapLocation w = new WrapLocation(l);

        return getDrawableForLocation(context, w, fav_list.contains(w));
    }

    static public void setFavState(Context context, MenuItem item, boolean is_fav, boolean is_toolbar) {
        if (is_fav) {
            item.setTitle(R.string.action_unfav_trip);
            item.setIcon(is_toolbar ? getToolbarDrawable(context, R.drawable.ic_action_star)
                    : getTintedDrawable(context, R.drawable.ic_action_star));
        } else {
            item.setTitle(R.string.action_fav_trip);
            item.setIcon(is_toolbar ? getToolbarDrawable(context, R.drawable.ic_action_star_empty)
                    : getTintedDrawable(context, R.drawable.ic_action_star_empty));
        }
    }

    static public Optimize getOptimize(Context context) {
        String optimizeString = Preferences.getOptimize(context).toUpperCase();

        return Optimize.valueOf(optimizeString);
    }

    static public WalkSpeed getWalkSpeed(Context context) {
        String walkString = Preferences.getWalkSpeed(context).toUpperCase();

        return WalkSpeed.valueOf(walkString);
    }

    static public int getDragDistance(Context context) {
        final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        return (int) (25 * metrics.density);
    }

    public static Intent getShortcutIntent(Context context) {
        Intent shortcutIntent = new Intent(DirectionsFragment.TAG, Uri.EMPTY, context, MainActivity.class);
        shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        shortcutIntent.putExtra("special", DirectionsFragment.TASK_BRING_ME_HOME);
        return shortcutIntent;
    }
}