Commits

littledot5566  committed eb424d0

*Liberated location data from Expedition to Route. *Completed implementation of Route. *Changed ExpeditionActivity to use Route. *Completed TWOANDFRO expedition mode.

  • Participants
  • Parent commits 4edbd6d

Comments (0)

Files changed (10)

File res/layout/expedition_act.xml

         android:layout_width="fill_parent"
         android:layout_height="0dp"
         android:layout_weight="1"
-        android:apiKey="0-0tVBYzo78F-qe7esdacwXkvQC1qjv3vYvBkbA"
+        android:apiKey="0-0tVBYzo78FEXFOBhiBi06dI13u00gCOfQnEUA"
         android:clickable="true" />
     <!-- Ubuntu:		0-0tVBYzo78GcruEETjNXCnXjt4rzTKIkzU5HAQ -->
     <!-- Win7:			0-0tVBYzo78FEXFOBhiBi06dI13u00gCOfQnEUA -->

File src/nctuw/littledot/localtreasure/Const.java

 	public static final String BUNDLE_EID = "eID";
 	public static final String BUNDLE_PROFILE = "userProfile";
 	public static final String BUNDLE_DISTANCE = "distance";
+	public static final String BUNDLE_MODE = "mode";
+
+	/* Expedition Mode */
+	public static final int MODE_ONEWAY = 1;
+	public static final int MODE_TOANDFRO = 2;
+	public static final int MODE_MULTI = 3;
+	public static final int MODE_FREESTYLE = 4;
+
 }

File src/nctuw/littledot/localtreasure/MapOverlay.java

 
 	/*
 	 * Class ItemizedOverlay (non-Javadoc)
+	 * 
 	 * @see com.google.android.maps.ItemizedOverlay#size()
 	 */
 

File src/nctuw/littledot/localtreasure/components/ExpeditionActivity.java

 import nctuw.littledot.localtreasure.R;
 import nctuw.littledot.localtreasure.database.DB;
 import nctuw.littledot.localtreasure.database.Expedition;
+import nctuw.littledot.localtreasure.database.Route;
 import nctuw.littledot.localtreasure.database.SP;
 import nctuw.littledot.localtreasure.database.Treasure;
-import nctuw.littledot.util.Echo;
 import nctuw.littledot.util.Leg;
 
 import org.holoeverywhere.app.AlertDialog;
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
+import android.location.Criteria;
 import android.location.Location;
 import android.location.LocationListener;
 import android.location.LocationManager;
 	private MapController mController;
 
 	private Expedition mExpedition;
+	private Route mRoute;
 
 	// private ExpeditionManager ell;
 
 				startMarker = new MapOverlay(getResources().getDrawable(
 						R.drawable.blue_map_marker_32_32), this));
 
+		// initialize Expedition
 		if (savedInstanceState != null) {
 			mExpedition = savedInstanceState.getParcelable(BUND_EXPEDITION);
 			isCalibrated = true;
 				mExpedition.setDistance(extras.getDouble(Const.BUNDLE_DISTANCE,
 						0));
 				mExpedition.setDistanceLeft(mExpedition.getDistance());
+				mExpedition.setMode(extras.getInt(Const.BUNDLE_MODE));
+
+				mRoute = new Route();
 
 			} else if (source.equals(MainActivity.class.getName())
 					|| source.equals(HistoryActivity.class.getName())) {
 				// load saved Expedition
 				long eID = extras.getLong(Const.BUNDLE_EID);
 				mExpedition = mDB.queryExpedition(eID);
+				mRoute = mDB.queryRoute(eID);
 
 				startMarker.clearOverlay();
-				startMarker
-						.addLocation(
-								mExpedition.getStartLoc(),
-								"Start",
-								"Reach the destination and claim your prize.\nBe careful of heavy traffic though, safety first!");
+				startMarker.addLocation(
+						// mExpedition.getStartLoc(),
+						mRoute.getNextWaypoint(),
+						"Start",
+						"Reach the destination and claim your prize.");
 				destMarker.clearOverlay();
-				destMarker.addLocation(mExpedition.getDestLoc(), "Destination",
+				destMarker.addLocation(
+						// mExpedition.getDestLoc(),
+						mRoute.getWaypoint(0),
+						"Destination",
 						"There seems to be something shimmering over there!");
 
 				mController.setCenter(new GeoPoint(
-						(int) (mExpedition.getDestLoc().getLatitude() * 1E6),
-						(int) (mExpedition.getDestLoc().getLongitude() * 1E6)));
+						// (int) (mExpedition.getDestLoc().getLatitude() * 1E6),
+						(int) (mRoute.getNextWaypoint().getLatitude() * 1E6),
+						// (int) (mExpedition.getDestLoc().getLongitude() * 1E6)));
+						(int) (mRoute.getNextWaypoint().getLongitude() * 1E6)));
 				mController.setZoom(14);
 
 				isCalibrated = true;
 			if (!isCalibrated)
 				showDialog(LOCATION_LOCK_DIALOG);
 
-			/*
-			 * // get a fresh start, only concerns are time & accuracy Time time
-			 * = new Time(); time.setToNow(); long now = time.toMillis(false);
-			 * long seconds;
-			 * 
-			 * lkGPS = mLM.getLastKnownLocation(LocationManager.GPS_PROVIDER);
-			 * // seconds = (lkGPS.getTime() - now) / 1000; //
-			 * greenMarker.addLocation(lkGPS, "LK GPS", // "Time=" + seconds +
-			 * "\n" + lkGPS.toString());
-			 * 
-			 * // time freshness must < 5 minutes & accuracy must < 100m if
-			 * (lkGPS != null && now - lkGPS.getTime() < LOCATION_TIME_THRESH &&
-			 * lkGPS.getAccuracy() < LOCATION_ACC_THRESH) { mStartLocation =
-			 * mCurLocation = lkGPS;
-			 * 
-			 * startMarker.addLocation(lkGPS, "LK GPS", lkGPS.toString());
-			 * playerMarker.addLocation(mCurLocation, "CurLoc",
-			 * mCurLocation.toString());
-			 * 
-			 * Echo.a(this, "gps=\n" + lkGPS); }
-			 * 
-			 * lkNetwork =
-			 * mLM.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); //
-			 * seconds = (lkNetwork.getTime() - now) / 1000; //
-			 * greenMarker.addLocation(lkNetwork, "LK NET", "Time=" + seconds +
-			 * "\n" // + lkNetwork.toString());
-			 * 
-			 * if (lkNetwork != null && ((mCurLocation != null &&
-			 * lkNetwork.getTime() > mCurLocation.getTime() && lkNetwork
-			 * .getAccuracy() < LOCATION_ACC_THRESH) || (mCurLocation == null &&
-			 * now - lkNetwork.getTime() < LOCATION_TIME_THRESH && lkNetwork
-			 * .getAccuracy() < LOCATION_ACC_THRESH))) { mStartLocation =
-			 * mCurLocation = lkNetwork;
-			 * 
-			 * startMarker.clearOverlay(); startMarker.addLocation(lkNetwork,
-			 * "LK NET", lkNetwork.toString()); playerMarker.clearOverlay();
-			 * playerMarker.addLocation(mCurLocation, "CurLoc",
-			 * mCurLocation.toString());
-			 * 
-			 * Echo.a(this, "network=\n" + lkNetwork); }
-			 * 
-			 * lkPassive =
-			 * mLM.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER); //
-			 * seconds = (lkPassive.getTime() - now) / 1000; //
-			 * greenMarker.addLocation(lkPassive, "LK NET", "Time=" + seconds +
-			 * "\n" // + lkPassive.toString());
-			 * 
-			 * if (lkPassive != null && ((mCurLocation != null &&
-			 * lkPassive.getTime() > mCurLocation.getTime() && lkPassive
-			 * .getAccuracy() < LOCATION_ACC_THRESH) || (mCurLocation == null &&
-			 * now - lkPassive.getTime() < LOCATION_TIME_THRESH && lkPassive
-			 * .getAccuracy() < LOCATION_ACC_THRESH))) { mStartLocation =
-			 * mCurLocation = lkPassive;
-			 * 
-			 * startMarker.clearOverlay(); startMarker.addLocation(lkNetwork,
-			 * "LK PASSIVE", lkPassive.toString()); playerMarker.clearOverlay();
-			 * playerMarker.addLocation(mCurLocation, "CurLoc",
-			 * mCurLocation.toString());
-			 * 
-			 * Echo.a(this, "passive=\n" + lkPassive); }
-			 */
-
-			// if (mStartLocation != null) {
-			// mDestLocation =
-			// Geodesy.calculateVincentyDestination(mStartLocation,
-			// mBearing, mDistance);
-			//
-			// destMarker.addLocation(mDestLocation, "Dest",
-			// mDestLocation.toString());
-
-			// tvCurLoc.setText("===curLoc===\n" + mCurLocation.toString());
-			// tvDestLoc.setText("===destLoc===\n" + mDestLocation.toString());
-			// tvDistance.setText("===dist==="
-			// + mCurLocation.distanceTo(mDestLocation));
-			// } else {
-			// else calibrate device
-			// showDialog(LOCATION_LOCK_DIALOG);
-			// }
-
 		}
 	}
 
 		for (String provider : mLM.getAllProviders()) {
 			Leg.a("provider=" + provider);
 
-			mLM.requestLocationUpdates(provider, 3000, 0, this);
+			if (!provider.equals(LocationManager.PASSIVE_PROVIDER))
+				mLM.requestLocationUpdates(provider, 3000, 0, this);
 		}
+		// mLM.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000, 0, this);
+		// mLM.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 3000, 0,
+		// this);
 
 		// register sensor updates
 		mSM.registerListener(this,
 		// mExpedition.setEndTS(System.currentTimeMillis());
 
 		// save only after destination is confirmed
-		if (mExpedition.getDestLoc() != null) {
+		if (mRoute.size() > 1) {
 			mDB.updateExpedition(mExpedition);
 			// only for incompleted expeditions
 			if (!isAtDest)
 		if (!isCalibrated) {
 
 			double bearing = Math.random() * 360;
-			mExpedition.setStartLoc(location);
-			mExpedition.setDestLoc(Geodesy.calculateVincentyDestination(
-					location, bearing, mExpedition.getDistance()));
+			// mExpedition.setStartLoc(location);
+			// mExpedition.setDestLoc(Geodesy.calculateVincentyDestination(
+			// location, bearing, mExpedition.getDistance()));
+
+			// mExpedition.addWaypoint(location);
+			mRoute.addWaypoint(location);
+
+			if (mExpedition.getMode() == Const.MODE_ONEWAY) {
+				mRoute.addWaypoint(Geodesy.calculateVincentyDestination(
+						location, bearing, mExpedition.getDistance()));
+			} else if (mExpedition.getMode() == Const.MODE_TOANDFRO) {
+				mRoute.addWaypoint(Geodesy.calculateVincentyDestination(
+						location, bearing, mExpedition.getDistance() / 2));
+				mRoute.addWaypoint(location);
+			}
 
-			// save only after destination is confirmed
+			// save only after destination is confirmed TODO: transaction
 			long eID = mDB.insertExpedition(mExpedition);
-			mExpedition.setEID(eID);
-			// mSP.setActiveExpeditionID(eID);
+			mRoute.setEID(eID);
+			mDB.insertRoute(mRoute);
+			Leg.a(mRoute.toString());
 
 			startMarker.clearOverlay();
-			startMarker
-					.addLocation(
-							location,
-							"Start",
-							"Reach the destination and claim your prize.\nBe careful of heavy traffic though, safety first!");
+			startMarker.addLocation(
+					location,
+					"Start",
+					"Reach the destination and claim your prize.");
 			destMarker.clearOverlay();
-			destMarker.addLocation(mExpedition.getDestLoc(), "Destination",
+			destMarker.addLocation(
+					// mExpedition.getDestLoc(),
+					mRoute.getNextWaypoint(),
+					"Destination",
 					"There seems to be something shimmering over there!");
 
 			// center the map
 			concludeExpedition();
 			showDialog(EXPEDITION_COMPLETE_DIALOG);
 		}
-		// // log remaining distance
-		// double distLeft = location.distanceTo(mExpedition.getDestLoc());
-		// mExpedition.setDistanceLeft(distLeft);
-		//
-		// // determine if player is close enough to win
-		// if (distLeft < mExpedition.getDistance() * 0.05) {
-		// Leg.a("apart=" + distLeft + " required=" + mExpedition.getDistance()
-		// * 0.05);
-		// mExpedition.setEndTS(System.currentTimeMillis());
-		// mExpedition.setPrize(Treasure.generateReward(mExpedition));
-		//
-		// mSP.setActiveExpeditionID(0);
-		//
-		// mLM.removeUpdates(this);
-		// mSM.unregisterListener(this);
-		//
-		// isAtDest = true;
-		//
-		// showDialog(EXPEDITION_COMPLETE_DIALOG);
-		// }
 
 		// debug info
 		Leg.a("expedition=" + mExpedition.toString());
 	}
 
 	public void onStatusChanged(String provider, int status, Bundle extras) {
-		Echo.a(this, "provider=" + provider + " status=" + status + " extras="
-				+ extras.toString());
+		// Echo.a(this, "provider=" + provider + " status=" + status + " extras="
+		// + extras.toString());
 	}
 
 	/***********************************/
 
 	private boolean isAtDestination(Location location) {
 		// log remaining distance
-		double distLeft = location.distanceTo(mExpedition.getDestLoc());
+		// double distLeft = location.distanceTo(mExpedition.getDestLoc());
+		double distLeft = location.distanceTo(mRoute.getNextWaypoint());
 		mExpedition.setDistanceLeft(distLeft);
 
-		// determine if player is close enough to win
+		// if the player is close enough to the waypoint
 		if (distLeft < mExpedition.getDistance() * 0.05 || distLeft < 10D) {
 			Leg.a("apart=" + distLeft + " required="
 					+ mExpedition.getDistance() * 0.05);
+			mRoute.isAtWaypoint();
 
-			return true;
+			// if there are no more waypoints to go
+			if (mRoute.getNextWaypoint() == null) {
+				return true;
+			} else {
+				destMarker.clearOverlay();
+				destMarker.addLocation(
+						mRoute.getNextWaypoint(),
+						"Destination",
+						"There seems to be something shimmering over there!");
+
+				// clear start marker since they overlap
+				if (mExpedition.getMode() == Const.MODE_TOANDFRO) {
+					startMarker.clearOverlay();
+				}
+				map.invalidate();
+			}
 		}
 		return false;
 	}

File src/nctuw/littledot/localtreasure/components/ExpeditionConfigActivity.java

 	private CheckBox cbOneWay;
 	private CheckBox cbToFro;
 
+	private int mode = Const.MODE_ONEWAY;
+
 	@Override
 	protected void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 		if (id == R.id.config_cb_oneway) {
 			cbOneWay.setChecked(true);
 			cbToFro.setChecked(false);
+			mode = Const.MODE_ONEWAY;
 		} else if (id == R.id.config_cb_toandfro) {
 			cbOneWay.setChecked(false);
 			cbToFro.setChecked(true);
+			mode = Const.MODE_TOANDFRO;
 		}
 	}
 
 	public void onChooseDistance(View v) {
-		Intent intent = new Intent(this, ExpeditionActivity.class);
+		int id = v.getId();
 
-		switch (v.getId()) {
-		case R.id.distance_but_500m:
-			intent.putExtra(Const.BUNDLE_SOURCE, getClass().getName());
-			intent.putExtra(Const.BUNDLE_DISTANCE, 500D);
-			break;
-		case R.id.distance_but_1000m:
-			intent.putExtra(Const.BUNDLE_SOURCE, getClass().getName());
-			intent.putExtra(Const.BUNDLE_DISTANCE, 1000D);
-			break;
+		if (id == R.id.distance_but_500m) {
+			startExpedition(500D);
+		} else if (id == R.id.distance_but_1000m) {
+			startExpedition(1000D);
 		}
-
-		startActivity(intent);
-		finish();
 	}
 
 	public void onChooseCustomDistance(View v) {
 
 			} else {
 				imm.hideSoftInputFromWindow(et.getWindowToken(), 0);
+				startExpedition(d);
 
-				Intent intent = new Intent(this, ExpeditionActivity.class);
-				intent.putExtra(Const.BUNDLE_SOURCE, getClass().getName());
-				intent.putExtra(Const.BUNDLE_DISTANCE, d);
-				startActivity(intent);
-				finish();
 			}
 		} catch (NumberFormatException e) {
-			Toast
-					.makeText(this, "Please enter a valid number.",
-							Toast.LENGTH_SHORT)
+			Toast.makeText(this, "Please enter a valid number.", Toast.LENGTH_SHORT)
 					.show();
 		}
 	}
+
+	private void startExpedition(double distance) {
+		Intent intent = new Intent(this, ExpeditionActivity.class);
+		intent.putExtra(Const.BUNDLE_SOURCE, getClass().getName());
+		intent.putExtra(Const.BUNDLE_DISTANCE, distance);
+		intent.putExtra(Const.BUNDLE_MODE, mode);
+		startActivity(intent);
+		finish();
+	}
 }

File src/nctuw/littledot/localtreasure/database/DB.java

 		DBHelper = new DatabaseHelper(mContext, DB_VERSION);
 	}
 
-	// private class DatabaseHelper extends SQLiteOpenHelper {
-	// DatabaseHelper(Context context) {
-	// super(context, context.getPackageName(), null, DB_VERSION);
-	// }
-	//
-	// @Override
-	// public void onCreate(SQLiteDatabase db) {
-	// // db.execSQL(SQL_CREATE_TREASURE);
-	// db.execSQL(Profile.SQL_CREATE_PROFILE);
-	// db.execSQL(Expedition.SQL_CREATE_EXPEDITION);
-	//
-	// db.execSQL("insert into " + Profile.TABLE_NAME + "("
-	// + Profile.KEY_ID + ") values (1);");
-	// }
-	//
-	// @Override
-	// public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
-	// {
-	//
-	// db.beginTransaction();
-	// try {
-	// // db.execSQL("alter table " + DBTABLE_PROFILE + " to TEMP");
-	// // db.execSQL(SQL_CREATE_PROFILE);
-	// //
-	// db.execSQL("insert into "+DBTABLE_PROFILE+" orig_table_name(col_a, col_b)				SELECT col_a, colb				FROM tmp_table_name;");
-	//
-	// // db.execSQL("drop table if exists " + DBTABLE_TREASURE + ";");
-	// db.execSQL("drop table if exists " + Profile.TABLE_NAME + ";");
-	// db.execSQL("drop table if exists " + Expedition.TABLE_NAME
-	// + ";");
-	// onCreate(db);
-	//
-	// db.setTransactionSuccessful();
-	// } finally {
-	// db.endTransaction();
-	// }
-	//
-	// }
-	// }
-
 	public DB open(int mode) {
 		if (mode == MODE_WRITE)
 			db = DBHelper.getWritableDatabase();
 		if (!where.equals("*"))
 			query += where;
 
-		Cursor cur = rawQuery(query);
+		Cursor c = rawQuery(query);
 
-		if (cur.moveToFirst()) {
+		if (c.moveToFirst()) {
 			ArrayList<Expedition> expeditions = new ArrayList<Expedition>();
 
-			while (!cur.isAfterLast()) {
-				expeditions.add(new Expedition(cur));
-				cur.moveToNext();
+			while (!c.isAfterLast()) {
+				expeditions.add(new Expedition(c));
+				c.moveToNext();
 			}
-			cur.close();
+			c.close();
 
 			return expeditions;
 		} else
 			return null;
 	}
 
+	public Route queryRoute(long eID) {
+		String sql = "select * from " + Route.TABLE_NAME + " where "
+				+ Route.KEY_EID + "=" + eID + " order by " + Route.KEY_ORDER + " asc";
+		Cursor c = rawQuery(sql);
+
+		Leg.dumpCursor(c);
+
+		if (c.moveToFirst()) {
+
+			Route r = new Route(c);
+			Leg.a(r.toString());
+			return r;
+		}
+		else
+			return null;
+	}
+
 	/*************/
 	/** Inserts **/
 	/*************/
 	}
 
 	public long insertExpedition(Expedition expedition) {
-		return db.insertOrThrow(Expedition.TABLE_NAME, null,
+		long eID = db.insertOrThrow(Expedition.TABLE_NAME, null,
 				expedition.toContentValues());
+
+		expedition.setEID(eID);
+
+		return eID;
 	}
 
 	public long insertProfile(Profile profile) {
-		return db.insert(Profile.TABLE_NAME, null, profile.toContentValues());
+		long pID = db.insertOrThrow(Profile.TABLE_NAME, null,
+				profile.toContentValues());
+
+		profile.setProfileID(pID);
+
+		return pID;
+	}
+
+	public long insertRoute(Route route) {
+
+		ArrayList<ContentValues> wp = route.toContentValues();
+
+		for (ContentValues kv : wp) {
+			db.insertOrThrow(Route.TABLE_NAME, null, kv);
+		}
+
+		return wp.size();
 	}
 
 	/*************/

File src/nctuw/littledot/localtreasure/database/DatabaseHelper.java

 package nctuw.littledot.localtreasure.database;
 
+import nctuw.littledot.util.Curser;
 import nctuw.littledot.util.Leg;
+import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 				public void apply(SQLiteDatabase db) {
 					db.execSQL(Route.SQL_CREATE_ROUTE);
 
-					String sql = "select * from " + Expedition.TABLE_NAME
-							+ " where " + Expedition.KEY_END_LAT + ">0";
+					String sql = "select * from " + Expedition.TABLE_NAME;
 					Cursor c = db.rawQuery(sql, null);
 					c.moveToFirst();
 
+					ContentValues kv = new ContentValues();
+
 					while (!c.isAfterLast()) {
-						String sql_start = "insert into " + Route.TABLE_NAME +
-								"(" + Route.KEY_EID + "," + Route.KEY_ORDER + ","
-								+ Route.KEY_LAT + "," + Route.KEY_LONG
-								+ ") values ("
-								+ c.getLong(c.getColumnIndex(Expedition.KEY_EID)) + ","
-								+ "0,"
-								+ c.getDouble(c.getColumnIndex(Expedition.KEY_START_LAT)) + ","
-								+ c.getDouble(c.getColumnIndex(Expedition.KEY_START_LONG))
-								+ ");";
-						db.execSQL(sql_start);
-						String sql_end = "insert into " + Route.TABLE_NAME +
-								"(" + Route.KEY_EID + "," + Route.KEY_ORDER + ","
-								+ Route.KEY_LAT + "," + Route.KEY_LONG
-								+ ") values ("
-								+ c.getLong(c.getColumnIndex(Expedition.KEY_EID)) + ","
-								+ "1,"
-								+ c.getDouble(c.getColumnIndex(Expedition.KEY_END_LAT)) + ","
-								+ c.getDouble(c.getColumnIndex(Expedition.KEY_END_LONG))
-								+ ");";
-						db.execSQL(sql_end);
+						// starting location is waypoint 0
+						kv.put(Route.KEY_EID, Curser.getLong(c, Expedition.KEY_EID));
+						kv.put(Route.KEY_ORDER, 0);
+						kv.put(Route.KEY_VISITED, 1);
+						kv.put(Route.KEY_LAT, Curser.getDouble(c, Expedition.KEY_START_LAT));
+						kv.put(Route.KEY_LONG,
+								Curser.getDouble(c, Expedition.KEY_START_LONG));
+						db.insert(Route.TABLE_NAME, null, kv);
+
+						// destination is waypoint 1
+						kv.put(Route.KEY_ORDER, 1);
+						kv.put(Route.KEY_LAT, Curser.getDouble(c, Expedition.KEY_END_LAT));
+						kv.put(Route.KEY_LONG, Curser.getDouble(c, Expedition.KEY_END_LONG));
+						if (Curser.getLong(c, Expedition.KEY_TIME) > 0)
+							kv.put(Route.KEY_VISITED, 1);
+						else
+							kv.put(Route.KEY_VISITED, 0);
+						db.insert(Route.TABLE_NAME, null, kv);
 
+						kv.clear();
 						c.moveToNext();
 					}
 				}

File src/nctuw/littledot/localtreasure/database/Expedition.java

 import java.util.ArrayList;
 import java.util.Date;
 
+import nctuw.littledot.util.Curser;
 import nctuw.littledot.util.Leg;
 import android.content.ContentValues;
 import android.database.Cursor;
 	private long eID = 0;
 
 	private long pID = 0;
-	private Location mStartLoc = null;
-	private Location mDestLoc = null;
+	// private Location mStartLoc = null;
+	// private Location mDestLoc = null;
 	private double mDistance;
 	private double mTravelled;
 	private double mDistanceLeft;
 
-	private Route mRoute;
+	private int mode;
+	// private Route mRoute;
 
 	private long mStartTS;
 	private long mEndTS;
 	public String toString() {
 		String sb = "eID=" + eID + " pID=" + pID;
 
-		if (mStartLoc != null)
-			sb += " stLoc=(" + mStartLoc.getLatitude() + ","
-					+ mStartLoc.getLongitude() + ")";
-		if (mDestLoc != null)
-			sb += " destLoc=(" + mDestLoc.getLatitude() + ","
-					+ mDestLoc.getLongitude() + ")";
+		// if (mStartLoc != null)
+		// sb += " stLoc=(" + mStartLoc.getLatitude() + ","
+		// + mStartLoc.getLongitude() + ")";
+		// if (mDestLoc != null)
+		// sb += " destLoc=(" + mDestLoc.getLatitude() + ","
+		// + mDestLoc.getLongitude() + ")";
 
 		sb += " dist=" + mDistance
 				+ " tra=" + mTravelled
 
 	public Expedition setEID(long eID) {
 		this.eID = eID;
+		// mRoute.setEID(eID);
 		return this;
 	}
 
 		return this;
 	}
 
-	public Location getStartLoc() {
-		return mStartLoc;
-	}
-
-	public Expedition setStartLoc(Location mStartLoc) {
-		this.mStartLoc = mStartLoc;
-		return this;
-	}
-
-	public Location getDestLoc() {
-		return mDestLoc;
-	}
-
-	public Expedition setDestLoc(Location mDestLoc) {
-		this.mDestLoc = mDestLoc;
-		return this;
-	}
+	// public Location getStartLoc() {
+	// return mStartLoc;
+	// }
+	//
+	// public Expedition setStartLoc(Location mStartLoc) {
+	// this.mStartLoc = mStartLoc;
+	// return this;
+	// }
+	//
+	// public Location getDestLoc() {
+	// return mDestLoc;
+	// // return mRoute.getNextWaypoint();
+	// }
+	//
+	// public Expedition setDestLoc(Location mDestLoc) {
+	// this.mDestLoc = mDestLoc;
+	// return this;
+	// }
 
 	public double getDistance() {
 		return mDistance;
 		return this;
 	}
 
+	public int getMode() {
+		return mode;
+	}
+
+	public Expedition setMode(int mode) {
+		this.mode = mode;
+		return this;
+	}
+
+	// public Route getRoute() {
+	// return mRoute;
+	// }
+	//
+	// public void addWaypoint(Location l) {
+	// mRoute.addWaypoint(l);
+	// }
+
 	/************/
 	/** SQLite **/
 	/************/
 	/**
 	 * Populate an Expedition via a Cursor.
 	 * 
-	 * @param cur
+	 * @param c
 	 */
-	public Expedition(Cursor cur) {
-		Leg.dumpCursor(cur);
+	public Expedition(Cursor c) {
+		Leg.dumpCursor(c);
 		Location loc;
 		int i;
 
-		setEID(cur.getLong(cur.getColumnIndex(Expedition.KEY_EID)));
-		setPID(cur.getLong(cur.getColumnIndex(Expedition.KEY_PID)));
-		setDistance(cur.getDouble(cur.getColumnIndex(Expedition.KEY_DISTANCE)));
-		setDistanceLeft(cur.getDouble(cur.getColumnIndex(KEY_DIST_LEFT)));
+		// setEID(c.getLong(c.getColumnIndex(Expedition.KEY_EID)));
+		eID = Curser.getLong(c, Expedition.KEY_EID);
+		// setPID(c.getLong(c.getColumnIndex(Expedition.KEY_PID)));
+		pID = Curser.getLong(c, Expedition.KEY_PID);
+		// setDistance(c.getDouble(c.getColumnIndex(Expedition.KEY_DISTANCE)));
+		mDistance = Curser.getDouble(c, Expedition.KEY_DISTANCE);
+		// setDistanceLeft(c.getDouble(c.getColumnIndex(KEY_DIST_LEFT)));
+		mDistanceLeft = Curser.getDouble(c, Expedition.KEY_DIST_LEFT);
 
-		if ((i = DB.getIndex(cur, Expedition.KEY_TRAVELED)) > -1)
-			setTravelled(cur.getDouble(i));
+		// if ((i = DB.getIndex(c, Expedition.KEY_TRAVELED)) > -1)
+		// setTravelled(c.getDouble(i));
+		mTravelled = Curser.getDouble(c, Expedition.KEY_TRAVELED);
 
-		if ((i = DB.getIndex(cur, Expedition.KEY_START_LAT)) > -1) {
+		if ((i = DB.getIndex(c, Expedition.KEY_START_LAT)) > -1) {
 			loc = new Location("");
-			loc.setLatitude(cur.getDouble(i));
-			loc.setLongitude(cur.getDouble(cur
+			loc.setLatitude(c.getDouble(i));
+			loc.setLongitude(c.getDouble(c
 					.getColumnIndex(Expedition.KEY_START_LONG)));
-			setStartLoc(loc);
+			// setStartLoc(loc);
 		}
 
-		if ((i = DB.getIndex(cur, Expedition.KEY_END_LAT)) > -1) {
+		if ((i = DB.getIndex(c, Expedition.KEY_END_LAT)) > -1) {
 			loc = new Location("");
-			loc.setLatitude(cur.getDouble(i));
-			loc.setLongitude(cur.getDouble(cur
+			loc.setLatitude(c.getDouble(i));
+			loc.setLongitude(c.getDouble(c
 					.getColumnIndex(Expedition.KEY_END_LONG)));
-			setDestLoc(loc);
+			// setDestLoc(loc);
 		}
 
-		setStartTS(cur.getLong(cur
+		setStartTS(c.getLong(c
 				.getColumnIndex(Expedition.KEY_START_TIMESTAMP)));
 
-		if ((i = DB.getIndex(cur, Expedition.KEY_END_TIMESTAMP)) > -1)
-			setEndTS(cur.getLong(i));
+		if ((i = DB.getIndex(c, Expedition.KEY_END_TIMESTAMP)) > -1)
+			setEndTS(c.getLong(i));
 
-		if ((i = DB.getIndex(cur, Expedition.KEY_TREASURE_ID)) > -1)
-			setPrize(Treasure.getTreasure(cur.getInt(i)));
+		if ((i = DB.getIndex(c, Expedition.KEY_TREASURE_ID)) > -1)
+			setPrize(Treasure.getTreasure(c.getInt(i)));
 	}
 
 	public ContentValues toContentValues() {
 			keys.add(KEY_TRAVELED);
 			vals.add(mTravelled);
 		}
-		if (mStartLoc != null) {
-			keys.add(KEY_START_LAT);
-			vals.add(mStartLoc.getLatitude());
-			keys.add(KEY_START_LONG);
-			vals.add(mStartLoc.getLongitude());
-		}
-		if (mDestLoc != null) {
-			keys.add(KEY_END_LAT);
-			vals.add(mDestLoc.getLatitude());
-			keys.add(KEY_END_LONG);
-			vals.add(mDestLoc.getLongitude());
-		}
+		// if (mStartLoc != null) {
+		// keys.add(KEY_START_LAT);
+		// vals.add(mStartLoc.getLatitude());
+		// keys.add(KEY_START_LONG);
+		// vals.add(mStartLoc.getLongitude());
+		// }
+		// if (mDestLoc != null) {
+		// keys.add(KEY_END_LAT);
+		// vals.add(mDestLoc.getLatitude());
+		// keys.add(KEY_END_LONG);
+		// vals.add(mDestLoc.getLongitude());
+		// }
 		if (mStartTS > 0) {
 			keys.add(KEY_START_TIMESTAMP);
 			vals.add(mStartTS);
 	public void writeToParcel(Parcel dest, int flags) {
 		dest.writeLong(eID);
 		dest.writeLong(pID);
-		dest.writeParcelable(mStartLoc, 0);
-		dest.writeParcelable(mDestLoc, 0);
+		// dest.writeParcelable(mStartLoc, 0);
+		// dest.writeParcelable(mDestLoc, 0);
 		dest.writeDouble(mDistance);
 		dest.writeDouble(mTravelled);
 		dest.writeDouble(mDistanceLeft);
 	private Expedition(Parcel in) {
 		eID = in.readLong();
 		pID = in.readLong();
-		mStartLoc = in.readParcelable(null);
-		mDestLoc = in.readParcelable(null);
+		// mStartLoc = in.readParcelable(null);
+		// mDestLoc = in.readParcelable(null);
 		mDistance = in.readDouble();
 		mTravelled = in.readDouble();
 		mDistanceLeft = in.readDouble();

File src/nctuw/littledot/localtreasure/database/Profile.java

 
 import java.util.ArrayList;
 
+import nctuw.littledot.util.Curser;
 import android.content.ContentValues;
 import android.database.Cursor;
 import android.os.Parcel;
 			+ " text default '<John Doe>'"
 			+ ");";
 
-	public Profile(Cursor cur) {
-		mProfileID = cur.getLong(cur.getColumnIndex(KEY_PID));
-		mName = cur.getString(cur.getColumnIndex(KEY_NAME));
-		mDistanceTravelled = cur.getDouble(cur
-				.getColumnIndex(Expedition.SUM_TRAVELED));
-		mExpeditionCount = cur.getInt(cur.getColumnIndex(Expedition.COUNT_ID));
+	public Profile(Cursor c) {
+		mProfileID = Curser.getLong(c, KEY_PID);
+		mName = Curser.getString(c, KEY_NAME);
+		mDistanceTravelled = Curser.getDouble(c, Expedition.SUM_TRAVELED);
+		mExpeditionCount = Curser.getInt(c, Expedition.COUNT_ID);
 	}
 
 	public ContentValues toContentValues() {
 	public static ContentValues toContentValues(Cursor c) {
 		ContentValues kv = new ContentValues();
 
-		kv.put(KEY_PID, c.getLong(c.getColumnIndex(KEY_PID)));
-		kv.put(KEY_NAME, c.getString(c.getColumnIndex(KEY_NAME)));
+		kv.put(KEY_PID, Curser.getLong(c, KEY_PID));
+		kv.put(KEY_NAME, Curser.getString(c, KEY_NAME));
 
 		return kv;
 	}

File src/nctuw/littledot/localtreasure/database/Route.java

 
 import java.util.ArrayList;
 
+import nctuw.littledot.util.Curser;
+
+import android.content.ContentValues;
 import android.database.Cursor;
 import android.location.Location;
 
 public class Route {
-	private long rID = 0;
 	private long eID = 0;
 	private ArrayList<Location> mWaypoints = new ArrayList<Location>();
 
+	private int mAt = 0;
+
 	public Route() {
 	}
 
 	public String toString() {
-		return "";
-	}
+		String s = "eID=" + eID + " at=" + mAt + " size=" + mWaypoints.size();
 
-	public long getRID() {
-		return rID;
-	}
+		s += " waypoints=";
+		for (Location l : mWaypoints) {
+			s += "(" + l.getLongitude() + "," + l.getLatitude() + ")";
+		}
 
-	public Route setRID(long rid) {
-		rID = rid;
-		return this;
+		return s;
 	}
 
 	public long getEID() {
 		return this;
 	}
 
+	public Route addWaypoint(Location l) {
+		mWaypoints.add(l);
+		return this;
+	}
+
+	public void isAtWaypoint() {
+		mAt++;
+	}
+
+	public Location getNextWaypoint() {
+		if (mAt + 1 < mWaypoints.size())
+			return new Location(mWaypoints.get(mAt + 1));
+		else
+			return null;
+	}
+
+	public Location getWaypoint(int i) {
+		return new Location(mWaypoints.get(i));
+	}
+
+	public int size() {
+		return mWaypoints.size();
+	}
+
 	/************/
 	/** SQLite **/
 	/************/
 	public static final String KEY_RID = "rID";
 	public static final String KEY_EID = "eID";
 	public static final String KEY_ORDER = "rOrder";
+	public static final String KEY_VISITED = "rVisited";
 	public static final String KEY_LAT = "rLat";
 	public static final String KEY_LONG = "rLong";
 
 			+ " integer not null,"
 			+ KEY_ORDER
 			+ " integer not null,"
+			+ KEY_VISITED
+			+ " integer not null,"
 			+ KEY_LAT
 			+ " real not null,"
 			+ KEY_LONG
 			+ " real not null"
 			+ ");";
 
-	public Route(Cursor cur) {
-		cur.moveToFirst();
+	public Route(Cursor c) {
+		c.moveToFirst();
 
-		rID = cur.getLong(cur.getColumnIndex(KEY_RID));
-		eID = cur.getLong(cur.getColumnIndex(KEY_EID));
+		eID = Curser.getLong(c, KEY_EID);
 
 		int order = 0;
+		boolean isAtSet = false;
+
+		while (!c.isAfterLast()) {
+			if (!isAtSet && Curser.getInt(c, KEY_VISITED) == 0) {
+				mAt = order - 1;
+				isAtSet = true;
+			}
 
-		while (!cur.isAfterLast()) {
-			if (order != cur.getInt(cur.getColumnIndex(KEY_ORDER)))
+			if (order != Curser.getInt(c, KEY_ORDER))
 				throw new IllegalStateException("Data is not in order.");
 			order++;
 
 			Location l = new Location("");
-			l.setLatitude(cur.getDouble(cur.getColumnIndex(KEY_LAT)));
-			l.setLongitude(cur.getDouble(cur.getColumnIndex(KEY_LONG)));
+			l.setLatitude(Curser.getDouble(c, KEY_LAT));
+			l.setLongitude(Curser.getDouble(c, KEY_LONG));
 			mWaypoints.add(l);
 
-			cur.moveToNext();
+			c.moveToNext();
 		}
 	}
+
+	public ArrayList<ContentValues> toContentValues() {
+		ArrayList<ContentValues> cv = new ArrayList<ContentValues>();
+
+		ArrayList<String> keys = new ArrayList<String>();
+		ArrayList<Object> vals = new ArrayList<Object>();
+		for (int i = 0; i < mWaypoints.size(); i++) {
+			keys.clear();
+			vals.clear();
+
+			keys.add(KEY_EID);
+			vals.add(eID);
+
+			keys.add(KEY_ORDER);
+			vals.add(i);
+
+			keys.add(KEY_LAT);
+			vals.add(mWaypoints.get(i).getLatitude());
+
+			keys.add(KEY_LONG);
+			vals.add(mWaypoints.get(i).getLongitude());
+
+			keys.add(KEY_VISITED);
+			if (i <= mAt)
+				vals.add(1);
+			else
+				vals.add(0);
+
+			cv.add(DB.toContentValues(
+					(String[]) keys.toArray(new String[keys.size()]),
+					vals.toArray()));
+		}
+
+		return cv;
+	}
 }