/*
* Copyright (C) 2011 Paul Watts (paulcwatts@gmail.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onebusaway.android.ui;
import org.onebusaway.android.R;
import org.onebusaway.android.app.Application;
import org.onebusaway.android.provider.ObaContract;
import org.onebusaway.android.util.UIUtils;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.support.v4.content.CursorLoader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.text.format.DateUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.ListView;
/**
* Utilities mainly to support queries for the Stops and Routes lists
*
* @author paulw
*/
public final class QueryUtils {
static protected CursorLoader newRecentQuery(
final Context context,
final Uri uri,
final String[] projection,
final String accessTime,
final String useCount) {
// "Recently" means seven days in the past
final long last = System.currentTimeMillis() - 7 * DateUtils.DAY_IN_MILLIS;
Uri limit = uri.buildUpon().appendQueryParameter("limit", "20").build();
String regionWhere = "";
if (Application.get().getCurrentRegion() != null) {
if (projection.equals(QueryUtils.StopList.Columns.PROJECTION)) {
regionWhere = " AND " + StopList.getRegionWhere();
} else if (projection.equals(QueryUtils.RouteList.Columns.PROJECTION)) {
regionWhere = " AND " + RouteList.getRegionWhere();
}
}
return new CursorLoader(context,
limit,
projection,
"((" +
accessTime + " IS NOT NULL AND " +
accessTime + " > " + last +
") OR (" + useCount + " > 0))" + regionWhere,
null,
accessTime + " desc, " +
useCount + " desc"
);
}
static final class RouteList {
public interface Columns {
public static final String[] PROJECTION = {
ObaContract.Routes._ID,
ObaContract.Routes.SHORTNAME,
ObaContract.Routes.LONGNAME,
ObaContract.Routes.URL
};
public static final int COL_ID = 0;
public static final int COL_SHORTNAME = 1;
// private static final int COL_LONGNAME = 2;
public static final int COL_URL = 3;
}
public static SimpleCursorAdapter newAdapter(Context context) {
final String[] from = {
ObaContract.Routes.SHORTNAME,
ObaContract.Routes.LONGNAME
};
final int[] to = {
R.id.short_name,
R.id.long_name
};
SimpleCursorAdapter simpleAdapter =
new SimpleCursorAdapter(context, R.layout.route_list_item,
null, from, to, 0);
return simpleAdapter;
}
static protected String getId(ListView l, int position) {
// Get the cursor and fetch the stop ID from that.
SimpleCursorAdapter cursorAdapter = (SimpleCursorAdapter) l.getAdapter();
Cursor c = cursorAdapter.getCursor();
c.moveToPosition(position - l.getHeaderViewsCount());
return c.getString(Columns.COL_ID);
}
static protected String getUrl(ListView l, int position) {
// Get the cursor and fetch the stop ID from that.
SimpleCursorAdapter cursorAdapter = (SimpleCursorAdapter) l.getAdapter();
Cursor c = cursorAdapter.getCursor();
c.moveToPosition(position - l.getHeaderViewsCount());
return c.getString(Columns.COL_URL);
}
static protected String getRegionWhere() {
return Application.get().getCurrentRegion() == null ? "" :
QueryUtils.getRegionWhere(ObaContract.Routes.REGION_ID,
Application.get().getCurrentRegion().getId());
}
}
static final class StopList {
public interface Columns {
public static final String[] PROJECTION = {
ObaContract.Stops._ID,
ObaContract.Stops.UI_NAME,
ObaContract.Stops.DIRECTION,
ObaContract.Stops.LATITUDE,
ObaContract.Stops.LONGITUDE,
ObaContract.Stops.UI_NAME,
ObaContract.Stops.FAVORITE
};
public static final int COL_ID = 0;
public static final int COL_NAME = 1;
public static final int COL_DIRECTION = 2;
public static final int COL_LATITUDE = 3;
public static final int COL_LONGITUDE = 4;
public static final int COL_UI_NAME = 5;
public static final int COL_FAVORITE = 6;
}
public static SimpleCursorAdapter newAdapter(Context context) {
String[] from = new String[]{
ObaContract.Stops.UI_NAME,
ObaContract.Stops.DIRECTION,
ObaContract.Stops.FAVORITE
};
int[] to = new int[]{
R.id.stop_name,
R.id.direction,
R.id.stop_favorite
};
SimpleCursorAdapter simpleAdapter =
new SimpleCursorAdapter(context, R.layout.stop_list_item, null, from, to, 0);
// We need to convert the direction text (N/NW/E/etc)
// to user level text (North/Northwest/etc..)
simpleAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
if (columnIndex == Columns.COL_FAVORITE) {
ImageView favorite = (ImageView) view.findViewById(R.id.stop_favorite);
if (cursor.getInt(columnIndex) == 1) {
favorite.setVisibility(View.VISIBLE);
// Make sure the star is visible against white background
favorite.setColorFilter(
favorite.getResources().getColor(R.color.navdrawer_icon_tint));
} else {
favorite.setVisibility(View.GONE);
}
return true;
} else if (columnIndex == Columns.COL_DIRECTION) {
UIUtils.setStopDirection(view.findViewById(R.id.direction),
cursor.getString(columnIndex),
true);
return true;
}
return false;
}
});
return simpleAdapter;
}
static protected String getId(ListView l, int position) {
// Get the cursor and fetch the stop ID from that.
SimpleCursorAdapter cursorAdapter = (SimpleCursorAdapter) l.getAdapter();
Cursor c = cursorAdapter.getCursor();
c.moveToPosition(position - l.getHeaderViewsCount());
return c.getString(Columns.COL_ID);
}
static protected String getRegionWhere() {
return Application.get().getCurrentRegion() == null ? "" :
QueryUtils.getRegionWhere(ObaContract.Stops.REGION_ID,
Application.get().getCurrentRegion().getId());
}
}
public static String getRegionWhere(String regionFieldName, long regionId) {
return "(" + regionFieldName + "=" + regionId +
" OR " + regionFieldName + " IS NULL)";
}
/**
* Sets the given route and headsign and stop as a favorite, including checking to make sure that the
* route has already been added to the local provider. If this route/headsign should be marked
* as a favorite for all stops, stopId should be null.
*
* @param routeUri Uri for the route to be added
* @param headsign the headsign to be marked as favorite, along with the routeUri
* @param stopId the stopId to be marked as a favorite, along with with route and headsign. If
* this route/headsign should be marked for all stops, then stopId should be null
* @param routeValues content routeValues to be set for the route details (see ObaContract.RouteColumns)
* (may be null)
* @param favorite true if this route/headsign should be marked as a favorite, false if it
* should not
*/
public static void setFavoriteRouteAndHeadsign(Context context, Uri routeUri,
String headsign, String stopId, ContentValues routeValues, boolean favorite) {
if (routeValues == null) {
routeValues = new ContentValues();
}
if (Application.get().getCurrentRegion() != null) {
routeValues.put(ObaContract.Routes.REGION_ID,
Application.get().getCurrentRegion().getId());
}
String routeId = routeUri.getLastPathSegment();
// Make sure this route has been inserted into the routes table
ObaContract.Routes.insertOrUpdate(context, routeId, routeValues, true);
// Mark the combination of route and headsign as a favorite or not favorite
ObaContract.RouteHeadsignFavorites
.markAsFavorite(context, routeId, headsign, stopId, favorite);
}
}