Index: /other-projects/tipple-android/tipple-casey/gen/org/tipple/mapDisplay/R.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/gen/org/tipple/mapDisplay/R.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/gen/org/tipple/mapDisplay/R.java	(revision 26526)
@@ -0,0 +1,109 @@
+/* AUTO-GENERATED FILE.  DO NOT MODIFY.
+ *
+ * This class was automatically generated by the
+ * aapt tool from the resource data it found.  It
+ * should not be modified by hand.
+ */
+
+package org.tipple.mapDisplay;
+
+public final class R {
+    public static final class array {
+        public static final int preferences_book_mode_entries=0x7f050002;
+        public static final int preferences_book_mode_entry_values=0x7f050003;
+        public static final int preferences_text_audio_mode_entries=0x7f050000;
+        public static final int preferences_text_audio_mode_entry_values=0x7f050001;
+    }
+    public static final class attr {
+    }
+    public static final class drawable {
+        public static final int ic_menu_archive=0x7f020000;
+        public static final int ic_menu_back=0x7f020001;
+        public static final int ic_menu_info_details=0x7f020002;
+        public static final int ic_menu_mapmode=0x7f020003;
+        public static final int ic_menu_preferences=0x7f020004;
+        public static final int ic_menu_quit=0x7f020005;
+        public static final int marker=0x7f020006;
+        public static final int markerd=0x7f020007;
+        public static final int markergreen=0x7f020008;
+        public static final int markerhighlightbook1=0x7f020009;
+        public static final int markerhighlightbook1d=0x7f02000a;
+        public static final int markerhighlightbook2=0x7f02000b;
+        public static final int markerhighlightd=0x7f02000c;
+        public static final int routemarker=0x7f02000d;
+        public static final int tipple_eab_icon=0x7f02000e;
+    }
+    public static final class id {
+        public static final int ScrollView01=0x7f080000;
+        public static final int button=0x7f080004;
+        public static final int fileBrowserView=0x7f080005;
+        public static final int iPopupImage=0x7f080006;
+        public static final int image=0x7f080002;
+        public static final int layout_root=0x7f080001;
+        public static final int menu_preferences=0x7f080009;
+        public static final int tSnippet=0x7f080008;
+        public static final int tTitle=0x7f080007;
+        public static final int text=0x7f080003;
+    }
+    public static final class layout {
+        public static final int custom_dialog=0x7f030000;
+        public static final int filebrowser=0x7f030001;
+        public static final int main=0x7f030002;
+        public static final int markerpopup=0x7f030003;
+    }
+    public static final class menu {
+        public static final int options_menu=0x7f070000;
+    }
+    public static final class string {
+        public static final int app_name=0x7f060003;
+        /**   General labels 
+         */
+        public static final int cancel=0x7f060004;
+        public static final int error=0x7f060005;
+        public static final int hello=0x7f060002;
+        public static final int latitude=0x7f060007;
+        public static final int log_file_invalid=0x7f06000c;
+        public static final int log_file_select=0x7f06000d;
+        public static final int logging_error_continue=0x7f06000e;
+        public static final int logging_error_stop=0x7f06000f;
+        public static final int logging_ok_disable=0x7f060011;
+        public static final int logging_ok_enable=0x7f060010;
+        public static final int longitude=0x7f060008;
+        /**   Values used in OptionsMenu 
+         */
+        public static final int menu_info=0x7f060009;
+        public static final int menu_logfile=0x7f06000b;
+        public static final int menu_preferences=0x7f06000a;
+        public static final int ok=0x7f060006;
+        /**   Values used in book number options 
+	<string name="preferences_book">Book settings</string>
+	<string name="preferences_book_mode">Book number Setting </string>
+	<string name="preferences_book_mode_desc">Control the ability to display number of books on a map</string>
+Values used in checked box layout of book number options 
+         */
+        public static final int preferences_book=0x7f06001e;
+        public static final int preferences_book_a=0x7f06001f;
+        public static final int preferences_book_a_desc=0x7f060020;
+        public static final int preferences_book_b=0x7f060021;
+        public static final int preferences_book_b_desc=0x7f060022;
+        public static final int preferences_book_mode_default=0x7f060000;
+        public static final int preferences_centre_on_loc=0x7f060015;
+        public static final int preferences_centre_on_loc_desc=0x7f060016;
+        public static final int preferences_map=0x7f060012;
+        /**   Values used in text/audio setting 
+         */
+        public static final int preferences_mode=0x7f06001b;
+        public static final int preferences_show_scale_bar=0x7f060013;
+        public static final int preferences_show_scale_bar_desc=0x7f060014;
+        public static final int preferences_show_sights=0x7f060017;
+        public static final int preferences_show_sights_desc=0x7f060018;
+        public static final int preferences_show_user_trail=0x7f060019;
+        public static final int preferences_show_user_trail_desc=0x7f06001a;
+        public static final int preferences_text_audio_mode=0x7f06001c;
+        public static final int preferences_text_audio_mode_default=0x7f060001;
+        public static final int preferences_text_audio_mode_desc=0x7f06001d;
+    }
+    public static final class xml {
+        public static final int preferences=0x7f040000;
+    }
+}
Index: /other-projects/tipple-android/tipple-casey/res/layout/custom_dialog.xml
===================================================================
--- /other-projects/tipple-android/tipple-casey/res/layout/custom_dialog.xml	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/res/layout/custom_dialog.xml	(revision 26526)
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView  android:id="@+id/ScrollView01" 
+            android:layout_width="fill_parent" 
+            android:layout_height="fill_parent" 
+            xmlns:android="http://schemas.android.com/apk/res/android">
+            
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:id="@+id/layout_root"
+              android:orientation="vertical"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent"
+              android:padding="10dp"             
+              android:scrollbars="vertical"
+              android:scrollbarAlwaysDrawVerticalTrack="true"
+              >
+    <ImageView android:id="@+id/image"
+               android:layout_width="wrap_content"
+               android:layout_height="wrap_content"               
+               android:layout_marginRight="10dp"
+               android:layout_marginBottom="10dp"
+               />
+    <TextView android:id="@+id/text"
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:textColor="#FFF"
+              />
+    <Button android:id="@+id/button"
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"
+			android:text="Take Photo"
+			android:visibility="gone"
+			android:enabled="false"
+			android:layout_weight="1"/>
+   
+</LinearLayout>
+</ScrollView>
Index: /other-projects/tipple-android/tipple-casey/res/layout/filebrowser.xml
===================================================================
--- /other-projects/tipple-android/tipple-casey/res/layout/filebrowser.xml	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/res/layout/filebrowser.xml	(revision 26526)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge xmlns:android="http://schemas.android.com/apk/res/android" >
+   <GridView android:id="@+id/fileBrowserView"
+		android:layout_width="fill_parent" android:layout_height="fill_parent"
+		android:fadingEdge="vertical" android:fadingEdgeLength="30dip"
+		android:columnWidth="100dip" android:numColumns="auto_fit" />
+    
+
+</merge>
Index: /other-projects/tipple-android/tipple-casey/res/layout/main.xml
===================================================================
--- /other-projects/tipple-android/tipple-casey/res/layout/main.xml	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/res/layout/main.xml	(revision 26526)
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical" >
+
+    <TextView
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/hello" />
+
+</LinearLayout>
Index: /other-projects/tipple-android/tipple-casey/res/layout/markerpopup.xml
===================================================================
--- /other-projects/tipple-android/tipple-casey/res/layout/markerpopup.xml	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/res/layout/markerpopup.xml	(revision 26526)
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal"
+    android:minWidth="200dip" 
+    android:gravity="center_horizontal">
+    
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"     
+        android:orientation="horizontal"
+        android:gravity="center_vertical"
+        android:layout_weight="1"
+        android:padding="1.5dp" >
+        
+     <ImageView
+                android:id="@+id/iPopupImage"
+                android:layout_width="40dip"
+                android:layout_height="54dip"            
+                android:paddingTop="10dip"
+                android:paddingRight="10dip" />
+     
+	        <LinearLayout	            
+	             android:layout_width="0dp"
+            	 android:layout_height="wrap_content"
+           		 android:layout_weight="1"
+           		 android:orientation="vertical"
+           		 android:paddingTop="10dip" >               
+         
+
+                <TextView
+                    android:id="@+id/tTitle"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:scrollbars="vertical"
+                    android:scrollbarStyle="insideInset"
+                    android:text=""
+                    android:focusable="false" />
+
+                <TextView
+                    android:id="@+id/tSnippet"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:singleLine="false"
+                    android:text=""
+                    android:textAppearance="?android:attr/textAppearanceSmall" />
+
+            </LinearLayout>
+        </LinearLayout>    
+ 
+
+</LinearLayout>
Index: /other-projects/tipple-android/tipple-casey/res/menu/options_menu.xml
===================================================================
--- /other-projects/tipple-android/tipple-casey/res/menu/options_menu.xml	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/res/menu/options_menu.xml	(revision 26526)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+	<!--  <item android:id="@+id/menu_info" android:title="@string/menu_info"
+		android:icon="@drawable/ic_menu_info_details">
+	</item>-->
+	
+	<item android:id="@+id/menu_preferences" android:title="@string/menu_preferences"
+		android:icon="@drawable/ic_menu_preferences" />
+			
+	<!--  <item android:id="@+id/menu_logfile" android:title="@string/menu_logfile"
+		android:icon="@drawable/ic_menu_archive" /> -->   
+
+</menu>
Index: /other-projects/tipple-android/tipple-casey/res/values/arrays.xml
===================================================================
--- /other-projects/tipple-android/tipple-casey/res/values/arrays.xml	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/res/values/arrays.xml	(revision 26526)
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+	<string-array name="preferences_text_audio_mode_entries">
+		<item>Text only</item>
+		<item>Text with audio</item>
+		<item>Audio only</item>
+		<item>Audio with text</item>
+	</string-array>
+
+	<string-array name="preferences_text_audio_mode_entry_values">
+		<item>TEXT_ONLY</item>
+		<item>TEXT_PLUS_AUDIO</item>
+		<item>AUDIO_ONLY</item>
+		<item>AUDIO_PLUS_TEXT</item>
+	</string-array>
+	
+	    <string-array name="preferences_book_mode_entries">
+		<item >Book 1:Garden</item>
+		<item >Book 2:Garden Design</item>
+		<item>Book 1 and Book 2</item>		
+	</string-array>
+
+	<string-array name="preferences_book_mode_entry_values">
+		<item>BOOK_A</item>
+		<item>BOOK_B</item>
+		<item>BOOK_AB</item>		
+	</string-array>
+	
+     <string name="preferences_book_mode_default">BOOK_AB</string>
+	<string name="preferences_text_audio_mode_default">AUDIO_PLUS_TEXT</string>
+</resources>
Index: /other-projects/tipple-android/tipple-casey/res/values/strings.xml
===================================================================
--- /other-projects/tipple-android/tipple-casey/res/values/strings.xml	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/res/values/strings.xml	(revision 26526)
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<resources>
+
+    <string name="hello">Hello World, MapsforgeMap1Activity!</string>
+    <string name="app_name">MapsforgeMap1</string>
+    
+     <!--  General labels -->
+    <string name="cancel">Cancel</string>
+	<string name="error">Error</string>
+	<string name="ok">OK</string>
+    <string name="latitude">Latitude</string>
+	<string name="longitude">Longitude</string>
+	
+	<!--  Values used in OptionsMenu -->
+    <string name="menu_info">Info</string>
+    <string name="menu_preferences">Preferences</string>
+    <string name="menu_logfile">Log file</string>
+    
+	<string name="log_file_invalid">
+	    The selected file is not a valid log file. 
+		Please select another file.
+	</string>
+	<string name="log_file_select">Please select a log file.</string>
+	
+	
+    <string name="logging_error_continue">Continue anyway</string>
+    <string name="logging_error_stop">Stop Tipple</string>
+    <string name="logging_ok_enable">Enable</string>
+    <string name="logging_ok_disable">Disable</string>
+     
+    <string name="preferences_map">Map settings</string>
+    <string name="preferences_show_scale_bar">Map scale bar</string>
+	<string name="preferences_show_scale_bar_desc">Show the scale of the map</string>
+	<string name="preferences_centre_on_loc">Centre on GPS location</string>
+	<string name="preferences_centre_on_loc_desc">Automatically centres the map based on your GPS location</string>
+	<string name="preferences_show_sights">Show sights</string>
+	<string name="preferences_show_sights_desc">Show the landmarks that Tipple has information about</string>
+	<string name="preferences_show_user_trail">Show your trail</string>
+	<string name="preferences_show_user_trail_desc">Display the recorded route walked for a designated log file</string>
+	
+	<!--  Values used in text/audio setting -->
+	<string name="preferences_mode">Text/Audio settings</string>
+	<string name="preferences_text_audio_mode">Text and/or Audio</string>
+	<string name="preferences_text_audio_mode_desc">Control the ability to display text and play audio</string>
+	
+	<!--  Values used in book number options 
+	<string name="preferences_book">Book settings</string>
+	<string name="preferences_book_mode">Book number Setting </string>
+	<string name="preferences_book_mode_desc">Control the ability to display number of books on a map</string>-->
+	
+	<!--Values used in checked box layout of book number options -->
+
+    <string name="preferences_book"> Book Selection</string>
+    <string name="preferences_book_a">Title:Paradise Collection</string>
+	<string name="preferences_book_a_desc">Introduce Paradise Collection Garden in Hamilton</string>
+	<string name="preferences_book_b">Title:Station of the Cross</string>
+	<string name="preferences_book_b_desc">Experience the stations of the cross 2012</string>
+</resources>
Index: /other-projects/tipple-android/tipple-casey/res/xml/preferences.xml
===================================================================
--- /other-projects/tipple-android/tipple-casey/res/xml/preferences.xml	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/res/xml/preferences.xml	(revision 26526)
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
+android:title="@string/menu_preferences">
+	<PreferenceCategory android:title="@string/preferences_map">
+		<CheckBoxPreference android:title="@string/preferences_show_scale_bar"
+			android:summary="@string/preferences_show_scale_bar_desc"
+			android:key="showScaleBar" />
+		<CheckBoxPreference android:title="@string/preferences_centre_on_loc"
+			android:summary="@string/preferences_centre_on_loc_desc"
+			android:key="centreOnGPSLoc" />
+		<CheckBoxPreference android:title="@string/preferences_show_sights"
+			android:summary="@string/preferences_show_sights_desc"
+			android:key="showSights" />		
+		<CheckBoxPreference android:title="@string/preferences_show_user_trail"
+			android:summary="@string/preferences_show_user_trail_desc"
+			android:key="showUserTrail" />			
+	
+	</PreferenceCategory>	
+    <PreferenceCategory android:title="@string/preferences_mode">
+    	<ListPreference android:title="@string/preferences_text_audio_mode"
+			android:summary="@string/preferences_text_audio_mode_desc"
+			android:entries="@array/preferences_text_audio_mode_entries"
+			android:entryValues="@array/preferences_text_audio_mode_entry_values"
+			android:key="textAudioMode" android:defaultValue="@string/preferences_text_audio_mode_default" />
+    </PreferenceCategory>
+    
+    <PreferenceCategory android:title="@string/preferences_book">
+        <!--  
+         <ListPreference android:title="@string/preferences_book_mode"
+            android:summary="@string/preferences_book_mode_desc"
+            android:entries="@array/preferences_book_mode_entries"
+            android:entryValues="@array/preferences_book_mode_entry_values"
+            android:key="bookMode" android:defaultValue="@string/preferences_book_mode_default" />-->
+            
+        <CheckBoxPreference android:title="@string/preferences_book_a"
+			android:summary="@string/preferences_book_a_desc"
+			android:key="showBookA" />
+		<CheckBoxPreference android:title="@string/preferences_book_b"
+			android:summary="@string/preferences_book_b_desc"
+			android:key="showBookB" />
+			
+    </PreferenceCategory>
+    
+    
+
+</PreferenceScreen>
Index: /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/ArrayItemizedMarkerOverlay.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/ArrayItemizedMarkerOverlay.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/ArrayItemizedMarkerOverlay.java	(revision 26526)
@@ -0,0 +1,364 @@
+package org.mapsforge.android.maps;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.tipple.mapDisplay.R;
+import org.tipple.mapDisplay.TakePicture;
+import org.tipple.mapDisplay.tippleActivity;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.MeasureSpec;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.LinearLayout.LayoutParams;
+import android.widget.TextView;
+
+/**
+ * Thread-safe implementation of the {@link ItemizedMarkerOverlay} class using
+ * an {@link ArrayList} as internal data structure. casey: implement the ontap
+ * method for the customized overlay item
+ */
+public class ArrayItemizedMarkerOverlay extends
+		ItemizedMarkerOverlay<OverlayMarkerItem> {
+	private static final int ARRAY_LIST_INITIAL_CAPACITY = 8;
+	private static final String THREAD_NAME = "ArrayItemizedMarkerOverlay";
+
+	protected final Context context;
+	protected AlertDialog.Builder builder;// Builder builder
+	protected View dialogLayout;
+	protected AlertDialog alertDialog;
+	Bitmap bmScreen;
+
+	protected OverlayItem item;
+	protected final ArrayList<OverlayMarkerItem> overlayMarkerItems;
+	protected OverlayMarkerItem overlayItem;
+	protected Drawable marker;
+	protected Drawable defaultMarker;
+
+	// casey
+	private List<Integer> visibleItems;
+	private int numberOfSize;
+	// private OverlayMarkerItem checkOverlayItem;
+	// casey: popup window
+	private MarkerPopup popup;
+	private String imageName;
+
+	/**
+	 * Constructs a new ArrayItemizedOverlay.
+	 * 
+	 * @param defaultMarker
+	 *            the default marker.
+	 * @param context
+	 *            the reference to the application context.
+	 */
+	public ArrayItemizedMarkerOverlay(Drawable defaultMarker, Context context) {
+
+		super(boundCenterBottom(defaultMarker));
+		this.context = context;
+		this.defaultMarker = defaultMarker;
+		this.overlayMarkerItems = new ArrayList<OverlayMarkerItem>(
+				ARRAY_LIST_INITIAL_CAPACITY);
+		this.visibleItems = new ArrayList<Integer>(numberOfSize);
+
+	}
+
+	public void setMarker(Drawable marker) {
+		this.marker = boundCenterBottom(marker);
+	}
+
+	public Drawable getMarker() {
+		return this.marker;
+	}
+
+	/**
+	 * Adds the given item to the Overlay.
+	 * 
+	 * @param overlayItem
+	 *            the item that should be added to the Overlay.
+	 */
+	public synchronized void addOverlay(OverlayMarkerItem overlayItem) {
+		this.overlayMarkerItems.add(overlayItem);
+		populate();
+	}
+
+	/**
+	 * Adds all items of the given collection to the Overlay.
+	 * 
+	 * @param c
+	 *            collection whose items should be added to the Overlay.
+	 */
+	public synchronized void addOverlays(
+			Collection<? extends OverlayMarkerItem> c) {
+		this.overlayMarkerItems.addAll(c);
+		populate();
+	}
+
+	/**
+	 * Removes all items from the Overlay.
+	 */
+	public synchronized void clear() {
+		this.overlayMarkerItems.clear();
+		populate();
+	}
+
+	@Override
+	public String getThreadName() {
+		return THREAD_NAME;
+	}
+
+	/**
+	 * Removes the given item from the Overlay.
+	 * 
+	 * @param overlayMarkerItem
+	 *            the item that should be removed from the Overlay.
+	 */
+	public synchronized void removeOverlay(OverlayMarkerItem overlayMarkerItem) {
+		this.overlayMarkerItems.remove(overlayMarkerItem);
+		populate();
+	}
+
+	@Override
+	public synchronized int size() {
+		numberOfSize = this.overlayMarkerItems.size();
+		return this.overlayMarkerItems.size();
+	}
+
+	@Override
+	public synchronized OverlayMarkerItem createItem(int i) {
+		return this.overlayMarkerItems.get(i);
+	}
+
+	protected boolean onTap(int index, MapView mapView) {
+
+		this.overlayItem = createItem(index);
+		if (this.overlayItem != null) {
+			if (this.overlayItem.getDescription() != null) {
+				hideOtherDialog(this.overlayMarkerItems, this.overlayItem,
+						mapView);
+				LayoutInflater inflater = (LayoutInflater) this.context
+						.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+				View view = inflater.inflate(R.layout.custom_dialog, null);
+				dialogLayout = (View) view.findViewById(R.id.ScrollView01);// ScrollView01
+				TextView text = (TextView) dialogLayout.findViewById(R.id.text);
+				text.setText(this.overlayItem.getDescription() + "\n" + "\n"
+						+ this.overlayItem.getContent());
+				// String fileName = "/sdcard/";
+				String fileName = tippleActivity.imageDirectory;
+				fileName += this.overlayItem.getDescription() + ".jpg";
+				File imgFile = new File(fileName);
+
+				// Take image for chapter without image initially
+				// save the image then next time can retrieve it
+				if (!imgFile.exists()) {
+					Button camera = (Button) dialogLayout
+							.findViewById(R.id.button);
+					camera.setEnabled(true);
+					camera.setVisibility(0);
+					String tmpFileName = this.overlayItem.getDescription()
+							+ ".jpg";
+					camera.setOnClickListener(new RandomClickListener(
+							tmpFileName));
+				}
+
+				if (imgFile.exists()) {
+
+					Bitmap bitmap = BitmapFactory.decodeFile(imgFile
+							.getAbsolutePath());
+					int width = bitmap.getWidth();
+					int height = bitmap.getHeight();
+					int newWidth = 200;
+					int newHeight = 150;
+					float scaleWidth = ((float) newWidth) / width;
+					float scaleHeight = ((float) newHeight) / height;
+					Matrix matrix = new Matrix();
+					matrix.postScale(scaleWidth, scaleHeight);
+
+					Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
+							width, height, matrix, true);
+					BitmapDrawable bmd = new BitmapDrawable(resizedBitmap);
+					ImageView image = (ImageView) dialogLayout
+							.findViewById(R.id.image);
+					image.setImageDrawable(bmd);
+
+				}
+
+				builder = new AlertDialog.Builder(this.context);
+				builder.setView(dialogLayout);
+
+				builder.setPositiveButton("OK", null);
+				alertDialog = builder.create();
+				alertDialog.show();
+			}
+			return true;
+		}
+		return false;
+
+	}
+
+	public boolean onTap(GeoPoint p, MapView mapView) {
+
+		Projection projection = mapView.getProjection();
+		Point eventPosition = projection.toPixels(p, null);
+
+		// check if the translation to pixel coordinates has failed
+		if (eventPosition == null) {
+			return false;
+		}
+		OverlayMarkerItem checkOverlayItem;
+		Point checkItemPoint = new Point();
+		Rect checkMarkerBounds;
+		int checkLeft;
+		int checkRight;
+		int checkTop;
+		int checkBottom;
+
+		synchronized (this.visibleItems) {
+			int numberOfSize = this.size();
+			Context contexto = mapView.getContext();
+			if (numberOfSize < 1) {
+				return false;
+			}
+
+			for (int i = 0; i < this.size(); ++i) {
+				checkOverlayItem = createItem(i);
+
+				if (checkOverlayItem == null) {
+					continue;
+				}
+				synchronized (checkOverlayItem) {
+					if (checkOverlayItem.getPoint() == null) {
+						continue;
+					}
+
+					checkItemPoint = projection.toPixels(
+							checkOverlayItem.getPoint(), checkItemPoint);
+					// check if the translation to pixel coordinates has failed
+					if (checkItemPoint == null) {
+						continue;
+					}
+					checkMarkerBounds = this.defaultMarker.getBounds();
+
+					checkLeft = checkItemPoint.x + checkMarkerBounds.left;
+					checkRight = checkItemPoint.x + checkMarkerBounds.right;
+					checkTop = checkItemPoint.y + checkMarkerBounds.top;
+					checkBottom = checkItemPoint.y + checkMarkerBounds.bottom;
+
+					if (checkRight >= eventPosition.x
+							&& checkLeft <= eventPosition.x
+							&& checkBottom >= eventPosition.y
+							&& checkTop <= eventPosition.y) {
+
+						return onTap(i, mapView);
+					}
+				}// end of synchronized (checkOverlayItem)
+			}
+		}
+
+		// no hit
+		return false;
+	}
+
+	private boolean onBalloonTap(MapView mapView,
+			OverlayMarkerItem checkOverlayItem) {
+		hideOtherBalloons(this.overlayMarkerItems, checkOverlayItem);
+		this.popup = new MarkerPopup(mapView);
+		MapView.LayoutParams params = new MapView.LayoutParams(
+				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+		popup.setData(checkOverlayItem);
+
+		// position
+		GeoPoint point = checkOverlayItem.getPoint();
+
+		// change parameter
+		popup.setLayoutParams(params);
+
+		// visibility
+		popup.setVisibility(View.VISIBLE);
+		mapView.addView(popup, params);
+
+		popup.setDrawingCacheEnabled(true);
+		popup.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
+				MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+		popup.layout(0, 0, popup.getMeasuredWidth(), popup.getMeasuredHeight());
+		popup.buildDrawingCache(true);
+		popup.setDrawingCacheEnabled(false); // clear drawing
+												// cache
+
+		mapView.getController().setCenter(point);
+
+		return true;
+
+	}
+
+	public void hideDialog(MapView mapView) {
+		if (dialogLayout != null) {
+			mapView.removeView(dialogLayout);
+		}
+
+	}
+
+	private void hideOtherDialog(ArrayList<OverlayMarkerItem> overlays,
+			OverlayMarkerItem item, MapView mapView) {
+
+		for (OverlayMarkerItem overlay : overlays) {
+			if ((overlay != null) && (overlay != item))
+				hideDialog(mapView);
+		}
+
+	}
+
+	public void hideBalloon() {
+		if (popup != null) {
+			popup.setVisibility(View.GONE);
+		}
+
+	}
+
+	private void hideOtherBalloons(ArrayList<OverlayMarkerItem> overlays,
+			OverlayMarkerItem item) {
+
+		for (OverlayMarkerItem overlay : overlays) {
+			if ((overlay != null) && (overlay != item))
+				hideBalloon();
+		}
+
+	}
+
+	public synchronized boolean unTap(GeoPoint p, MapView mapView) {
+
+		alertDialog.cancel();
+		return true;
+	}
+
+	// inner class for taking pictures
+	public class RandomClickListener implements View.OnClickListener {
+		private final String tmpImage;
+
+		public RandomClickListener(final String randomIndex) {
+			this.tmpImage = randomIndex;
+		}
+
+		@Override
+		public void onClick(View view) {
+			Intent myIntent = new Intent(view.getContext(), TakePicture.class);
+			myIntent.putExtra("filename", tmpImage);
+			context.startActivity(myIntent);
+
+		}
+	}
+
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/ArrayItemizedOverlayTweaked.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/ArrayItemizedOverlayTweaked.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/ArrayItemizedOverlayTweaked.java	(revision 26526)
@@ -0,0 +1,112 @@
+package org.mapsforge.android.maps;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+
+/**
+ * Thread-safe implementation of the {@link ItemizedOverlay} class using an
+ * {@link ArrayList} as internal data structure.
+ */
+public class ArrayItemizedOverlayTweaked extends ItemizedOverlay<OverlayItem> {
+	private static final int ARRAY_LIST_INITIAL_CAPACITY = 8;
+	private static final String THREAD_NAME = "ArrayItemizedOverlayTweaked";
+
+	protected final Context context;
+	protected AlertDialog.Builder dialog;
+	protected OverlayItem item;
+	protected final ArrayList<OverlayItem> overlayItems;
+
+	/**
+	 * Constructs a new ArrayItemizedOverlay.
+	 * 
+	 * @param defaultMarker
+	 *            the default marker.
+	 * @param context
+	 *            the reference to the application context.
+	 */
+	public ArrayItemizedOverlayTweaked(Drawable defaultMarker, Context context) {
+		super(boundCenterBottom(defaultMarker));
+		this.context = context;
+		this.overlayItems = new ArrayList<OverlayItem>(
+				ARRAY_LIST_INITIAL_CAPACITY);
+	}
+
+	/**
+	 * Adds the given item to the Overlay.
+	 * 
+	 * @param overlayItem
+	 *            the item that should be added to the Overlay.
+	 */
+	public synchronized void addOverlay(OverlayItem overlayItem) {
+		this.overlayItems.add(overlayItem);
+		populate();
+	}
+
+	/**
+	 * Adds all items of the given collection to the Overlay.
+	 * 
+	 * @param c
+	 *            collection whose items should be added to the Overlay.
+	 */
+	public synchronized void addOverlays(Collection<? extends OverlayItem> c) {
+		this.overlayItems.addAll(c);
+		populate();
+	}
+
+	/**
+	 * Removes all items from the Overlay.
+	 */
+	public synchronized void clear() {
+		this.overlayItems.clear();
+		populate();
+	}
+
+	@Override
+	public String getThreadName() {
+		return THREAD_NAME;
+	}
+
+	/**
+	 * Removes the given item from the Overlay.
+	 * 
+	 * @param overlayItem
+	 *            the item that should be removed from the Overlay.
+	 */
+	public synchronized void removeOverlay(OverlayItem overlayItem) {
+		this.overlayItems.remove(overlayItem);
+		populate();
+		super.requestRedraw();
+	}
+
+	@Override
+	public synchronized int size() {
+		return this.overlayItems.size();
+	}
+
+	@Override
+	public synchronized OverlayItem createItem(int i) {
+		return this.overlayItems.get(i);
+	}
+
+	@Override
+	// you always need this even it doesn't do anything visibly
+	protected synchronized boolean onTap(int index) {
+
+		OverlayItem item = createItem(index);
+
+		if (item != null)
+			System.out.println("ArrayItemizedOverlayTweaked ontap");
+		return true;
+		// this.dialog = new AlertDialog.Builder(this.context);
+		// this.dialog.setTitle(this.item.getTitle());
+		// this.dialog.setMessage(this.item.getSnippet());
+		// this.dialog.show();
+		//
+		// return false;
+	}
+
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/ArrayItemizedTextAudioOverlay.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/ArrayItemizedTextAudioOverlay.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/ArrayItemizedTextAudioOverlay.java	(revision 26526)
@@ -0,0 +1,67 @@
+package org.mapsforge.android.maps;
+
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.speech.tts.TextToSpeech;
+
+public class ArrayItemizedTextAudioOverlay extends ArrayItemizedOverlayTweaked {
+	protected final TextToSpeech tts_;
+	protected AlertDialog dialogAlert;
+	protected Drawable marker;
+
+	public ArrayItemizedTextAudioOverlay(Drawable defaultMarker,
+			Context context, TextToSpeech tts) {
+		super(defaultMarker, context);
+		tts_ = tts;
+	}
+
+	public ArrayItemizedTextAudioOverlay(Drawable defaultMarker, Context context) {
+		super(defaultMarker, context);
+		tts_ = null;
+	}
+
+	/*
+	 * 21 -03 try to change the marker next need to override the method
+	 * "drawonOvermap" --option 2
+	 */
+	public void setMarker(Drawable marker) {
+		this.marker = boundCenterBottom(marker);
+	}
+
+	public Drawable getMarker() {
+		return this.marker;
+	}
+
+	@Override
+	public synchronized boolean onTap(int index) {
+		this.item = this.overlayItems.get(index);
+		// this.dialog = new AlertDialog.Builder(this.context);
+		// this.dialog.setTitle(this.item.getTitle());
+		// this.dialog.setMessage(this.item.getSnippet());
+		// dialogAlert = this.dialog.show();
+		//
+		// return true;
+
+		// OverlayItem item = createItem(index);
+		if (item != null) {
+			// System.out.println("ArrayItemizedTextAudioOverlay ontap");
+			Builder builder = new AlertDialog.Builder(this.context);
+			// builder.setIcon(android.R.drawable.ic_menu_info_details);
+			builder.setTitle(item.getTitle());
+			builder.setMessage(item.getSnippet());
+			builder.setPositiveButton("OK", null);
+			builder.show();
+		}
+		return true;
+
+	}
+
+	public synchronized boolean unTap() {
+
+		// dialogAlert.cancel();
+		// tts_.stop();
+		return true;
+	}
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/CirclesOverlay.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/CirclesOverlay.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/CirclesOverlay.java	(revision 26526)
@@ -0,0 +1,137 @@
+package org.mapsforge.android.maps;
+
+import java.util.ArrayList;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Point;
+
+/**
+ * CirclesOverlay is a special Overlay to display a series of circles on top of
+ * the map. The radius of a circle is specified in meters and will be
+ * automatically converted to pixels at each redraw.
+ * <p>
+ * All rendering parameters like color, stroke width, pattern and transparency
+ * can be configured via the two {@link android.graphics.Paint Paint} objects in
+ * the {@link #CircleOverlay(Paint,Paint)} constructor.
+ */
+
+public class CirclesOverlay extends Overlay {
+	private static final String THREAD_NAME = "CirclesOverlay";
+
+	private byte cachedZoomLevel;
+
+	private Paint fillPaint;
+	private Paint outlinePaint;
+
+	private final Path path;
+	private ArrayList<GeoPoint> center;
+	private ArrayList<Float> radius;
+	private ArrayList<Point> cachedCenterPosition;
+
+	/**
+	 * Constructs a new CircleOverlay.
+	 * 
+	 * @param fillPaint
+	 *            the paint object which will be used to fill the overlay.
+	 * @param outlinePaint
+	 *            the paint object which will be used to draw the outline of the
+	 *            overlay.
+	 */
+	public CirclesOverlay(Paint fillPaint, Paint outlinePaint) {
+		this.path = new Path();
+
+		this.center = new ArrayList<GeoPoint>();
+		this.radius = new ArrayList<Float>();
+		this.cachedCenterPosition = new ArrayList<Point>();
+
+		setPaint(fillPaint, outlinePaint);
+	}
+
+	public synchronized void reset() {
+		this.center = new ArrayList<GeoPoint>();
+		this.radius = new ArrayList<Float>();
+		this.cachedCenterPosition = new ArrayList<Point>();
+		path.reset();
+		super.requestRedraw();
+	}
+
+	/**
+	 * Sets the parameters of the circle.
+	 * 
+	 * @param center
+	 *            the geographical coordinates of the centre point.
+	 * @param radius
+	 *            the radius of the circle in meters.
+	 */
+	public synchronized void addCircleData(GeoPoint center, float radius) {
+		this.center.add(center);
+		this.radius.add(radius);
+		this.cachedCenterPosition.add(new Point());
+
+		this.cachedZoomLevel = Byte.MIN_VALUE;
+		super.requestRedraw();
+	}
+
+	/**
+	 * Sets the paint objects which will be used to draw the overlay.
+	 * 
+	 * @param fillPaint
+	 *            the paint object which will be used to fill the overlay.
+	 * @param outlinePaint
+	 *            the paint object which will be used to draw the outline of the
+	 *            overlay.
+	 */
+	public synchronized void setPaint(Paint fillPaint, Paint outlinePaint) {
+		this.fillPaint = fillPaint;
+		this.outlinePaint = outlinePaint;
+	}
+
+	@Override
+	protected synchronized void drawOverlayBitmap(Canvas canvas,
+			Point drawPosition, Projection projection, byte drawZoomLevel) {
+		if (this.center.size() == 0 || this.radius.size() == 0) {
+			// no valid parameters to draw the circle
+			return;
+		} else if (this.fillPaint == null && this.outlinePaint == null) {
+			// no paint to draw
+			return;
+		}
+
+		// make sure that the cached centre position is valid
+		if (drawZoomLevel != this.cachedZoomLevel) {
+			for (int i = 0; i < center.size(); i++) {
+				Point cachedPoint = projection.toPoint(this.center.get(i),
+						this.cachedCenterPosition.get(i), drawZoomLevel);
+				this.cachedCenterPosition.set(i, cachedPoint);
+			}
+
+			this.cachedZoomLevel = drawZoomLevel;
+		}
+
+		// assemble the path
+		this.path.reset();
+		for (int i = 0; i < cachedCenterPosition.size(); i++) {
+			float radius_meters = projection.metersToPixels(this.radius.get(i),
+					drawZoomLevel);
+
+			this.path.addCircle(this.cachedCenterPosition.get(i).x
+					- drawPosition.x, this.cachedCenterPosition.get(i).y
+					- drawPosition.y, radius_meters, Path.Direction.CCW);
+		}
+
+		// draw the path on the canvas
+		if (this.fillPaint != null) {
+			canvas.drawPath(this.path, this.fillPaint);
+		}
+		if (this.outlinePaint != null) {
+			canvas.drawPath(this.path, this.outlinePaint);
+		}
+	}
+
+	@Override
+	protected String getThreadName() {
+		return THREAD_NAME;
+	}
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/ItemizedMarkerOverlay.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/ItemizedMarkerOverlay.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/ItemizedMarkerOverlay.java	(revision 26526)
@@ -0,0 +1,192 @@
+package org.mapsforge.android.maps;
+
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Paint.Style;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+
+/**
+ * ItemizedMarkerOverlay is an abstract base class to display a list of
+ * OverlayMarkerItems.
+ * 
+ * @param <Item>
+ *            the type of items handled by this Overlay.
+ */
+public abstract class ItemizedMarkerOverlay<Item extends OverlayMarkerItem>
+		extends Overlay {
+	private static final int ARRAY_LIST_INITIAL_CAPACITY = 8;
+	private static final String THREAD_NAME = "ItemizedMarkerOverlay";
+
+	/**
+	 * Sets the bounds of the given drawable so that (0,0) is the center of the
+	 * bottom row.
+	 * 
+	 * @param balloon
+	 *            the drawable whose bounds should be set.
+	 * @return the given drawable.
+	 */
+	protected static Drawable boundCenter(Drawable balloon) {
+		balloon.setBounds(balloon.getIntrinsicWidth() / -2,
+				balloon.getIntrinsicHeight() / -2,
+				balloon.getIntrinsicWidth() / 2,
+				balloon.getIntrinsicHeight() / 2);
+		return balloon;
+	}
+
+	/**
+	 * Sets the bounds of the given drawable so that (0,0) is the center of the
+	 * bounding box.
+	 * 
+	 * @param balloon
+	 *            the drawable whose bounds should be set.
+	 * @return the given drawable.
+	 */
+	protected static Drawable boundCenterBottom(Drawable balloon) {
+		balloon.setBounds(balloon.getIntrinsicWidth() / -2,
+				-balloon.getIntrinsicHeight(), balloon.getIntrinsicWidth() / 2,
+				0);
+		return balloon;
+	}
+
+	private int bottom;
+	private Drawable defaultMarker;
+	private Drawable itemMarker;
+	private final Point itemPosition;
+	private int left;
+	private Rect markerBounds;
+	private int numberOfItems;
+	private Item overlayItem;
+	private int right;
+	private int top;
+
+	/**
+	 * Constructs a new ItemizedOverlay.
+	 * 
+	 * @param defaultMarker
+	 *            the default marker for each item.
+	 */
+	public ItemizedMarkerOverlay(Drawable defaultMarker) {
+		this.defaultMarker = defaultMarker;
+		this.itemPosition = new Point();
+	}
+
+	/**
+	 * Returns the numbers of items in this Overlay.
+	 * 
+	 * @return the numbers of items in this Overlay.
+	 */
+	public abstract int size();
+
+	/**
+	 * Creates an item in the Overlay.
+	 * 
+	 * @param i
+	 *            the index of the item.
+	 * @return the item.
+	 */
+	protected abstract Item createItem(int i);
+
+	@Override
+	protected synchronized void drawOverlayBitmap(Canvas canvas,
+			Point drawPosition, Projection projection, byte drawZoomLevel) {
+		this.numberOfItems = size();
+		if (this.numberOfItems < 1) {
+			// no items to draw
+			return;
+		}
+
+		// draw the Overlay items
+		for (int i = 0; i < this.numberOfItems; ++i) {
+			// get the current item
+			this.overlayItem = createItem(i);
+
+			// check if the item has a position
+			if (this.overlayItem.getPoint() == null) {
+				continue;
+			}
+
+			// make sure that the cached item position is valid
+			if (drawZoomLevel != this.overlayItem.cachedZoomLevel) {
+				this.overlayItem.cachedMapPosition = projection.toPoint(
+						this.overlayItem.getPoint(),
+						this.overlayItem.cachedMapPosition, drawZoomLevel);
+				this.overlayItem.cachedZoomLevel = drawZoomLevel;
+			}
+
+			// calculate the relative item position on the display
+			this.itemPosition.x = this.overlayItem.cachedMapPosition.x
+					- drawPosition.x;
+			this.itemPosition.y = this.overlayItem.cachedMapPosition.y
+					- drawPosition.y;
+
+			// get the correct marker for the item
+			if (this.overlayItem.getMarker() == null) {
+				this.itemMarker = this.defaultMarker;
+			} else {
+				this.itemMarker = this.overlayItem.getMarker();
+			}
+
+			// get the position of the marker
+			this.markerBounds = this.itemMarker.copyBounds();
+
+			// calculate the bounding box of the marker
+			this.left = this.itemPosition.x + this.markerBounds.left;
+			this.right = this.itemPosition.x + this.markerBounds.right;
+			this.top = this.itemPosition.y + this.markerBounds.top;
+			this.bottom = this.itemPosition.y + this.markerBounds.bottom;
+
+			// check if the bounding box of the marker intersects with the
+			// canvas
+			if (this.right >= 0 && this.left <= canvas.getWidth()
+					&& this.bottom >= 0 && this.top <= canvas.getHeight()) {
+				// set the position of the marker
+				this.itemMarker.setBounds(this.left, this.top, this.right,
+						this.bottom);
+
+				// draw the item marker on the canvas
+				this.itemMarker.draw(canvas);
+
+				// restore the position of the marker
+				this.itemMarker.setBounds(this.markerBounds);
+
+				// Add text label next to marker
+				Paint paint_text = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+				paint_text.setColor(Color.BLACK);
+				paint_text.setStyle(Style.FILL);
+				paint_text.setTextSize(20);
+
+				canvas.drawText(overlayItem.getTitle(), itemPosition.x - 10,
+						itemPosition.y - 28, paint_text);
+			}
+		}
+	}
+
+	@Override
+	protected String getThreadName() {
+		return THREAD_NAME;
+	}
+
+	/**
+	 * Handles a tap event.
+	 * <p>
+	 * The default implementation of this method does nothing and returns false.
+	 * 
+	 * @param index
+	 *            the position of the item.
+	 * 
+	 * @return true if the event was handled, false otherwise. try to make this
+	 *         Ontap work --option 1
+	 */
+
+	/**
+	 * This method should be called after items have been added to the Overlay.
+	 */
+	protected final void populate() {
+		super.requestRedraw();
+	}
+
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/MarkerPopup.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/MarkerPopup.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/MarkerPopup.java	(revision 26526)
@@ -0,0 +1,62 @@
+package org.mapsforge.android.maps;
+
+import org.tipple.mapDisplay.R;
+
+import android.content.Context;
+import android.text.method.ScrollingMovementMethod;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+public class MarkerPopup extends LinearLayout {
+
+	private TextView title;
+	private TextView snippet;
+	private ImageView image;
+
+	public MarkerPopup(MapView mapView) {
+		super(mapView.getContext());
+		setupPopup(mapView);
+		this.setPadding(20, 10, 20, 10);
+		this.setVisibility(View.GONE);
+	}
+
+	private void setupPopup(ViewGroup mapView) {
+		LayoutInflater inflater = (LayoutInflater) mapView.getContext()
+				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+		View view = inflater.inflate(R.layout.markerpopup, this);
+		title = (TextView) view.findViewById(R.id.tTitle);
+		title.setGravity(Gravity.BOTTOM | Gravity.FILL_HORIZONTAL);
+		title.setTextColor(0xffffffff);
+		title.setBackgroundColor(0xCC000000);
+		title.setTextSize(14.0f);
+		title.setVerticalScrollBarEnabled(true);
+		title.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
+		title.setMovementMethod(new ScrollingMovementMethod());
+		image = (ImageView) view.findViewById(R.id.iPopupImage);
+		image.setImageDrawable(null);
+
+	}
+
+	public void setData(OverlayMarkerItem item) {
+		this.setVisibility(VISIBLE);
+		setObjects(item);
+	}
+
+	private void setObjects(OverlayMarkerItem item) {
+		if (item.getTitle() != null) {
+			title.setVisibility(VISIBLE);
+			String text_desc = item.getDescription();
+			text_desc += "\n" + item.getContent();
+			title.setText(text_desc);
+			title.setSelected(true);
+		} else {
+			title.setText("");
+			title.setVisibility(INVISIBLE);
+		}
+	}
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/OverlayMarkerItem.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/OverlayMarkerItem.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/OverlayMarkerItem.java	(revision 26526)
@@ -0,0 +1,145 @@
+package org.mapsforge.android.maps;
+
+import android.graphics.Point;
+import android.graphics.drawable.Drawable;
+
+/**
+ * An OverlayMarkerItem holds all parameters of a single element on an
+ * {@link ItemizedMarkerOverlay}.
+ */
+public class OverlayMarkerItem {
+	/**
+	 * Marker used to indicate the item.
+	 */
+	protected Drawable marker;
+
+	/**
+	 * Geographical position of the item.
+	 */
+	protected final GeoPoint point;
+
+	/**
+	 * Title of the item.
+	 */
+	protected final String title;
+
+	/*
+	 * description of the itme
+	 */
+	protected final String description;
+	protected final String content;
+	/**
+	 * 
+	 * Cached position of the item on the map.
+	 */
+	Point cachedMapPosition;
+
+	/**
+	 * Zoom level of the cached map position.
+	 */
+	byte cachedZoomLevel;
+
+	/**
+	 * Constructs a new OverlayItem.
+	 * 
+	 * @param point
+	 *            the geographical position of the item.
+	 */
+	public OverlayMarkerItem(GeoPoint point, String title, Drawable balloon) {
+		this.point = point;
+		this.title = title;
+		this.marker = balloon;
+		this.description = null;
+		this.cachedZoomLevel = Byte.MIN_VALUE;
+		this.content = null;
+	}
+
+	public OverlayMarkerItem(GeoPoint point, String title) {
+		this.point = point;
+		this.title = title;
+		this.description = null;
+		this.cachedZoomLevel = Byte.MIN_VALUE;
+		this.content = null;
+	}
+
+	public OverlayMarkerItem(GeoPoint point, String title, String description,
+			String content) {
+		this.point = point;
+		this.title = title;
+		this.description = description;
+		this.content = content;
+	}
+
+	protected static Drawable boundCenter(Drawable balloon) {
+		balloon.setBounds(balloon.getIntrinsicWidth() / -2,
+				balloon.getIntrinsicHeight() / -2,
+				balloon.getIntrinsicWidth() / 2,
+				balloon.getIntrinsicHeight() / 2);
+		return balloon;
+	}
+
+	/**
+	 * Sets the bounds of the given drawable so that (0,0) is the center of the
+	 * bounding box.
+	 * 
+	 * @param balloon
+	 *            the drawable whose bounds should be set.
+	 * @return the given drawable.
+	 */
+	protected static Drawable boundCenterBottom(Drawable balloon) {
+		balloon.setBounds(balloon.getIntrinsicWidth() / -2,
+				-balloon.getIntrinsicHeight(), balloon.getIntrinsicWidth() / 2,
+				0);
+		return balloon;
+	}
+
+	/**
+	 * Returns the marker used to indicate the item (may be null).
+	 * 
+	 * @return the marker used to indicate the item.
+	 */
+	public Drawable getMarker() {
+		return this.marker;
+	}
+
+	/**
+	 * Returns the position of the item.
+	 * 
+	 * @return the position of the item.
+	 */
+	public GeoPoint getPoint() {
+		return this.point;
+	}
+
+	/**
+	 * Returns the title of the item.
+	 * 
+	 * @return the title of the item.
+	 */
+	public String getTitle() {
+		return this.title;
+	}
+
+	/**
+	 * Return the description of the item
+	 */
+	public String getDescription() {
+		return this.description;
+	}
+
+	public String getContent() {
+		return this.content;
+	}
+
+	/**
+	 * Sets the marker that is drawn on the map for this item. If the item
+	 * marker is null, the default marker will be drawn instead.
+	 * 
+	 * @param marker
+	 *            the marker that is drawn on the map for this item.
+	 */
+	public void setMarker(Drawable marker) {
+		this.marker = boundCenterBottom(marker);
+	}
+
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/OverlayTextAudioItem.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/OverlayTextAudioItem.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/OverlayTextAudioItem.java	(revision 26526)
@@ -0,0 +1,89 @@
+package org.mapsforge.android.maps;
+
+/**
+ * An OverlayTextAudioItem holds all parameters of a single element (capable of
+ * displaying text and/or audio in {@link ItemizedOverlay}. If the item has not
+ * raw audio file, then it will use Text-To-Speech (TTS) to synthesize the audio
+ */
+public class OverlayTextAudioItem extends OverlayItem {
+	protected final String ttsSnippet;
+	protected final String audioFile;
+	private String chapter;
+	private String bookID;
+
+	/**
+	 * Constructs a new OverlayTextAduioItem.
+	 * 
+	 * @param point
+	 *            the geographical position of the item.
+	 * @param title
+	 *            the title of the item.
+	 * @param snippet
+	 *            the short description of the item.
+	 * @param tts_snippet
+	 *            optinal phonetically based version of the short description;
+	 *            can be null in which case the text in snippet is used.
+	 * @param audio
+	 *            the audio file to use
+	 * @param chapter
+	 *            the chapter of the item
+	 */
+	public OverlayTextAudioItem(GeoPoint point, String title, String snippet,
+			String ttsSnippet, String Chapter, String audio, String bookId) {
+		super(point, title, snippet);
+		this.ttsSnippet = (ttsSnippet != null) ? ttsSnippet : snippet;
+		this.chapter = Chapter;
+		this.audioFile = audio;
+		this.bookID = bookId;
+	}
+
+	public OverlayTextAudioItem(GeoPoint point, String title, String snippet,
+			String ttsSnippet, String Chapter, String bookID) {
+		super(point, title, snippet);
+		this.ttsSnippet = (ttsSnippet != null) ? ttsSnippet : snippet;
+		this.chapter = Chapter;
+		this.audioFile = null;
+		this.bookID = bookID;
+	}
+
+	public OverlayTextAudioItem(GeoPoint point, String title, String snippet,
+			String ttsSnippet, String Chapter) {
+		super(point, title, snippet);
+		this.ttsSnippet = (ttsSnippet != null) ? ttsSnippet : snippet;
+		this.chapter = Chapter;
+		this.audioFile = null;
+
+	}
+
+	/**
+	 * Constructs a new OverlayTextAudioItem.
+	 * 
+	 * @param point
+	 *            the geographical position of the item.
+	 * @param title
+	 *            the title of the item.
+	 * @param chapter
+	 *            the chater of the item
+	 * @param snippet
+	 *            the short description of the item.
+	 */
+	public OverlayTextAudioItem(GeoPoint point, String title, String snippet,
+			String ttsSnippet) {
+		super(point, title, snippet);
+		this.ttsSnippet = (ttsSnippet != null) ? ttsSnippet : snippet;
+		this.audioFile = null;
+
+	}
+
+	public String getChapter() {
+		return chapter;
+	}
+
+	public String getNodeID() {
+		return bookID;
+	}
+
+	public String getTTSSnippet() {
+		return ttsSnippet;
+	}
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/RouteOverlayResetable.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/RouteOverlayResetable.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/mapsforge/android/maps/RouteOverlayResetable.java	(revision 26526)
@@ -0,0 +1,147 @@
+package org.mapsforge.android.maps;
+
+import java.util.ArrayList;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Point;
+
+/**
+ * RouteOverlayResetable is a special Overlay to display a sequence of way
+ * nodes. To draw an arbitrary polygon, add a way node sequence where the first
+ * and the last way node are equal.
+ * <p>
+ * All rendering parameters like color, stroke width, pattern and transparency
+ * can be configured via the two {@link android.graphics.Paint Paint} objects in
+ * the {@link #RouteOverlay(Paint,Paint)} constructor.
+ */
+
+public class RouteOverlayResetable extends Overlay {
+
+	private static final String THREAD_NAME = "RouteOverlayResetable";
+
+	private Point[] cachedWayPositions;
+	private byte cachedZoomLevel;
+	private Paint fillPaint;
+	private Paint outlinePaint;
+	private final Path path;
+	private GeoPoint[] wayNodes;
+	private ArrayList<String> nodeID;
+
+	/**
+	 * Constructs a new RouteOverlay.
+	 * 
+	 * @param fillPaint
+	 *            the paint object which will be used to fill the overlay.
+	 * @param outlinePaint
+	 *            the paint object which will be used to draw the outline of the
+	 *            overlay.
+	 */
+	public RouteOverlayResetable(Paint fillPaint, Paint outlinePaint) {
+		this.path = new Path();
+		this.cachedWayPositions = new Point[0];
+		this.nodeID = new ArrayList<String>();
+		setPaint(fillPaint, outlinePaint);
+	}
+
+	public void reset() {
+		this.path.reset();
+		this.cachedWayPositions = new Point[0];
+		this.wayNodes = new GeoPoint[0];
+		super.requestRedraw();
+	}
+
+	/**
+	 * Sets the paint objects which will be used to draw the overlay.
+	 * 
+	 * @param fillPaint
+	 *            the paint object which will be used to fill the overlay.
+	 * @param outlinePaint
+	 *            the paint object which will be used to draw the outline of the
+	 *            overlay.
+	 */
+	public synchronized void setPaint(Paint fillPaint, Paint outlinePaint) {
+		this.fillPaint = fillPaint;
+		this.outlinePaint = outlinePaint;
+	}
+
+	/**
+	 * Sets the way nodes of the route.
+	 * 
+	 * @param wayNodes
+	 *            the geographical coordinates of the way nodes.
+	 */
+	public synchronized void setRouteData(GeoPoint[] wayNodes) {
+		this.wayNodes = wayNodes;
+		if (this.wayNodes != null
+				&& this.wayNodes.length != this.cachedWayPositions.length) {
+			this.cachedWayPositions = new Point[this.wayNodes.length];
+		}
+		this.cachedZoomLevel = Byte.MIN_VALUE;
+		super.requestRedraw();
+	}
+
+	/**
+	 * Sets the way nodes of the route. Sets the nodeId of each way
+	 * nodes--03-22-2012
+	 * 
+	 * @param wayNodes
+	 *            the geographical coordinates of the way nodes.
+	 */
+	public synchronized void setRouteData(GeoPoint[] wayNodes,
+			ArrayList<String> nodeId) {
+		this.wayNodes = wayNodes;
+		if (this.wayNodes != null
+				&& this.wayNodes.length != this.cachedWayPositions.length) {
+			this.cachedWayPositions = new Point[this.wayNodes.length];
+		}
+		this.nodeID = nodeId;
+		this.cachedZoomLevel = Byte.MIN_VALUE;
+		super.requestRedraw();
+	}
+
+	@Override
+	protected synchronized void drawOverlayBitmap(Canvas canvas,
+			Point drawPosition, Projection projection, byte drawZoomLevel) {
+		if (this.wayNodes == null || this.wayNodes.length < 1) {
+			// no way nodes to draw
+			return;
+		} else if (this.fillPaint == null && this.outlinePaint == null) {
+			// no paint to draw
+			return;
+		}
+
+		// make sure that the cached way node positions are valid
+		if (drawZoomLevel != this.cachedZoomLevel) {
+			for (int i = 0; i < this.cachedWayPositions.length; ++i) {
+				this.cachedWayPositions[i] = projection.toPoint(
+						this.wayNodes[i], this.cachedWayPositions[i],
+						drawZoomLevel);
+			}
+			this.cachedZoomLevel = drawZoomLevel;
+		}
+
+		// assemble the path
+		this.path.reset();
+		this.path.moveTo(this.cachedWayPositions[0].x - drawPosition.x,
+				this.cachedWayPositions[0].y - drawPosition.y);
+		for (int i = 1; i < this.cachedWayPositions.length; ++i) {
+			this.path.lineTo(this.cachedWayPositions[i].x - drawPosition.x,
+					this.cachedWayPositions[i].y - drawPosition.y);
+		}
+
+		// draw the path on the canvas
+		if (this.fillPaint != null) {
+			canvas.drawPath(this.path, this.fillPaint);
+		}
+		if (this.outlinePaint != null) {
+			canvas.drawPath(this.path, this.outlinePaint);
+		}
+	}
+
+	@Override
+	protected String getThreadName() {
+		return THREAD_NAME;
+	}
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/AudioPlayerView.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/AudioPlayerView.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/AudioPlayerView.java	(revision 26526)
@@ -0,0 +1,614 @@
+package org.tipple.mapDisplay;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import android.content.Context;
+import android.media.MediaPlayer;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+public class AudioPlayerView extends LinearLayout {
+	public AudioPlayerView(Context context) {
+		super(context);
+		// TODO Auto-generated constructor stub
+	}
+
+	TextView text_view_;
+
+	protected Button buttonPlayPause_;
+	protected Button buttonNext_;
+	protected Button buttonShowHideText_;
+
+	protected String stopLabel_;
+
+	protected boolean hasCompletionHandler_;
+
+	protected tippleActivity.TextAudioModeEnum current_text_audio_mode_;
+
+	protected List<MediaPlayer> audioPlayerQueue_;
+	protected List<String> idPlayerQueue_;
+	protected List<String> textPlayerQueue_;
+	protected List<Boolean> visitedPlayerQueue_;
+	protected int absolute_head_pos_;
+	protected int absolute_tail_pos_;
+
+	AudioPlayerView(Context context, TextView text_view) {
+		super(context);
+
+		text_view_ = text_view;
+
+		audioPlayerQueue_ = new LinkedList<MediaPlayer>();
+		idPlayerQueue_ = new LinkedList<String>();
+		textPlayerQueue_ = new LinkedList<String>();
+		visitedPlayerQueue_ = new LinkedList<Boolean>();
+
+		absolute_head_pos_ = 0;
+		absolute_tail_pos_ = -1;
+
+		// media buttons - play/pause, and next song/audio as horizontal layout,
+		// 50% each
+
+		stopLabel_ = "Stop";
+
+		LayoutParams layout_params = new LinearLayout.LayoutParams(
+				ViewGroup.LayoutParams.WRAP_CONTENT,
+				ViewGroup.LayoutParams.MATCH_PARENT, 1);
+
+		buttonPlayPause_ = new Button(context);
+		buttonPlayPause_.setLayoutParams(layout_params);
+		buttonPlayPause_.setText("Play");
+		buttonPlayPause_.setEnabled(false);
+
+		buttonNext_ = new Button(context);
+		buttonNext_.setLayoutParams(layout_params);
+		buttonNext_.setText(stopLabel_);
+		buttonNext_.setEnabled(false);
+
+		hasCompletionHandler_ = false;
+
+		buttonPlayPause_.setOnClickListener(new View.OnClickListener() {
+			public void onClick(View v) {
+
+				if (isPlaying()) {
+					// Change to pause
+
+					// tippleActivity.log.optMessage("Manual Pause Audio",
+					// textPlayerQueue_.get(0));
+
+					pauseAudio();
+				} else {
+					// Must be paused => resume playing
+					// tippleActivity.log.optMessage("Manual Play/Resume Audio",
+					// textPlayerQueue_.get(0));
+
+					playResumeAudio();
+				}
+			}
+		});
+
+		buttonNext_.setOnClickListener(new View.OnClickListener() {
+			@Override
+			public void onClick(View v) {
+				// tippleActivity.log.optMessage("Manual Next Audio Location");
+				nextAudioLocation();
+			}
+		});
+
+		// Optional show text button
+
+		buttonShowHideText_ = new Button(context);
+		buttonShowHideText_.setLayoutParams(layout_params);
+		buttonShowHideText_.setText("Show Text");
+		buttonShowHideText_.setEnabled(false);
+
+		buttonShowHideText_.setOnClickListener(new View.OnClickListener() {
+			public void onClick(View v) {
+				// tippleActivity.log.optMessage("Manual Show/Hide Text");
+
+				if (text_view_.getVisibility() == View.INVISIBLE) {
+					// tippleActivity.log.optMessage("Manual Show Text");
+					text_view_.setVisibility(View.VISIBLE);
+					buttonShowHideText_.setText("Hide Text");
+				} else {
+					// tippleActivity.log.optMessage("Manual Hide Text");
+					text_view_.setVisibility(View.INVISIBLE);
+					buttonShowHideText_.setText("Show Text");
+				}
+			}
+		});
+
+		// Horozontal layout is:
+		// Play | OptText | Next
+
+		addView(buttonPlayPause_);
+
+		/*
+		 * current_text_audio_mode_ = tippleActivity.textAudioMode; if
+		 * (current_text_audio_mode_ ==
+		 * tippleActivity.TextAudioModeEnum.AUDIO_PLUS_TEXT) {
+		 * addView(buttonShowHideText_); }
+		 */
+		addView(buttonShowHideText_);
+
+		addView(buttonNext_);
+	}
+
+	// delete the public then call this method?
+	void resetAudioView() {
+		audioPlayerQueue_.clear();
+		idPlayerQueue_.clear();
+		textPlayerQueue_.clear();
+		visitedPlayerQueue_.clear();
+		audioPlayerQueue_ = new LinkedList<MediaPlayer>();
+		idPlayerQueue_ = new LinkedList<String>();
+		textPlayerQueue_ = new LinkedList<String>();
+		visitedPlayerQueue_ = new LinkedList<Boolean>();
+
+		absolute_head_pos_ = 0;
+		absolute_tail_pos_ = -1;
+
+	}
+
+	protected boolean audioViewIsActive() {
+		return ((current_text_audio_mode_ == tippleActivity.TextAudioModeEnum.AUDIO_ONLY)
+				|| (current_text_audio_mode_ == tippleActivity.TextAudioModeEnum.AUDIO_PLUS_TEXT) || (current_text_audio_mode_ == tippleActivity.TextAudioModeEnum.TEXT_PLUS_AUDIO));
+
+	}
+
+	protected boolean textViewIsActive() {
+		return ((current_text_audio_mode_ == tippleActivity.TextAudioModeEnum.TEXT_ONLY)
+				|| (current_text_audio_mode_ == tippleActivity.TextAudioModeEnum.TEXT_PLUS_AUDIO) || (current_text_audio_mode_ == tippleActivity.TextAudioModeEnum.AUDIO_PLUS_TEXT));
+
+	}
+
+	public void refreshView() {
+		if (current_text_audio_mode_ != tippleActivity.textAudioMode) {
+			// There has been a mode change
+
+			if (tippleActivity.textAudioMode == tippleActivity.TextAudioModeEnum.AUDIO_PLUS_TEXT) {
+				// ensure both play/pause and show/hide removed, then add in
+				// order needed
+
+				if (this.indexOfChild(buttonPlayPause_) >= 0) {
+					this.removeView(buttonPlayPause_);
+				}
+				if (this.indexOfChild(buttonShowHideText_) >= 0) {
+					this.removeView(buttonShowHideText_);
+				}
+				this.addView(buttonPlayPause_, 0);
+				this.addView(buttonShowHideText_, 1);
+
+				stopLabel_ = "Stop";
+			}
+
+			else if (tippleActivity.textAudioMode == tippleActivity.TextAudioModeEnum.AUDIO_ONLY) {
+				// ensure show/hide is gone, and only add play/pause if needed
+				if (this.indexOfChild(buttonShowHideText_) >= 0) {
+					// Don't want to see a show/hide text button
+					this.removeView(buttonShowHideText_);
+				}
+				if (this.indexOfChild(buttonPlayPause_) < 0) {
+					this.addView(buttonPlayPause_);
+				}
+				stopLabel_ = "Stop";
+			}
+
+			else if (tippleActivity.textAudioMode == tippleActivity.TextAudioModeEnum.TEXT_PLUS_AUDIO) {
+				// ensure both play/pause and show/hide removed, then add in
+				// order needed
+				if (this.indexOfChild(buttonPlayPause_) >= 0) {
+					this.removeView(buttonPlayPause_);
+				}
+				if (this.indexOfChild(buttonShowHideText_) >= 0) {
+					this.removeView(buttonShowHideText_);
+				}
+
+				this.addView(buttonShowHideText_, 0);
+				this.addView(buttonPlayPause_, 1);
+
+				stopLabel_ = "Stop";
+			}
+
+			else if (tippleActivity.textAudioMode == tippleActivity.TextAudioModeEnum.TEXT_ONLY) {
+				// ensure play/pause is gone, and only add show/hide if needed
+
+				if (this.indexOfChild(buttonPlayPause_) >= 0) {
+					// Don't want to see a play button
+					this.removeView(buttonPlayPause_);
+				}
+
+				if (this.indexOfChild(buttonShowHideText_) < 0) {
+					this.addView(buttonShowHideText_, 0);
+				}
+				stopLabel_ = "End";
+			}
+
+			current_text_audio_mode_ = tippleActivity.textAudioMode;
+			System.out.println("refreshView AudioPlayerView");
+		}
+
+	}
+
+	synchronized public boolean audioQueueEmpty() {
+		return (audioPlayerQueue_.size() == 0);
+	}
+
+	synchronized public boolean outstandingAudioPending() {
+		return (audioPlayerQueue_.size() > 1);
+	}
+
+	synchronized public int audioQueueLength() {
+		return audioPlayerQueue_.size();
+	}
+
+	synchronized public boolean addAudio(String new_id) {
+		// Assume audio should be added, unless an existing match is found
+		boolean add_audio = true;
+
+		int rev_pos = audioPlayerQueue_.size() - 1;
+		for (int i = 0; i < 3; i++) {
+			if (rev_pos < 0) {
+				break;
+			}
+
+			String id = idPlayerQueue_.get(rev_pos);
+
+			if (new_id.equals(id)) {
+				add_audio = false;
+			}
+
+			rev_pos--;
+		}
+
+		return add_audio;
+	}
+
+	synchronized public void queueAudio(String audio_filename, String id,
+			String text, boolean previously_visited) {
+		MediaPlayer mp = new MediaPlayer();
+		try {
+
+			mp.setDataSource(audio_filename);
+			mp.prepare();
+			audioPlayerQueue_.add(mp);
+			idPlayerQueue_.add(id);
+			textPlayerQueue_.add(text);
+			visitedPlayerQueue_.add(previously_visited);
+
+			absolute_tail_pos_++;
+
+			int audio_queue_len = audioPlayerQueue_.size();
+			int mod_head_pos = absolute_head_pos_ % 3;
+
+			if (audio_queue_len == 1) {
+				// Nothing to do, not enough data to allow the user to play
+				// anything
+				return;
+			} else if (audio_queue_len == 2) {
+
+				// mod_head_pos==0 => title followed by text => ready to play
+				// mod_head_pos==1 => text followed by beep => "stop"
+				// mod_head_pos==2 => beep followed title => "skip to next"
+
+				if (mod_head_pos == 0) {
+					// just queued up a title and text (at the head of the
+					// queue)
+					// => make play active if not already so
+					if (!buttonPlayPause_.isEnabled()) {
+						// buttonPlayPause_.setText("Play");
+						buttonPlayPause_.setEnabled(true);
+					}
+					if (!buttonShowHideText_.isEnabled()) {
+						buttonShowHideText_.setEnabled(true);
+
+					}
+					buttonNext_.setText(stopLabel_);
+					buttonNext_.setEnabled(true);
+				} else if (mod_head_pos == 1) {
+
+					buttonNext_.setText(stopLabel_);
+					buttonNext_.setEnabled(true);
+				} else {
+					// mod_head_pos==2
+					buttonNext_.setText("Skip to Next (1)");
+					buttonNext_.setEnabled(true);
+				}
+			} else {
+				// length >= 3
+
+				// mod_head_pos==0 => title at head, spans loc if len >3
+				// mod_head_pos==1 => text at head, guaranteed to span loc =>
+				// "skip to next"
+				// mod_head_pos==2 => beep at head, guaranteed to span loc =>
+				// "skip to next"
+
+				if ((mod_head_pos == 0) && (audio_queue_len == 3)) {
+					// stop
+					buttonNext_.setText(stopLabel_);
+					buttonNext_.setEnabled(true);
+				} else {
+					// for everything else, the queue spans to another location
+
+					int relative_adjustment_pos = mod_head_pos - 1;
+					int num_remaining_locations = (audio_queue_len + relative_adjustment_pos) / 3;
+
+					buttonNext_.setText("Skip to Next ("
+							+ num_remaining_locations + ")");
+					buttonNext_.setEnabled(true);
+				}
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	synchronized public void queueAudio(String audio_filename, String id,
+			String text) {
+		queueAudio(audio_filename, id, text, false);
+	}
+
+	synchronized public void removeAudioTrack() {
+		if (audioPlayerQueue_.size() > 0) {
+
+			// tippleActivity.log.optMessage("Remove Audio Track",
+			// "Queue size was: " + audioPlayerQueue_.size());
+
+			MediaPlayer mp = audioPlayerQueue_.remove(0);
+			idPlayerQueue_.remove(0);
+			textPlayerQueue_.remove(0);
+			visitedPlayerQueue_.remove(0);
+
+			absolute_head_pos_++;
+			mp.stop();
+			mp.release();
+
+			hasCompletionHandler_ = false;
+		} else {
+			System.err.println("Error: No audio in queue to remove");
+		}
+	}
+
+	synchronized public void removeAudioLocation() {
+		int audio_queue_len = audioPlayerQueue_.size();
+
+		if (audio_queue_len > 0) {
+
+			// tippleActivity.log.optMessage("Remove Audio Location",
+			// "Queue size was: " + audioPlayerQueue_.size());
+
+			int mod_head_pos = absolute_head_pos_ % 3;
+			int need_to_skip = 3 - mod_head_pos;
+
+			// remove up to the next absolute multiple of 3
+			for (int i = 0; i < need_to_skip; i++) {
+				MediaPlayer mp = audioPlayerQueue_.remove(0);
+				idPlayerQueue_.remove(0);
+				textPlayerQueue_.remove(0);
+				visitedPlayerQueue_.remove(0);
+				absolute_head_pos_++;
+
+				mp.stop();
+				mp.release();
+				if (audioPlayerQueue_.size() == 0) {
+					// happens if there is no beep on the last location
+					break;
+				}
+			}
+
+			hasCompletionHandler_ = false;
+		} else {
+			System.err.println("Error: No audio in queue to remove");
+		}
+	}
+
+	synchronized public void onAudioCompletion(MediaPlayer mp) {
+		mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+
+			@Override
+			public void onCompletion(MediaPlayer mp) {
+				nextAudioTrack();
+			}
+		});
+	}
+
+	synchronized public void onVisitedAudioCompletion(MediaPlayer mp) {
+		mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+
+			@Override
+			public void onCompletion(MediaPlayer mp) {
+				playResumeAudioInternal();
+			}
+		});
+	}
+
+	public boolean updateTextViewIfHeadIsNewLocation() {
+		boolean updated = false;
+
+		if ((absolute_head_pos_ % 3) == 0) {
+			// start of a new location
+			String text_desc = textPlayerQueue_.get(0);
+			if (visitedPlayerQueue_.get(0)) {// return true or false
+				text_desc += "\n(Previously Visited)";
+			}
+			text_desc += "\n------";
+
+			if (textPlayerQueue_.size() > 1) {
+				text_desc += "\n" + textPlayerQueue_.get(1);
+			}
+
+			text_view_.setText(text_desc);
+			updated = true;
+		}
+
+		return updated;
+	}
+
+	synchronized public void playResumeAudio() {
+		if (audioPlayerQueue_.size() > 0) {
+
+			if ((audioViewIsActive()) && (visitedPlayerQueue_.get(0))) {
+				// Play (synchronously) the "previously visited" message before
+				// moving on to
+				// describing the location itself
+				MediaPlayer mp = new MediaPlayer();
+
+				try {
+					// mp.setDataSource(tippleLocationManager.prevVisitedFilename);
+					mp.setDataSource(TippleLocationManagerVersion2.prevVisitedFilename);
+
+					mp.prepare();
+					onVisitedAudioCompletion(mp);
+					mp.start();
+				} catch (Exception e) {
+					e.printStackTrace();
+				}
+			} else {
+				// go straight on and play the queued audio
+				playResumeAudioInternal();
+			}
+		} else {
+			System.err
+					.println("Error: No audio in queue to start playing --call palyResumeAudio function");
+
+		}
+
+	}
+
+	synchronized public void playResumeAudioInternal() {
+		if (audioPlayerQueue_.size() > 0) {
+			// tippleActivity.log.optMessage("Play/Resume Audio",
+			// "Queue size was: " + audioPlayerQueue_.size());
+
+			MediaPlayer mp = audioPlayerQueue_.get(0);
+
+			if (!hasCompletionHandler_) {
+
+				updateTextViewIfHeadIsNewLocation();
+
+				onAudioCompletion(mp);
+				hasCompletionHandler_ = true;
+			}
+
+			if (audioViewIsActive() || ((absolute_head_pos_ % 3) == 2)) {
+				// allow it to play a "ding" even in text only mode
+				mp.start();
+			}
+			buttonPlayPause_.setText("Pause"); // next operation
+		} else {
+			System.err
+					.println("Error: No audio in queue to start playing --call playResumeAudioInternal function");
+		}
+
+	}
+
+	synchronized public void pauseAudio() {
+		if (audioPlayerQueue_.size() > 0) {
+			MediaPlayer mp = audioPlayerQueue_.get(0);
+			mp.pause();
+			buttonPlayPause_.setText("Play/Resume"); // next operation
+		} else {
+			System.err.println("Error: No audio in queue to pause");
+		}
+	}
+
+	synchronized public void nextAudioLocation() {
+		removeAudioLocation(); // stops it if currently playing
+
+		int remaining_audio_len = audioQueueLength();
+		if (remaining_audio_len > 0) {
+			playResumeAudio();
+
+			int mod_head_pos = absolute_head_pos_ % 3;
+			/*
+			 * int relative_adjustment_pos = 1 - mod_head_pos; int
+			 * num_remaining_locations =
+			 * (remaining_audio_len+relative_adjustment_pos)/3;
+			 * 
+			 * if (num_remaining_locations>=1) {
+			 * 
+			 * buttonNext_.setText("Skip to Next (" + num_remaining_locations +
+			 * ")"); buttonNext_.setEnabled(true); }
+			 */
+
+			int num_remaining_locations = (remaining_audio_len + mod_head_pos) / 3;
+
+			if (num_remaining_locations > 1) {
+
+				buttonNext_.setText("Skip to Next ("
+						+ (num_remaining_locations - 1) + ")");
+				buttonNext_.setEnabled(true);
+			}
+
+			else {
+				buttonNext_.setText(stopLabel_);
+				buttonNext_.setEnabled(true);
+				buttonPlayPause_.setText("Play");
+				buttonPlayPause_.setEnabled(true);
+				buttonShowHideText_.setText("Show Text");
+				buttonShowHideText_.setEnabled(true);
+			}
+		} else {
+			buttonNext_.setText(stopLabel_);
+			buttonNext_.setEnabled(false);
+			buttonPlayPause_.setText("Play");
+			buttonPlayPause_.setEnabled(false);
+
+			if (text_view_.getVisibility() == View.VISIBLE) {
+				// tippleActivity.log.optMessage("Audio Hide Text");
+				text_view_.setVisibility(View.INVISIBLE);
+			}
+			buttonShowHideText_.setText("Show Text");
+			buttonShowHideText_.setEnabled(false);
+		}
+	}
+
+	synchronized public void nextAudioTrack() {
+		removeAudioTrack(); // stops it if currently playing
+
+		int remaining_audio_len = audioQueueLength();
+		if (remaining_audio_len > 0) {
+			playResumeAudio();
+
+			int num_remaining_locations = ((remaining_audio_len - 1) / 3);
+
+			if (num_remaining_locations >= 1) {
+
+				buttonNext_.setText("Skip to Next (" + num_remaining_locations
+						+ ")");
+				buttonNext_.setEnabled(true);
+			} else {
+				buttonNext_.setText(stopLabel_);
+				buttonNext_.setEnabled(true);
+				// buttonPlayPause_.setText("Play");
+				buttonPlayPause_.setEnabled(true);
+				buttonShowHideText_.setEnabled(true);
+			}
+		} else {
+			buttonNext_.setText(stopLabel_);
+			buttonNext_.setEnabled(false);
+			buttonPlayPause_.setText("Play");
+			buttonPlayPause_.setEnabled(false);
+
+			if (text_view_.getVisibility() == View.VISIBLE) {
+				tippleActivity.log.optMessage("Audio Hide Text");
+				text_view_.setVisibility(View.INVISIBLE);
+			}
+			buttonShowHideText_.setText("Show Text");
+			buttonShowHideText_.setEnabled(false);
+
+		}
+	}
+
+	synchronized public boolean isPlaying() {
+		boolean is_playing = false;
+		if (audioPlayerQueue_.size() > 0) {
+			is_playing = audioPlayerQueue_.get(0).isPlaying();
+		}
+		return is_playing;
+	}
+
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/EditPreferences.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/EditPreferences.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/EditPreferences.java	(revision 26526)
@@ -0,0 +1,26 @@
+package org.tipple.mapDisplay;
+
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+
+public class EditPreferences extends PreferenceActivity {
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		System.err.println("*** EditPreferences::onCreate()");
+		super.onCreate(savedInstanceState);
+		addPreferencesFromResource(R.xml.preferences);
+	}
+
+	@Override
+	protected void onResume() {
+		System.err.println("*** EditPreferences::onResume()");
+		super.onResume();
+	}
+
+	@Override
+	protected void onStop() {
+		System.err.println("*** EditPreferences::onStop()");
+		super.onResume();
+	}
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/ImageLoader.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/ImageLoader.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/ImageLoader.java	(revision 26526)
@@ -0,0 +1,183 @@
+package org.tipple.mapDisplay;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLConnection;
+
+import android.app.Activity;
+import android.content.ContentValues;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Environment;
+import android.provider.MediaStore;
+import android.util.Log;
+
+public class ImageLoader extends AsyncTask<String, Integer, Bitmap> {
+
+	private final String TAG = null;
+	public String myurl;
+	Context context;
+	String name;
+
+	public ImageLoader(Activity context) {
+		this.context = context;
+	}
+
+	public void download(String url) {
+		myurl = null;
+		myurl = url;
+		String[] imageName = myurl.split("\\/");
+		String finalName = imageName[11].replaceAll("%20", " ");
+		name = "/sdcard/" + finalName;
+		File file = new File(name);
+		if (file.exists()) {
+			System.out.println("File exists");
+			return;
+		} else
+			this.execute(myurl);
+	}
+
+	@Override
+	protected Bitmap doInBackground(String... params) {
+		return downloadAvatar(params[0]);
+
+	}
+
+	public Bitmap downloadAvatar(String url) {
+		Bitmap bm = null;
+		try {
+			URL aURL = new URL(url);
+			URLConnection conn = aURL.openConnection();
+			conn.connect();
+			InputStream is = conn.getInputStream();
+			BufferedInputStream bis = new BufferedInputStream(is);
+			bm = BitmapFactory.decodeStream(bis);
+			bis.close();
+			is.close();
+		}
+
+		catch (Exception e) {
+			Log.w("AvatarDownloader", "Error while ...retrieving bitmap from "
+					+ url);
+		}
+
+		return bm;
+
+	}
+
+	String imageDirectory;
+
+	protected void onPostExecute(Bitmap result) {
+		String rname = "/sdcard/" + myurl.toString().hashCode() + "-t.jpg";
+		try {
+			if (result != null) {
+				hasExternalStoragePublicPicture(name);
+				Bitmap rezised = this.resizeBitmap(result, 300, 300);
+				saveToSDCard(result, name, myurl.toString().hashCode() + ".jpg");
+				result.recycle();
+				rezised.recycle();
+
+			} else {
+				System.out.println("onPostExecute... already exist");
+
+			}
+		} catch (NullPointerException e) {
+			System.out.println("onPostExecute...unsuccessfully download ");
+		}
+
+	}
+
+	private boolean hasExternalStoragePublicPicture(String name) {
+		File file = new File(name);
+		if (file != null) {
+			file.delete();
+		}
+
+		try {
+			file.createNewFile();
+
+		} catch (IOException e) {
+			e.printStackTrace();
+
+		}
+		return file.exists();
+	}
+
+	public void saveToSDCard(Bitmap bitmap, String name, String nam) {
+		boolean mExternalStorageAvailable = false;
+		boolean mExternalStorageWriteable = false;
+		String state = Environment.getExternalStorageState();
+		if (Environment.MEDIA_MOUNTED.equals(state)) {
+			mExternalStorageAvailable = mExternalStorageWriteable = true;
+			Log.v(TAG, "SD Card is available for read and write "
+					+ mExternalStorageAvailable + mExternalStorageWriteable);
+			saveFile(bitmap, name, nam);
+		} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+			mExternalStorageAvailable = true;
+			mExternalStorageWriteable = false;
+			Log.v(TAG, "SD Card is available for read "
+					+ mExternalStorageAvailable);
+		} else {
+			mExternalStorageAvailable = mExternalStorageWriteable = false;
+			Log.v(TAG, "Please insert a SD Card to save your Video "
+					+ mExternalStorageAvailable + mExternalStorageWriteable);
+		}
+	}
+
+	private void saveFile(Bitmap bitmap, String fullname, String nam) {
+
+		ContentValues values = new ContentValues();
+
+		File outputFile = new File(fullname);
+		values.put(MediaStore.MediaColumns.DATA, outputFile.toString());
+		values.put(MediaStore.MediaColumns.TITLE, nam);
+		values.put(MediaStore.MediaColumns.DATE_ADDED,
+				System.currentTimeMillis());
+		values.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg");
+		Uri uri = context.getContentResolver().insert(
+				android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
+
+				values);
+		;
+
+		try {
+			OutputStream outStream = context.getContentResolver()
+					.openOutputStream(uri);
+			bitmap.compress(Bitmap.CompressFormat.JPEG, 95, outStream);
+
+			outStream.flush();
+			outStream.close();
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		bitmap.recycle();
+
+	}
+
+	public Bitmap resizeBitmap(Bitmap result, int i, int j) {
+		// TODO Auto-generated method stub
+		int width = result.getWidth();
+		int height = result.getHeight();
+		int newWidth = 1;
+		int newHeight = j;
+		float scaleWidth = ((float) newWidth) / width;
+		float scaleHeight = ((float) newHeight) / height;
+		Matrix matrix = new Matrix();
+		matrix.postScale(scaleWidth, scaleHeight);
+		// create the new Bitmap
+		Bitmap resizedBitmap = Bitmap.createBitmap(result, 0, 0, width, height,
+				matrix, true);
+		return resizedBitmap;
+	}
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/ImageURL.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/ImageURL.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/ImageURL.java	(revision 26526)
@@ -0,0 +1,19 @@
+package org.tipple.mapDisplay;
+
+public class ImageURL {
+	protected static final String[] URLS = {
+			"http://130.217.244.51:8383/greenstone3/sites/localsite/collect/imgdemo/index/assoc/HASHd37f.dir/10%20Entrance%20to%20Chinese%20Garden.jpg",
+			"http://130.217.244.51:8383/greenstone3/sites/localsite/collect/imgdemo/index/assoc/HASH2489.dir/1%20Beginning%20of%20gardens.jpg",
+			"http://130.217.244.51:8383/greenstone3/sites/localsite/collect/imgdemo/index/assoc/HASH1320.dir/11%20The%20Entrance.jpg",
+			"http://130.217.244.51:8383/greenstone3/sites/localsite/collect/imgdemo/index/assoc/HASH0172.dir/12%20Tree,%20Rock%20and%20Bridge.jpg",
+			"http://130.217.244.51:8383/greenstone3/sites/localsite/collect/imgdemo/index/assoc/HASH01e4.dir/15%20Entrance%20to%20Modernist%20Garden.jpg",
+			"http://130.217.244.51:8383/greenstone3/sites/localsite/collect/imgdemo/index/assoc/HASH011c.dir/16%20American%20House.jpg",
+			"http://130.217.244.51:8383/greenstone3/sites/localsite/collect/imgdemo/index/assoc/HASH01c2.dir/20%20Italian%20Renaissance%20Garden.jpg",
+			"http://130.217.244.51:8383/greenstone3/sites/localsite/collect/imgdemo/index/assoc/HASH012f.dir/21%20Overview%20of%20Italian%20Garden.jpg",
+			"http://130.217.244.51:8383/greenstone3/sites/localsite/collect/imgdemo/index/assoc/HASHf960.dir/22%20Water%20in%20the%20Italian%20Garden.jpg",
+			"http://130.217.244.51:8383/greenstone3/sites/localsite/collect/imgdemo/index/assoc/HASH8a59.dir/5%20Japanense%20Rock%20Garden.jpg",
+			"http://130.217.244.51:8383/greenstone3/sites/localsite/collect/imgdemo/index/assoc/HASH9003.dir/6%20Entrance%20of%20Engligh%20Garden.jpg",
+			"http://130.217.244.51:8383/greenstone3/sites/localsite/collect/imgdemo/index/assoc/HASH3331.dir/8%20Collector%27s%20Garden.jpg",
+			"http://130.217.244.51:8383/greenstone3/sites/localsite/collect/imgdemo/index/assoc/HASH3e13.dir/9%20White%20GardenWater%20in%20the%20Italian%20Garden.jpg" };
+
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/InfoView.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/InfoView.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/InfoView.java	(revision 26526)
@@ -0,0 +1,23 @@
+package org.tipple.mapDisplay;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.webkit.WebView;
+
+/**
+ * Simple activity to display the info web page from the assets folder.
+ */
+public class InfoView extends Activity {
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		WebView webView = new WebView(this);
+		webView.loadUrl("file:///android_asset/info.xml");
+		setContentView(webView);
+	}
+
+	@Override
+	protected void onResume() {
+		super.onResume();
+	}
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/TakePicture.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/TakePicture.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/TakePicture.java	(revision 26526)
@@ -0,0 +1,100 @@
+package org.tipple.mapDisplay;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.ObjectOutputStream;
+
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.provider.MediaStore;
+import android.util.Log;
+
+public class TakePicture extends Activity {
+	protected Uri imageUri;
+	String filename = "imageExample.jpg";
+	File photo;
+
+	@Override
+	public void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+
+		// retrieve value from picture taking
+		Bundle extras = getIntent().getExtras();
+		if (extras != null) {
+			filename = extras.getString("filename");
+		}
+		startCameraActivity(filename);
+
+	}
+
+	protected void startCameraActivity(String filename) {
+
+		Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
+		photo = new File(Environment.getExternalStorageDirectory(), filename);
+		intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
+		imageUri = Uri.fromFile(photo);
+		startActivityForResult(intent, 0);
+
+	}
+
+	public void onActivityResult(int requestCode, int resultCode, Intent data) {
+
+		super.onActivityResult(requestCode, resultCode, data);
+		Log.i("TakePicture", "resultCode: " + resultCode);
+		switch (resultCode) {
+		case 0:
+			Log.i("TakePicture", "User cancelled");
+			break;
+
+		case -1:
+			onPhotoTaken();
+			break;
+		}
+		this.finish(); // when user click on V then back to previous activity
+
+	}
+
+	private void onPhotoTaken() {
+		Uri selectedImage = imageUri;
+		getContentResolver().notifyChange(selectedImage, null);
+		ContentResolver cr = getContentResolver();
+
+		try {
+			Bitmap bitmap = android.provider.MediaStore.Images.Media.getBitmap(
+					cr, selectedImage);
+			Log.i("TakePicture", "save file to the location" + filename);
+			savePicture(tippleActivity.imageDirectory + filename, bitmap,
+					getApplicationContext());
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	private void savePicture(String filename, Bitmap b, Context ctx) {
+		if (!photo.exists()) {// look for sdcard directory
+			try {
+				ObjectOutputStream oos;
+				FileOutputStream out = new FileOutputStream(filename);
+				out = ctx.openFileOutput(filename, Context.MODE_PRIVATE);
+				oos = new ObjectOutputStream(out);
+				b.compress(Bitmap.CompressFormat.PNG, 100, oos);
+				oos.close();
+				oos.notifyAll();
+				out.notifyAll();
+				out.close();
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		} else {
+			Log.i("TakePicture", "file exist" + filename);
+			return;
+		}
+	}
+
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/TippleLocationManagerVersion2.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/TippleLocationManagerVersion2.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/TippleLocationManagerVersion2.java	(revision 26526)
@@ -0,0 +1,706 @@
+package org.tipple.mapDisplay;
+
+import java.io.File;
+import java.net.URL;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.mapsforge.android.maps.ArrayItemizedMarkerOverlay;
+import org.mapsforge.android.maps.ArrayItemizedTextAudioOverlay;
+import org.mapsforge.android.maps.CirclesOverlay;
+import org.mapsforge.android.maps.GeoPoint;
+import org.mapsforge.android.maps.MapView;
+import org.mapsforge.android.maps.Overlay;
+import org.mapsforge.android.maps.OverlayItem;
+import org.mapsforge.android.maps.OverlayMarkerItem;
+import org.mapsforge.android.maps.OverlayTextAudioItem;
+import org.mapsforge.android.maps.RouteOverlayResetable;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+
+import android.app.Activity;
+import android.graphics.Color;
+import android.graphics.DashPathEffect;
+import android.graphics.Paint;
+import android.graphics.drawable.Drawable;
+import android.location.Location;
+import android.location.LocationManager;
+import android.speech.tts.TextToSpeech;
+import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
+import android.util.Log;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+
+public class TippleLocationManagerVersion2 {
+	protected LocationManager locationManager;
+	protected static MapView mapview;
+	protected ArrayList<tippleLocation> locations;
+	protected Button retrieveLocationButton;
+	protected double currentLongitude;
+	protected double currentLatitude;
+	protected double currentNodeId;
+	protected String nodeId;
+	protected Boolean bookSelected = true;
+
+	public static String hamiltonGardenURL = "HASH4e454a5d938158a2a3fcde";
+	public static String stationOfCrossURL = "HASH0158acd736565602cd1f1b1b";
+	Activity activity_;
+	AudioPlayerView audio_player_view_;
+	TextToSpeech tts_;
+	TextView textview;
+	protected tippleActivity.bookModeEnum current_book_mode_;
+
+	public static CirclesOverlay circlesOverlay = null;
+	public static ArrayItemizedMarkerOverlay itemizedMarkerOverlay;
+	public static ArrayList<OverlayItem> itemizedMarkerOverlayArrayList;
+	public static ArrayList<GeoPoint> circlesOverlayGeoPoints;
+	public static ArrayList<Integer> circlesOverlayRadii;
+
+	public static RouteOverlayResetable routeOverlay = null;
+	public static RouteOverlayResetable routeOverlay2 = null;
+	public static ArrayItemizedTextAudioOverlay routeMarkerOverlay;
+	public static GeoPoint[] routeOverlayArray;
+	public static ArrayList<String> nodeIDArray;
+	public static GeoPoint[] routeOverlayArray2;
+	public static int lengthOfFirstBook = 0;
+	public static int lengthOfSecondBook = 0;
+
+	// paint color for route
+	Paint fillPaint, fillPaint2, outlinePaint, outlinePaint2;
+
+	public static ArrayList<OverlayItem> routeMarkerOverlayArrayList;
+	public static HashMap<Integer, OverlayMarkerItem> highlight_marker_hash_;
+	public static String prevVisitedFilename;
+	Drawable defaultMarker;// declare as global variable
+
+	ArrayList<tippleLocation> preLocations = null;
+	ArrayList<tippleLocation> temLocations = null;
+	Location thislocation;
+
+	TippleLocationManagerVersion2(Activity activity, MapView mapview,
+			TextView textview, LocationManager manager,
+			AudioPlayerView audio_player_view, TextToSpeech tts) {
+		activity_ = activity;
+		audio_player_view_ = audio_player_view;
+		tts_ = tts;
+		this.locationManager = manager;
+		this.mapview = mapview;
+		this.textview = textview;
+
+		Paint circleFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+		circleFillPaint.setStyle(Paint.Style.FILL);
+		circleFillPaint.setColor(Color.BLUE);
+		circleFillPaint.setAlpha(64);
+
+		Paint circleOutlinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+		circleOutlinePaint.setStyle(Paint.Style.STROKE);
+		circleOutlinePaint.setColor(Color.BLUE);
+		circleOutlinePaint.setAlpha(64);
+		circleOutlinePaint.setStrokeWidth(1);
+		circlesOverlay = new CirclesOverlay(circleFillPaint, circleOutlinePaint);
+		circlesOverlayGeoPoints = new ArrayList<GeoPoint>();
+		circlesOverlayRadii = new ArrayList<Integer>();
+		defaultMarker = activity_.getResources().getDrawable(R.drawable.marker);
+		itemizedMarkerOverlay = new ArrayItemizedMarkerOverlay(defaultMarker,
+				activity_);
+		itemizedMarkerOverlayArrayList = new ArrayList<OverlayItem>();
+		highlight_marker_hash_ = new HashMap<Integer, OverlayMarkerItem>();
+		fillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+		// deal with routeoverlay
+		fillPaint.setStyle(Paint.Style.STROKE);
+		fillPaint.setColor(Color.BLUE);
+		fillPaint.setAlpha(160);
+		fillPaint.setStrokeWidth(7);
+		fillPaint.setStrokeCap(Paint.Cap.BUTT);
+		fillPaint.setStrokeJoin(Paint.Join.ROUND);
+		fillPaint.setPathEffect(new DashPathEffect(new float[] { 20, 20 }, 0));
+
+		outlinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+		outlinePaint.setStyle(Paint.Style.STROKE);
+		outlinePaint.setColor(Color.BLUE);
+		outlinePaint.setAlpha(96);
+		outlinePaint.setStrokeWidth(7);
+		outlinePaint.setStrokeCap(Paint.Cap.BUTT);
+		outlinePaint.setStrokeJoin(Paint.Join.ROUND);
+		fillPaint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
+		// deal with routeoverlay
+		fillPaint2.setStyle(Paint.Style.STROKE);
+		fillPaint2.setColor(Color.RED);
+		fillPaint2.setAlpha(160);
+		fillPaint2.setStrokeWidth(7);
+		fillPaint2.setStrokeCap(Paint.Cap.BUTT);
+		fillPaint2.setStrokeJoin(Paint.Join.ROUND);
+		fillPaint2.setPathEffect(new DashPathEffect(new float[] { 20, 20 }, 0));
+
+		outlinePaint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
+		outlinePaint2.setStyle(Paint.Style.STROKE);
+		outlinePaint2.setColor(Color.BLUE);
+		outlinePaint2.setAlpha(96);
+		outlinePaint2.setStrokeWidth(7);
+		outlinePaint2.setStrokeCap(Paint.Cap.BUTT);
+		outlinePaint2.setStrokeJoin(Paint.Join.ROUND);
+
+		routeOverlay = new RouteOverlayResetable(fillPaint, outlinePaint);
+		routeOverlay2 = new RouteOverlayResetable(fillPaint2, outlinePaint2);
+
+	}
+
+	protected String getCurrentLocation() {
+		String myCurrentLongitude = null;
+		thislocation = locationListener.lastKnownLocation;
+		if (thislocation != null) {
+			currentLongitude = thislocation.getLongitude();
+			currentLatitude = thislocation.getLatitude();
+			String[] result = (String.valueOf(currentLatitude)).split("\\.");
+			myCurrentLongitude = result[0].substring(1, 3);// image start
+			DecimalFormat trunPlaces = new DecimalFormat("0.0000");
+			String text_mess = "(Long,Lat): ("
+					+ trunPlaces.format(currentLongitude) + ","
+					+ trunPlaces.format(currentLatitude) + ")";
+			textview.setText(text_mess);
+
+		} else {
+			Toast.makeText(activity_, "failed to get GPS", Toast.LENGTH_LONG)
+					.show();
+
+		}
+		return myCurrentLongitude;
+	}
+
+	// protected void createLogRouteLocationsOverlay(MapView mapView,
+	// ArrayList<tippleLocation> locations) {
+	// Paint fillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+	// fillPaint.setStyle(Paint.Style.STROKE);
+	// fillPaint.setColor(Color.BLUE);
+	// fillPaint.setAlpha(160);
+	// fillPaint.setStrokeWidth(7);
+	// fillPaint.setStrokeCap(Paint.Cap.BUTT);
+	// fillPaint.setStrokeJoin(Paint.Join.ROUND);
+	// fillPaint.setPathEffect(new DashPathEffect(new float[] { 20, 20 }, 0));
+	//
+	// Paint outlinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+	// outlinePaint.setStyle(Paint.Style.STROKE);
+	// outlinePaint.setColor(Color.BLUE);
+	// outlinePaint.setAlpha(96);
+	// outlinePaint.setStrokeWidth(7);
+	// outlinePaint.setStrokeCap(Paint.Cap.BUTT);
+	// outlinePaint.setStrokeJoin(Paint.Join.ROUND);
+	//
+	// Drawable defaultMarker = activity_.getResources().getDrawable(
+	// R.drawable.routemarker);
+	//
+	// if (routeOverlay == null) {
+	// routeOverlay = new RouteOverlayResetable(fillPaint, outlinePaint);
+	// routeMarkerOverlay = new ArrayItemizedTextAudioOverlay(
+	// defaultMarker, activity_, tts_);
+	// routeMarkerOverlayArrayList = new ArrayList<OverlayItem>();
+	//
+	// }
+	// // This one needs to be done again, incase it is of a different size
+	// routeOverlayArray = new GeoPoint[locations.size()];
+	//
+	// for (int i = 0; i < locations.size(); i++) {
+	// tippleLocation location = locations.get(i);
+	// double latitude = location.getlatitude();
+	// double longitude = location.getlongitude();
+	// String title = location.getTitle();
+	// String text = location.getContent();
+	// String tts_text = location.getTTSText();
+	// GeoPoint geoPoint = new GeoPoint(latitude, longitude);
+	//
+	// routeOverlayArray[i] = geoPoint;
+	//
+	// // if (title.startsWith("Manual")) {
+	// // ItemizedOverlay => display marker with text for info pop-up
+	// // window
+	// OverlayTextAudioItem overlayItem = new OverlayTextAudioItem(
+	// geoPoint, title, text, tts_text);
+	//
+	// // routeMarkerOverlay.addOverlay(overlayItem);
+	// routeMarkerOverlayArrayList.add(overlayItem);
+	// // }
+	// }
+	//
+	// // routeOverlay.setRouteData(routeOverlayArray);
+	//
+	// // Only add in if not already present
+	// List<Overlay> overlays = mapView.getOverlays();
+	// if (!overlays.contains(routeOverlay)) {
+	// overlays.add(routeOverlay);
+	// }
+	// if (!overlays.contains(routeMarkerOverlay)) {
+	// overlays.add(routeMarkerOverlay);
+	// }
+	// }
+	//
+	// protected void addLogRouteLocations(MapView mapView) {
+	// for (int i = 0; i < routeMarkerOverlayArrayList.size(); i++) {
+	//
+	// OverlayItem overlay_item = routeMarkerOverlayArrayList.get(i);
+	// routeMarkerOverlay.addOverlay(overlay_item);
+	// }
+	// routeOverlay.setRouteData(routeOverlayArray);
+	//
+	// mapView.invalidate();
+	//
+	// }
+	//
+	// protected void removeLogRouteLocations(MapView mapView) {
+	//
+	// for (int i = 0; i < routeMarkerOverlayArrayList.size(); i++) {
+	//
+	// OverlayItem overlay_item = routeMarkerOverlayArrayList.get(i);
+	// routeMarkerOverlay.removeOverlay(overlay_item);
+	//
+	// }
+	//
+	// routeOverlay.reset();
+	//
+	// mapView.invalidate();
+	// }
+
+	protected void createTourLocationsOverlay(MapView mapView,
+			ArrayList<tippleLocation> locations) {
+		System.out.println("createTourLocaitonOverlay"
+				+ String.valueOf(lengthOfFirstBook) + "size"
+				+ String.valueOf(lengthOfSecondBook)
+				+ "check two locations size");
+		routeOverlayArray = new GeoPoint[lengthOfFirstBook];
+		routeOverlayArray2 = new GeoPoint[lengthOfSecondBook];
+
+		System.out
+				.println("createTourLocaitonOverlay" + routeOverlayArray.length
+						+ "size" + routeOverlayArray2.length);
+
+		int numOfFirstRoute = 0;
+		int numOfSecondRoute = 0;
+		for (int i = 0; i < locations.size(); i++) {
+			tippleLocation location = locations.get(i);
+			double latitude = location.getlatitude();
+			double longitude = location.getlongitude();
+			int radius = (int) Math.round(1000.0 * location.getradius());
+			String title = location.getTitle();
+			String text = location.getContent();
+			String tts_text = location.getTTSText();
+			String chapter = location.getChapter();
+			String nodeID = location.getNodeID();
+			String[] curbookId = nodeID.split("\\.");
+			GeoPoint geoPoint = new GeoPoint(latitude, longitude);
+			circlesOverlayGeoPoints.add(geoPoint);
+			circlesOverlayRadii.add(radius);
+
+			OverlayTextAudioItem overlayItem = new OverlayTextAudioItem(
+					geoPoint, title, text, tts_text, chapter, nodeID);
+
+			itemizedMarkerOverlayArrayList.add(overlayItem);
+
+			if (curbookId[0].equalsIgnoreCase(stationOfCrossURL)) {
+				routeOverlayArray2[numOfSecondRoute] = geoPoint;
+				numOfSecondRoute++;
+			}
+
+			else {
+				routeOverlayArray[numOfFirstRoute] = geoPoint;
+				numOfFirstRoute++;
+			}
+
+		}
+
+		// Only add in if not already present
+		List<Overlay> overlays = mapView.getOverlays();
+
+		if (!overlays.contains(itemizedMarkerOverlay)) {
+			overlays.add(itemizedMarkerOverlay);
+		}
+		if (!overlays.contains(circlesOverlay)) {
+			overlays.add(circlesOverlay);
+		}
+
+		if (!overlays.contains(routeOverlay)) {
+			overlays.add(routeOverlay);
+		}
+		if (!overlays.contains(routeOverlay2)) {
+			overlays.add(routeOverlay2);
+		}
+
+	}
+
+	protected void addTourLocations(MapView mapView, Boolean showTrail) {
+		for (int i = 0; i < itemizedMarkerOverlayArrayList.size(); i++) {
+
+			OverlayTextAudioItem here_marker_item = (OverlayTextAudioItem) itemizedMarkerOverlayArrayList
+					.get(i);
+
+			GeoPoint dm_geopoint = here_marker_item.getPoint();
+			String chapter = here_marker_item.getChapter();
+			String description = here_marker_item.getTitle();
+			String content = here_marker_item.getSnippet();
+			String[] bookId = (here_marker_item.getNodeID()).split("\\.");
+			Drawable marker;
+			OverlayMarkerItem highlight_marker_item;
+			if (bookId[0].equalsIgnoreCase(stationOfCrossURL)) {//
+				// Garden
+				// Design:HASH012992fff824b01e87d30f32
+				// hamilton
+				// Garden;
+				// HASHe280873a5c76118bd7e1a7
+				marker = activity_.getResources().getDrawable(
+						R.drawable.markergreen);// green color
+				highlight_marker_item = new OverlayMarkerItem(dm_geopoint,
+						chapter, description, content);
+				highlight_marker_item.setMarker((marker));
+				routeOverlay.setPaint(fillPaint2, outlinePaint2);
+
+			} else {
+				highlight_marker_item = new OverlayMarkerItem(dm_geopoint,
+						chapter, description, content);
+				itemizedMarkerOverlay.setMarker(defaultMarker);// red color
+				routeOverlay2.setPaint(fillPaint, outlinePaint);
+			}
+
+			highlight_marker_hash_.put(i, highlight_marker_item);
+			itemizedMarkerOverlay.addOverlay(highlight_marker_item);
+
+			GeoPoint geo_point = circlesOverlayGeoPoints.get(i);
+			int radius = circlesOverlayRadii.get(i);
+			circlesOverlay.addCircleData(geo_point, radius);
+		}
+		// check the routeOverlay nodeID
+		if (showTrail) {
+
+			if (lengthOfFirstBook > 0)
+				routeOverlay.setRouteData(routeOverlayArray);
+
+			if (lengthOfSecondBook > 0)
+				routeOverlay2.setRouteData(routeOverlayArray2);
+		}
+
+		mapView.invalidate();
+	}
+
+	protected void removeTourLocations(MapView mapView) {
+		if (itemizedMarkerOverlayArrayList.size() > 0) {
+			for (int i = 0; i < itemizedMarkerOverlayArrayList.size(); i++) {
+
+				OverlayMarkerItem highlight_marker_item = highlight_marker_hash_
+						.remove(i);
+				itemizedMarkerOverlay.removeOverlay(highlight_marker_item);
+			}
+			highlight_marker_hash_.clear();
+			circlesOverlay.reset();
+			// remove routeOverlay item from the map
+			if ((routeOverlay != null) || (routeOverlay2 != null)) {
+
+				routeOverlay.reset();
+				routeOverlay2.reset();
+			}
+			mapView.invalidate();
+		} else {
+			System.out.println("removeTourLocation "
+					+ itemizedMarkerOverlayArrayList.size());
+		}
+
+	}
+
+	private String queryString(Boolean bookOption) {
+
+		String urlLocation = "";
+
+		this.bookSelected = bookOption;
+
+		if (bookSelected) {
+			urlLocation = "http://130.217.244.51:8383/greenstone3/dev?a=d&ed=1&book=off"
+					+ "&c=hamilton&d=";// HASH4e454a5d938158a2a3fcde
+			urlLocation += hamiltonGardenURL;
+			urlLocation += "&dt=hierarchy&p.a=b&p.sa=&p.s=ClassifierBrowse&o=xml";
+		}
+		// book 2
+		else
+		// bookSelected for the book B : Garden Design
+		{
+			urlLocation = "http://130.217.244.51:8383/greenstone3/dev?a=d&ed=1&book=off"
+					+ "&c=hamilton&d=";// HASH012992fff824b01e87d30f32
+			urlLocation += stationOfCrossURL;
+			urlLocation += "&dt=hierarchy&p.a=b&p.sa=&p.s=ClassifierBrowse&o=xml";
+		}
+		return urlLocation;
+	}
+
+	/*
+	 * parseXML translate cml data to location instance
+	 */
+	protected ArrayList<HashMap<String, String>> parseXMLToHashMapArrayList(
+			Boolean bookOption) {
+
+		ArrayList<HashMap<String, String>> hashmap_list = null;
+		String urlLocation;
+		try {
+			urlLocation = queryString(bookOption);
+			URL url = new URL(urlLocation);
+			SAXParserFactory spf = SAXParserFactory.newInstance();
+			SAXParser sp = spf.newSAXParser();
+			XMLReader xr = sp.getXMLReader();
+			xmlHandler myExampleHandler = new xmlHandler("documentNode");
+			xr.setContentHandler(myExampleHandler);
+			xr.parse(new InputSource(url.openStream()));
+			hashmap_list = myExampleHandler.getHashmapList();
+
+		} catch (Exception e) {
+			System.out.println("can't connect to the DL server");
+		}
+		return hashmap_list;
+
+	}
+
+	public ArrayList<tippleLocation> loadTour(Boolean bookOption) {
+
+		ArrayList<HashMap<String, String>> location_hashmap_list = parseXMLToHashMapArrayList(bookOption);
+
+		if (location_hashmap_list != null) {
+			Log.d("TippleActivity::loadTour()", "XML Tour File Parsed");
+		}
+
+		ArrayList<tippleLocation> locations = new ArrayList<tippleLocation>();
+		System.out.println(" LoadTour size of hashmaplist "
+				+ location_hashmap_list.size());
+		for (int i = 0; i < location_hashmap_list.size() - 1; i++) {
+			HashMap<String, String> location_hashmap = location_hashmap_list
+					.get(i);
+			tippleLocation location = new tippleLocation(location_hashmap);
+			locations.add(location);
+
+		}
+		location_hashmap_list.clear();
+		location_hashmap_list = null;
+		if (bookOption)
+			lengthOfFirstBook = locations.size();
+		else
+			lengthOfSecondBook = locations.size();
+		return locations;
+	}
+
+	public ArrayList<tippleLocation> loadTourDescription() {
+		preLocations = loadTour(true);// load book A
+		lengthOfFirstBook = preLocations.size();
+		temLocations = new ArrayList<tippleLocation>();
+		temLocations = loadTour(false);// load book B
+		lengthOfSecondBook = temLocations.size();
+
+		for (int i = 0; i < preLocations.size(); i++) {
+			tippleLocation preLocation = preLocations.get(i);
+			temLocations.add(preLocation);
+		}
+		return temLocations;
+
+	}
+
+	/*
+	 * clear route data, allows route reset data based on the showTrail option.
+	 */
+	public void resetRouteOverlay() {
+		if (routeOverlay != null) {
+			routeOverlay.reset();
+		}
+		if (routeOverlay2 != null)
+			routeOverlay2.reset();
+		if (routeMarkerOverlay != null) {
+			// routeMarkerOverlay.stop();
+			routeMarkerOverlay.clear();
+		}
+
+	}
+
+	/*
+	 * clear route data, circle data and locations data
+	 */
+	public void resetOverlayThreads() {
+		resetRouteOverlay();// reset route data
+		if (circlesOverlayGeoPoints != null) {
+			circlesOverlayGeoPoints.clear();
+			// circlesOverlayGeoPoints = null;
+		}
+		if (circlesOverlayRadii != null) {
+			circlesOverlayRadii.clear();
+			// circlesOverlayRadii = null;
+		}
+		if (circlesOverlay != null) {
+			// circlesOverlay.stop();
+			circlesOverlay.reset();
+
+			// circlesOverlay = null;
+		}
+
+		if (itemizedMarkerOverlay != null) {
+			itemizedMarkerOverlay.clear();
+			// itemizedMarkerOverlay = null;
+		}
+		if (highlight_marker_hash_ != null)
+
+		{
+			highlight_marker_hash_.clear();
+			// highlight_marker_hash_ = null;
+		}
+
+		if (itemizedMarkerOverlayArrayList != null) {
+			itemizedMarkerOverlayArrayList.clear();
+			// itemizedMarkerOverlayArrayList = null;
+		}
+		lengthOfFirstBook = 0;
+		lengthOfSecondBook = 0;
+		if (routeOverlayArray != null)
+			routeOverlayArray = null;
+		if (routeOverlayArray2 != null)
+			routeOverlayArray = null;
+		System.gc();
+
+	}
+
+	public static void stopOverlayThreads() {
+		if (circlesOverlay != null) {
+			// circlesOverlay.stop();
+			circlesOverlay = null;
+		}
+
+		if (itemizedMarkerOverlay != null) {
+			// itemizedMarkerOverlay.stop();
+			itemizedMarkerOverlay = null;
+		}
+
+		if (routeOverlay != null) {
+			// routeOverlay.stop();
+			routeOverlay = null;
+		}
+		if (routeOverlay2 != null) {
+			routeOverlay2 = null;
+		}
+		if (routeMarkerOverlay != null) {
+			// routeMarkerOverlay.stop();
+			routeMarkerOverlay = null;
+		}
+	}
+
+	protected String SyncSynthesizeToFile(String text, String id,
+			String root_utterance) {
+		// String audio_dir = tippleActivity.audioDirectory;
+		String audio_dir = "/sdcard/";
+		File tts_file = new File(audio_dir, id + "-" + root_utterance
+				+ "-TTS.wav");
+		// check if the mps file already exist
+		// File tts_file_mps= new
+		// File(audio_dir,id+"-"+root_utterance+"TTS.mp3");
+		String tts_filename = tts_file.getAbsolutePath();
+		if (tts_file.exists()) {
+
+			// already synthesized this
+			return tts_filename;
+		}
+		// if(tts_file_mps.exists())
+		// {
+		// tts_filename= tts_file_mps.getAbsolutePath();
+		// // already synthesized this
+		// return tts_filename;
+		// }
+		// Rendering the supplied text of the id+utterance derived WAV file
+		HashMap<String, String> hashRender = new HashMap<String, String>();
+		hashRender.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, text);
+
+		String UTTERANCE = root_utterance + "-utterance";
+
+		hashRender.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, UTTERANCE);
+		UtteranceWaitListener listener = new UtteranceWaitListener(UTTERANCE);
+		tts_.setOnUtteranceCompletedListener(listener);
+
+		tts_.synthesizeToFile(text, hashRender, tts_filename);
+
+		try {
+			listener.waitForComplete();
+		} catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+
+		return tts_filename;
+	}
+
+	boolean genPrevVisited = true;
+
+	public boolean textToSpeechToLocation(tippleLocation curtip_location,
+			boolean visited_previously) {
+		if (genPrevVisited) {
+			prevVisitedFilename = SyncSynthesizeToFile("Previously visited.",
+					"Previously-visited", "cue");
+			System.err
+					.println("** Prev visisted file = " + prevVisitedFilename);
+			genPrevVisited = false;
+		}
+		// get updated location and talk to DL, update locations content data
+		// tippleLocation tip_location = loadLocationContent(curtip_location);
+		String title = curtip_location.getTitle();
+		String text = curtip_location.getContent();
+		String id = curtip_location.getID();
+
+		String title_filename = SyncSynthesizeToFile(title, id, "title");
+		String text_filename = SyncSynthesizeToFile(text, id, "text");
+
+		if ((title_filename != null) && (text_filename != null)) {
+			String audio_dir = tippleActivity.audioDirectory;
+			File ding_file = new File(audio_dir, "DingExtended.wav");
+			String ding_filename = ding_file.getAbsolutePath();
+			//
+			if (audio_player_view_.addAudio(id)) {
+				audio_player_view_.queueAudio(title_filename, id, title,
+						visited_previously);
+				audio_player_view_.queueAudio(text_filename, id, text);
+				audio_player_view_
+						.queueAudio(ding_filename, id, "[Audio Bing]");
+
+				audio_player_view_.updateTextViewIfHeadIsNewLocation();
+				System.out
+						.println("the size of audio player view queue should be at least 1"
+								+ audio_player_view_.audioPlayerQueue_.size());
+			}
+		}
+		System.out.println("the size "
+				+ audio_player_view_.audioPlayerQueue_.size());
+		return true;
+	}
+
+	private static class UtteranceWaitListener implements
+			OnUtteranceCompletedListener {
+		private boolean mIsComplete = false;
+		private final String mExpectedUtterance;
+
+		public UtteranceWaitListener(String expectedUtteranceId) {
+			mExpectedUtterance = expectedUtteranceId;
+		}
+
+		public void onUtteranceCompleted(String utteranceId) {
+			if (mExpectedUtterance.equals(utteranceId)) {
+				synchronized (this) {
+					mIsComplete = true;
+					notify();
+				}
+			}
+		}
+
+		public boolean waitForComplete() throws InterruptedException {
+			if (mIsComplete) {
+				return true;
+			}
+			//
+			synchronized (this) {
+				int TTS_SPEECH_MAX_WAIT_TIME = 5 * 1000;
+				wait(TTS_SPEECH_MAX_WAIT_TIME);
+				return mIsComplete;
+			}
+		}
+
+	}
+
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/TippleLog.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/TippleLog.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/TippleLog.java	(revision 26526)
@@ -0,0 +1,185 @@
+package org.tipple.mapDisplay;
+
+import java.io.File;
+import java.io.PrintStream;
+import java.text.DecimalFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.location.Location;
+
+public class TippleLog {
+	protected Activity activity_;
+	protected String log_directory_;
+
+	public PrintStream TIPLOG = null;
+	protected boolean logging_enabled_ = false;
+	protected File logging_file_;
+	protected String logging_filename_final_;
+
+	public TippleLog(Activity activity, String logDirectory) {
+		activity_ = activity;
+		log_directory_ = logDirectory;
+
+		// boolean logfile_ok = initLogging();
+		// alertLogging(logfile_ok);
+	}
+
+	public void optStartLog() {
+		if (TIPLOG != null) {
+			TIPLOG.println("<Log>");
+		}
+	}
+
+	public void optStopLog() {
+		if (TIPLOG != null) {
+			TIPLOG.println("</Log>");
+
+			TIPLOG.close();
+
+			File logging_file_final = new File(logging_filename_final_);
+			logging_file_.renameTo(logging_file_final);
+
+		}
+	}
+
+	public void optMessage(String action, String message_line) {
+		if (logging_enabled_) {
+
+			TIPLOG.println("  <LogEntry>");
+
+			final long timestamp = System.currentTimeMillis();
+			final Calendar cal = Calendar.getInstance();
+			cal.setTimeInMillis(timestamp);
+			Date date = cal.getTime();
+			int hour = date.getHours();
+			int minute = date.getMinutes();
+			int seconds = date.getSeconds();
+
+			TIPLOG.println("    <Timestamp>" + timestamp + "</Timestamp>");
+			TIPLOG.println("    <Time>" + hour + ":" + minute + ":" + seconds
+					+ "</Time>");
+
+			Location loc = locationListener.lastKnownLocation;
+			if (loc != null) {
+				double longitude = loc.getLongitude();
+				double latitude = loc.getLatitude();
+				double accuracy = loc.getAccuracy();
+				TIPLOG.println("    <Longitude>" + longitude + "</Longitude>");
+				TIPLOG.println("    <Latitude>" + latitude + "</Latitude>");
+				TIPLOG.println("    <Accuracy>" + accuracy + "</Accuracy>");
+			}
+			TIPLOG.println("    <Action>" + action + "</Action>");
+			if (message_line != "") {
+				TIPLOG.println("    <Message>" + message_line + "</Message>");
+			}
+			TIPLOG.println("  </LogEntry>");
+		}
+	}
+
+	public void optMessage(String action) {
+		optMessage(action, "");
+	}
+
+	DialogInterface.OnClickListener contEnableCallback = new DialogInterface.OnClickListener() {
+		public void onClick(DialogInterface dialog, int which) {
+			logging_enabled_ = true;
+			dialog.cancel();
+			// dialog.notifyAll();
+		}
+	};
+
+	DialogInterface.OnClickListener contDisableCallback = new DialogInterface.OnClickListener() {
+		public void onClick(DialogInterface dialog, int which) {
+
+			// Delete logging file, then allow application to proceed
+			logging_file_.delete();
+			logging_file_ = null;
+			TIPLOG = null;
+
+			logging_enabled_ = false;
+
+			// SharedPreferences.Editor editor =
+			// activity_.sharedPreferences.edit();
+			// editor.putBoolean("showUserTrail", false);
+			// editor.commit();
+
+			dialog.cancel();
+		}
+	};
+
+	DialogInterface.OnClickListener stopCallback = new DialogInterface.OnClickListener() {
+		public void onClick(DialogInterface dialog, int which) {
+
+			// Delete logging file, then finish application
+
+			logging_file_.delete();
+			logging_file_ = null;
+			TIPLOG = null;
+
+			logging_enabled_ = false;
+
+			activity_.finish();
+		}
+	};
+
+	protected boolean initLogging() {
+		boolean logfile_ok = false;
+
+		try {
+
+			for (int i = 1; i < 1000; i++) {
+
+				DecimalFormat zeroFill = new DecimalFormat("000");
+				String formatted_i = zeroFill.format(i);
+
+				File potential_log_file = new File(log_directory_,
+						"UserInteract-" + formatted_i + ".log");
+
+				if (potential_log_file.exists()) {
+					continue;
+				}
+
+				logging_file_ = new File(log_directory_, "UserInteract-"
+						+ formatted_i);
+				logging_filename_final_ = logging_file_.getAbsolutePath()
+						+ ".log";
+
+				TIPLOG = new PrintStream(logging_file_);
+				if (TIPLOG != null) {
+					logfile_ok = true;
+					break;
+				}
+			}
+		} catch (Exception e) {
+			logging_file_ = null;
+			e.printStackTrace();
+		}
+
+		return logfile_ok;
+	}
+
+	protected void alertLogging(boolean logfile_ok) {
+		AlertDialog.Builder confirm_log_alert = new AlertDialog.Builder(
+				activity_);
+
+		if (logfile_ok) {
+			confirm_log_alert.setTitle("Logging Activity");
+			confirm_log_alert
+					.setMessage("Tipple can log your user interaction.  Do you want this activated?");
+			// confirm_log_alert.setPositiveButton(R.string.logging_ok_enable,contEnableCallback);
+			// confirm_log_alert.setNegativeButton(R.string.logging_ok_disable,contDisableCallback);
+		} else {
+			confirm_log_alert.setTitle("Error");
+			confirm_log_alert
+					.setMessage("Failed to initialize user activity log file");
+			// confirm_log_alert.setPositiveButton(R.string.logging_error_continue,contDisableCallback);
+			// confirm_log_alert.setNegativeButton(R.string.logging_error_stop,stopCallback);
+		}
+
+		confirm_log_alert.show();
+	}
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/XMLToHashmapHandler.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/XMLToHashmapHandler.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/XMLToHashmapHandler.java	(revision 26526)
@@ -0,0 +1,70 @@
+package org.tipple.mapDisplay;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class XMLToHashmapHandler extends DefaultHandler {
+	String lockon_element_;
+	Boolean locked_on_;
+	ArrayList<HashMap<String, String>> lockon_list_;
+
+	HashMap<String, String> hashmap_;
+	String active_element_;
+	StringBuffer inner_text_;
+
+	public XMLToHashmapHandler(String lockon_element) {
+		// initial settings to parse a file
+		lockon_element_ = lockon_element;
+		lockon_list_ = new ArrayList<HashMap<String, String>>();
+		locked_on_ = false;
+	}
+
+	public ArrayList<HashMap<String, String>> getHashmapList() {
+		return lockon_list_;
+	}
+
+	@Override
+	public void startElement(String uri, String localName, String qName,
+			Attributes attributes) throws SAXException {
+		if (localName.equalsIgnoreCase(lockon_element_)) {
+			hashmap_ = new HashMap<String, String>();
+			locked_on_ = true; // => covert each child element inside this to a
+								// hashmap key
+		} else if (locked_on_) {
+			active_element_ = localName.toLowerCase();
+			inner_text_ = new StringBuffer();
+		}
+		// else ignore element as outside area of interest
+	}
+
+	@Override
+	public void endElement(String uri, String localName, String qName)
+			throws SAXException {
+		if (localName.equalsIgnoreCase(lockon_element_)) {
+			// push hashmap onto arraylist
+			lockon_list_.add(hashmap_);
+			hashmap_ = null;
+
+			locked_on_ = false;
+		} else if (localName.equalsIgnoreCase(active_element_)) {
+
+			hashmap_.put(active_element_, inner_text_.toString());
+			active_element_ = null;
+			inner_text_ = null;
+		}
+	}
+
+	@Override
+	public void characters(char[] ch, int start, int length)
+			throws SAXException {
+		if ((locked_on_) && (active_element_ != null)) {
+			String text = new String(ch, start, length);
+			inner_text_.append(text);
+		}
+	}
+
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/copyOfLocationManager.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/copyOfLocationManager.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/copyOfLocationManager.java	(revision 26526)
@@ -0,0 +1,757 @@
+package org.tipple.mapDisplay;
+
+import java.io.File;
+import java.net.URL;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.mapsforge.android.maps.ArrayItemizedMarkerOverlay;
+import org.mapsforge.android.maps.ArrayItemizedTextAudioOverlay;
+import org.mapsforge.android.maps.CirclesOverlay;
+import org.mapsforge.android.maps.GeoPoint;
+import org.mapsforge.android.maps.MapView;
+import org.mapsforge.android.maps.Overlay;
+import org.mapsforge.android.maps.OverlayItem;
+import org.mapsforge.android.maps.OverlayMarkerItem;
+import org.mapsforge.android.maps.OverlayTextAudioItem;
+import org.mapsforge.android.maps.RouteOverlayResetable;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+
+import android.app.Activity;
+import android.graphics.Color;
+import android.graphics.DashPathEffect;
+import android.graphics.Paint;
+import android.graphics.drawable.Drawable;
+import android.location.Location;
+import android.location.LocationManager;
+import android.speech.tts.TextToSpeech;
+import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
+import android.util.Log;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+
+public class copyOfLocationManager {
+	protected LocationManager locationManager;
+	protected static MapView mapview;
+	protected ArrayList<tippleLocation> locations;
+	protected Button retrieveLocationButton;
+	protected double currentLongitude;
+	protected double currentLatitude;
+	protected double currentNodeId;
+	protected String nodeId;
+	protected Boolean bookSelected = true;// true for the first book, false for
+											// the second book
+	// global value for book url
+	public static String hamiltonGardenURL = "HASH4e454a5d938158a2a3fcde";// HASH4e454a5d938158a2a3fcde
+	public static String stationOfCrossURL = "HASH0158acd736565602cd1f1b1b";// HASH0158acd736565602cd1f1b1b
+
+	Activity activity_;
+	AudioPlayerView audio_player_view_;
+	TextToSpeech tts_;
+	TextView textview;
+	protected tippleActivity.bookModeEnum current_book_mode_;
+
+	public static CirclesOverlay circlesOverlay = null;
+	// public static ArrayItemizedTextAudioOverlay itemizedMarkerOverlay;
+	public static ArrayItemizedMarkerOverlay itemizedMarkerOverlay;
+	public static ArrayList<OverlayItem> itemizedMarkerOverlayArrayList;
+	public static ArrayList<GeoPoint> circlesOverlayGeoPoints;
+	public static ArrayList<Integer> circlesOverlayRadii;
+
+	public static RouteOverlayResetable routeOverlay = null;
+	public static RouteOverlayResetable routeOverlay2 = null;
+	public static ArrayItemizedTextAudioOverlay routeMarkerOverlay;
+	public static GeoPoint[] routeOverlayArray;// hold first book overlay data
+	public static ArrayList<String> nodeIDArray;
+	public static GeoPoint[] routeOverlayArray2;// hold second book overlay data
+	public static int lengthOfFirstBook = 0;
+	public static int lengthOfSecondBook = 0;
+
+	// paint color for route
+	Paint fillPaint, fillPaint2, outlinePaint, outlinePaint2;
+
+	public static ArrayList<OverlayItem> routeMarkerOverlayArrayList;
+	public static HashMap<Integer, OverlayMarkerItem> highlight_marker_hash_;
+	public static String prevVisitedFilename;
+	Drawable defaultMarker;// declare as global variable
+
+	ArrayList<tippleLocation> preLocations = null;// book hamilton Garden
+	ArrayList<tippleLocation> temLocations = null;// seocnd station Of Cross
+
+	copyOfLocationManager(Activity activity, MapView mapview,
+			TextView textview, LocationManager manager,
+			AudioPlayerView audio_player_view, TextToSpeech tts) {
+		activity_ = activity;
+		audio_player_view_ = audio_player_view;
+		tts_ = tts;
+		this.locationManager = manager;
+		this.mapview = mapview;
+		this.textview = textview;
+
+		// initailize these arraylist value
+
+		Paint circleFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+		circleFillPaint.setStyle(Paint.Style.FILL);
+		circleFillPaint.setColor(Color.BLUE);
+		circleFillPaint.setAlpha(64);
+
+		Paint circleOutlinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+		circleOutlinePaint.setStyle(Paint.Style.STROKE);
+		// circleOutlinePaint.setStyle(Paint.Style.FILL);
+		circleOutlinePaint.setColor(Color.BLUE);
+		circleOutlinePaint.setAlpha(64);// initially 128
+		circleOutlinePaint.setStrokeWidth(1);
+		circlesOverlay = new CirclesOverlay(circleFillPaint, circleOutlinePaint);
+		circlesOverlayGeoPoints = new ArrayList<GeoPoint>();
+		circlesOverlayRadii = new ArrayList<Integer>();
+		defaultMarker = activity_.getResources().getDrawable(R.drawable.marker);
+		itemizedMarkerOverlay = new ArrayItemizedMarkerOverlay(defaultMarker,
+				activity_);
+		// itemizedMarkerOverlay = new ArrayItemizedTextAudioOverlay(
+		// defaultMarker, activity_);
+		itemizedMarkerOverlayArrayList = new ArrayList<OverlayItem>();
+		highlight_marker_hash_ = new HashMap<Integer, OverlayMarkerItem>();
+		fillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+		// deal with routeoverlay
+		fillPaint.setStyle(Paint.Style.STROKE);
+		fillPaint.setColor(Color.BLUE);
+		fillPaint.setAlpha(160);
+		fillPaint.setStrokeWidth(7);
+		fillPaint.setStrokeCap(Paint.Cap.BUTT);
+		fillPaint.setStrokeJoin(Paint.Join.ROUND);
+		fillPaint.setPathEffect(new DashPathEffect(new float[] { 20, 20 }, 0));
+
+		outlinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+		outlinePaint.setStyle(Paint.Style.STROKE);
+		outlinePaint.setColor(Color.BLUE);
+		outlinePaint.setAlpha(96);
+		outlinePaint.setStrokeWidth(7);
+		outlinePaint.setStrokeCap(Paint.Cap.BUTT);
+		outlinePaint.setStrokeJoin(Paint.Join.ROUND);
+		fillPaint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
+		// deal with routeoverlay
+		fillPaint2.setStyle(Paint.Style.STROKE);
+		fillPaint2.setColor(Color.RED);
+		fillPaint2.setAlpha(160);
+		fillPaint2.setStrokeWidth(7);
+		fillPaint2.setStrokeCap(Paint.Cap.BUTT);
+		fillPaint2.setStrokeJoin(Paint.Join.ROUND);
+		fillPaint2.setPathEffect(new DashPathEffect(new float[] { 20, 20 }, 0));
+
+		outlinePaint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
+		outlinePaint2.setStyle(Paint.Style.STROKE);
+		outlinePaint2.setColor(Color.BLUE);
+		outlinePaint2.setAlpha(96);
+		outlinePaint2.setStrokeWidth(7);
+		outlinePaint2.setStrokeCap(Paint.Cap.BUTT);
+		outlinePaint2.setStrokeJoin(Paint.Join.ROUND);
+
+		routeOverlay = new RouteOverlayResetable(fillPaint, outlinePaint);
+		routeOverlay2 = new RouteOverlayResetable(fillPaint2, outlinePaint2);
+
+	}
+
+	Location thislocation;// lastknown location should be global
+
+	protected String getCurrentLocation() {
+		String myCurrentLongitude = null;
+		thislocation = locationListener.lastKnownLocation;
+		if (thislocation != null) {
+
+			currentLongitude = thislocation.getLongitude();
+			currentLatitude = thislocation.getLatitude();
+
+			// Toast.makeText(Tipple.this, message, Toast.LENGTH_LONG).show();
+			String[] result = (String.valueOf(currentLatitude)).split("\\.");
+			// myCurrentLongitude = result[1].substring(0, 4);
+			myCurrentLongitude = result[0].substring(1, 3);// image start
+			// from
+			// -,
+			DecimalFormat trunPlaces = new DecimalFormat("0.0000");
+			String text_mess = "(Long,Lat): ("
+					+ trunPlaces.format(currentLongitude) + ","
+					+ trunPlaces.format(currentLatitude) + ")";
+			textview.setText(text_mess);
+			// String myCurrentLongitude = "-37.80608675";
+
+		} else {
+			Toast.makeText(activity_, "failed to get GPS", Toast.LENGTH_LONG)
+					.show();
+
+		}
+		return myCurrentLongitude;
+	}
+
+	protected void createLogRouteLocationsOverlay(MapView mapView,
+			ArrayList<tippleLocation> locations) {
+		Paint fillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+		fillPaint.setStyle(Paint.Style.STROKE);
+		fillPaint.setColor(Color.BLUE);
+		fillPaint.setAlpha(160);
+		fillPaint.setStrokeWidth(7);
+		fillPaint.setStrokeCap(Paint.Cap.BUTT);
+		fillPaint.setStrokeJoin(Paint.Join.ROUND);
+		fillPaint.setPathEffect(new DashPathEffect(new float[] { 20, 20 }, 0));
+
+		Paint outlinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+		outlinePaint.setStyle(Paint.Style.STROKE);
+		outlinePaint.setColor(Color.BLUE);
+		outlinePaint.setAlpha(96);
+		outlinePaint.setStrokeWidth(7);
+		outlinePaint.setStrokeCap(Paint.Cap.BUTT);
+		outlinePaint.setStrokeJoin(Paint.Join.ROUND);
+
+		Drawable defaultMarker = activity_.getResources().getDrawable(
+				R.drawable.routemarker);
+
+		if (routeOverlay == null) {
+			routeOverlay = new RouteOverlayResetable(fillPaint, outlinePaint);
+			routeMarkerOverlay = new ArrayItemizedTextAudioOverlay(
+					defaultMarker, activity_, tts_);
+			routeMarkerOverlayArrayList = new ArrayList<OverlayItem>();
+
+		}
+		// This one needs to be done again, incase it is of a different size
+		routeOverlayArray = new GeoPoint[locations.size()];
+
+		for (int i = 0; i < locations.size(); i++) {
+			tippleLocation location = locations.get(i);
+			double latitude = location.getlatitude();
+			double longitude = location.getlongitude();
+			String title = location.getTitle();
+			String text = location.getContent();
+			String tts_text = location.getTTSText();
+			GeoPoint geoPoint = new GeoPoint(latitude, longitude);
+
+			routeOverlayArray[i] = geoPoint;
+
+			// if (title.startsWith("Manual")) {
+			// ItemizedOverlay => display marker with text for info pop-up
+			// window
+			OverlayTextAudioItem overlayItem = new OverlayTextAudioItem(
+					geoPoint, title, text, tts_text);
+
+			// routeMarkerOverlay.addOverlay(overlayItem);
+			routeMarkerOverlayArrayList.add(overlayItem);
+			// }
+		}
+
+		// routeOverlay.setRouteData(routeOverlayArray);
+
+		// Only add in if not already present
+		List<Overlay> overlays = mapView.getOverlays();
+		if (!overlays.contains(routeOverlay)) {
+			overlays.add(routeOverlay);
+		}
+		if (!overlays.contains(routeMarkerOverlay)) {
+			overlays.add(routeMarkerOverlay);
+		}
+	}
+
+	protected void addLogRouteLocations(MapView mapView) {
+		for (int i = 0; i < routeMarkerOverlayArrayList.size(); i++) {
+
+			OverlayItem overlay_item = routeMarkerOverlayArrayList.get(i);
+			routeMarkerOverlay.addOverlay(overlay_item);
+		}
+		routeOverlay.setRouteData(routeOverlayArray);
+
+		mapView.invalidate();
+
+	}
+
+	protected void removeLogRouteLocations(MapView mapView) {
+
+		for (int i = 0; i < routeMarkerOverlayArrayList.size(); i++) {
+
+			OverlayItem overlay_item = routeMarkerOverlayArrayList.get(i);
+			routeMarkerOverlay.removeOverlay(overlay_item);
+
+		}
+
+		routeOverlay.reset();
+
+		mapView.invalidate();
+	}
+
+	protected void createTourLocationsOverlay(MapView mapView,
+			ArrayList<tippleLocation> locations) {
+		System.out.println("createTourLocaitonOverlay"
+				+ String.valueOf(lengthOfFirstBook) + "size"
+				+ String.valueOf(lengthOfSecondBook)
+				+ "check two locations size");
+		// This one needs to be done again, incase it is of a different size
+		routeOverlayArray = new GeoPoint[lengthOfFirstBook];// changed it
+															// later
+															// on
+		routeOverlayArray2 = new GeoPoint[lengthOfSecondBook];// supposed to
+		// store second
+		// book
+		// with two chapters
+		System.out
+				.println("createTourLocaitonOverlay" + routeOverlayArray.length
+						+ "size" + routeOverlayArray2.length);
+		// nodeIDArray = new ArrayList<String>();
+		int numOfFirstRoute = 0;
+		int numOfSecondRoute = 0;
+		for (int i = 0; i < locations.size(); i++) {
+			tippleLocation location = locations.get(i);
+			double latitude = location.getlatitude();
+			double longitude = location.getlongitude();
+			int radius = (int) Math.round(1000.0 * location.getradius());
+			String title = location.getTitle();
+			String text = location.getContent();
+			String tts_text = location.getTTSText();
+			String chapter = location.getChapter();
+			String nodeID = location.getNodeID();
+			String[] curbookId = nodeID.split("\\.");
+			GeoPoint geoPoint = new GeoPoint(latitude, longitude);
+			// System.out.println("createTourLocation" +
+			// String.valueOf(latitude));
+			// add geo to routOverlayArray
+
+			// CirclesOverlay => Highlight location with a circle showing
+			// catchment radius
+			// circlesOverlay.addCircleData(geoPoint, radius);
+			circlesOverlayGeoPoints.add(geoPoint);
+			circlesOverlayRadii.add(radius);
+
+			// ItemizedOverlay => display marker with text for info pop-up
+			// window
+			OverlayTextAudioItem overlayItem = new OverlayTextAudioItem(
+					geoPoint, title, text, tts_text, chapter, nodeID);
+
+			// itemizedMarkerOverlay.addOverlay(overlayItem);
+			itemizedMarkerOverlayArrayList.add(overlayItem);
+			// if (tippleActivity.showUserTrail)
+
+			if (curbookId[0].equalsIgnoreCase(stationOfCrossURL)) {
+				routeOverlayArray2[numOfSecondRoute] = geoPoint;
+				numOfSecondRoute++;
+			}
+
+			// else if (curbookId[0].equalsIgnoreCase(hamiltonGardenURL)) {
+			// routeOverlayArray[i] = geoPoint;
+			// }
+
+			else {
+				routeOverlayArray[numOfFirstRoute] = geoPoint;
+				numOfFirstRoute++;
+			}
+			// nodeIDArray.add(nodeID);
+		}
+
+		// Only add in if not already present
+		List<Overlay> overlays = mapView.getOverlays();
+
+		if (!overlays.contains(itemizedMarkerOverlay)) {
+			overlays.add(itemizedMarkerOverlay);
+		}
+		if (!overlays.contains(circlesOverlay)) {
+			overlays.add(circlesOverlay);
+		}
+		// if (tippleActivity.showUserTrail) {
+		if (!overlays.contains(routeOverlay)) {
+			overlays.add(routeOverlay);
+		}
+		if (!overlays.contains(routeOverlay2)) {
+			overlays.add(routeOverlay2);
+		}
+		// }
+
+	}
+
+	protected void addTourLocations(MapView mapView, Boolean showTrail) {
+		for (int i = 0; i < itemizedMarkerOverlayArrayList.size(); i++) {
+
+			OverlayTextAudioItem here_marker_item = (OverlayTextAudioItem) itemizedMarkerOverlayArrayList
+					.get(i);
+
+			GeoPoint dm_geopoint = here_marker_item.getPoint();
+			String chapter = here_marker_item.getChapter();
+			String[] bookId = (here_marker_item.getNodeID()).split("\\.");
+			Drawable marker;
+			OverlayMarkerItem highlight_marker_item;
+			if (bookId[0].equalsIgnoreCase(stationOfCrossURL)) {//
+				// Garden
+				// Design:HASH012992fff824b01e87d30f32
+				// hamilton
+				// Garden;
+				// HASHe280873a5c76118bd7e1a7
+				marker = activity_.getResources().getDrawable(
+						R.drawable.markergreen);// greeen color
+				highlight_marker_item = new OverlayMarkerItem(dm_geopoint,
+						chapter);
+				highlight_marker_item.setMarker((marker));
+				routeOverlay.setPaint(fillPaint2, outlinePaint2);
+
+			} else {
+				highlight_marker_item = new OverlayMarkerItem(dm_geopoint,
+						chapter);
+				itemizedMarkerOverlay.setMarker(defaultMarker);// red color
+				routeOverlay2.setPaint(fillPaint, outlinePaint);
+			}
+
+			highlight_marker_hash_.put(i, highlight_marker_item);
+			itemizedMarkerOverlay.addOverlay(highlight_marker_item);
+
+			GeoPoint geo_point = circlesOverlayGeoPoints.get(i);
+			int radius = circlesOverlayRadii.get(i);
+			circlesOverlay.addCircleData(geo_point, radius);
+		}
+		// next check the routeOverlay nodeID, then call SetPaint method to
+		// change the route color
+		if (showTrail) {
+			// if (routeOverlayArray.length > 0)
+			if (lengthOfFirstBook > 0)
+				routeOverlay.setRouteData(routeOverlayArray);
+			// if (routeOverlayArray2.length > 0)
+			if (lengthOfSecondBook > 0)
+				routeOverlay2.setRouteData(routeOverlayArray2);
+		}
+
+		mapView.invalidate();
+	}
+
+	protected void removeTourLocations(MapView mapView) {
+		if (itemizedMarkerOverlayArrayList.size() > 0) {
+			for (int i = 0; i < itemizedMarkerOverlayArrayList.size(); i++) {
+
+				OverlayMarkerItem highlight_marker_item = highlight_marker_hash_
+						.remove(i);
+				itemizedMarkerOverlay.removeOverlay(highlight_marker_item);
+			}
+			highlight_marker_hash_.clear();
+			circlesOverlay.reset();
+			// remove routeOverlay item from the map
+			if ((routeOverlay != null) || (routeOverlay2 != null)) {// no matter
+																	// boolean
+																	// showUserTrail,
+				// always need to reset to initial
+				// value.
+				routeOverlay.reset();
+				routeOverlay2.reset();
+			}
+			mapView.invalidate();
+		} else {
+			System.out.println("removeTourLocation "
+					+ itemizedMarkerOverlayArrayList.size());
+		}
+
+	}
+
+	private String queryString(Boolean bookOption) {
+
+		String urlLocation = "";
+
+		this.bookSelected = bookOption;
+		// bookeSeleted for the bookA: hamilton Garden
+		if (bookSelected) {
+			urlLocation = "http://130.217.244.51:8383/greenstone3/dev?a=d&ed=1&book=off"
+					+ "&c=hamilton&d=";// HASH4e454a5d938158a2a3fcde
+			urlLocation += hamiltonGardenURL;
+			urlLocation += "&dt=hierarchy&p.a=b&p.sa=&p.s=ClassifierBrowse&o=xml";
+		}
+		// book 2
+		else
+		// bookSelected for the book B : Garden Design
+		{
+			urlLocation = "http://130.217.244.51:8383/greenstone3/dev?a=d&ed=1&book=off"
+					+ "&c=hamilton&d=";// HASH012992fff824b01e87d30f32
+			urlLocation += stationOfCrossURL;
+			urlLocation += "&dt=hierarchy&p.a=b&p.sa=&p.s=ClassifierBrowse&o=xml";
+		}
+		// book 1 and book 2
+
+		return urlLocation;
+	}
+
+	/*
+	 * now only pass the longitude location to connect to DL, need to pass
+	 * longitude and latitude later on?
+	 */
+	protected ArrayList<HashMap<String, String>> parseXMLToHashMapArrayList(
+			Boolean bookOption) {
+
+		ArrayList<HashMap<String, String>> hashmap_list = null;
+		String urlLocation;
+		try {
+			urlLocation = queryString(bookOption);
+			URL url = new URL(urlLocation);
+			SAXParserFactory spf = SAXParserFactory.newInstance();
+			SAXParser sp = spf.newSAXParser();
+
+			XMLReader xr = sp.getXMLReader();
+
+			xmlHandler myExampleHandler = new xmlHandler("documentNode");
+
+			xr.setContentHandler(myExampleHandler);
+
+			xr.parse(new InputSource(url.openStream()));
+
+			hashmap_list = myExampleHandler.getHashmapList();
+
+		} catch (Exception e) {
+			// Log.e(MY_DEBUG_TAG, "Failed to get DL data", e);
+			System.out.println("can't connect to the DL server");
+		}
+		return hashmap_list;
+
+	}
+
+	public ArrayList<tippleLocation> loadTour(Boolean bookOption) {
+
+		ArrayList<HashMap<String, String>> location_hashmap_list = parseXMLToHashMapArrayList(bookOption);
+
+		if (location_hashmap_list != null) {
+			Log.d("TippleActivity::loadTour()", "XML Tour File Parsed");
+		}
+
+		ArrayList<tippleLocation> locations = new ArrayList<tippleLocation>();
+		System.out.println(" LoadTour size of hashmaplist "
+				+ location_hashmap_list.size());
+		for (int i = 0; i < location_hashmap_list.size() - 1; i++) {
+			HashMap<String, String> location_hashmap = location_hashmap_list
+					.get(i);
+			tippleLocation location = new tippleLocation(location_hashmap);
+			locations.add(location);
+
+		}
+		location_hashmap_list.clear();
+		location_hashmap_list = null;
+		if (bookOption)
+			lengthOfFirstBook = locations.size();
+		else
+			lengthOfSecondBook = locations.size();
+		return locations;
+	}
+
+	public ArrayList<tippleLocation> loadTourDescription() {
+		preLocations = loadTour(true);// load book A
+		lengthOfFirstBook = preLocations.size();
+		temLocations = new ArrayList<tippleLocation>();
+		temLocations = loadTour(false);// load book B
+		lengthOfSecondBook = temLocations.size();
+
+		for (int i = 0; i < preLocations.size(); i++) {
+			tippleLocation preLocation = preLocations.get(i);
+			temLocations.add(preLocation);
+		}
+		// preLocations.clear();
+		// preLocations = null;
+		// return temLocations;
+		return temLocations;
+
+	}
+
+	/*
+	 * clear route data, allows route reset data based on the showTrail option.
+	 */
+	public void resetRouteOverlay() {
+		// if (routeOverlayArray != null)
+		// routeOverlayArray = null;
+		// if (routeOverlayArray2 != null)
+		// routeOverlayArray = null;
+		if (routeOverlay != null) {// no matter boolean showUserTrail,
+			// always need to reset to initial
+			// value.
+			routeOverlay.reset();
+		}
+		if (routeOverlay2 != null)
+			routeOverlay2.reset();
+		if (routeMarkerOverlay != null) {
+			// routeMarkerOverlay.stop();
+			routeMarkerOverlay.clear();
+		}
+
+	}
+
+	/*
+	 * clear route data, circle data and locations data
+	 */
+	public void resetOverlayThreads() {
+		resetRouteOverlay();// reset route data
+		if (circlesOverlayGeoPoints != null) {
+			circlesOverlayGeoPoints.clear();
+			// circlesOverlayGeoPoints = null;
+		}
+		if (circlesOverlayRadii != null) {
+			circlesOverlayRadii.clear();
+			// circlesOverlayRadii = null;
+		}
+		if (circlesOverlay != null) {
+			// circlesOverlay.stop();
+			circlesOverlay.reset();
+
+			// circlesOverlay = null;
+		}
+
+		if (itemizedMarkerOverlay != null) {
+			itemizedMarkerOverlay.clear();
+
+			// itemizedMarkerOverlay = null;
+		}
+		if (highlight_marker_hash_ != null)
+
+		{
+			highlight_marker_hash_.clear();
+			// highlight_marker_hash_ = null;
+		}
+
+		if (itemizedMarkerOverlayArrayList != null) {
+			itemizedMarkerOverlayArrayList.clear();
+			// itemizedMarkerOverlayArrayList = null;
+		}
+		lengthOfFirstBook = 0;
+		lengthOfSecondBook = 0;
+		if (routeOverlayArray != null)
+			routeOverlayArray = null;
+		if (routeOverlayArray2 != null)
+			routeOverlayArray = null;
+		System.gc();
+
+	}
+
+	public static void stopOverlayThreads() {
+		if (circlesOverlay != null) {
+			// circlesOverlay.stop();
+			circlesOverlay = null;
+		}
+
+		if (itemizedMarkerOverlay != null) {
+			// itemizedMarkerOverlay.stop();
+			itemizedMarkerOverlay = null;
+		}
+
+		if (routeOverlay != null) {
+			// routeOverlay.stop();
+			routeOverlay = null;
+		}
+		if (routeOverlay2 != null) {
+			routeOverlay2 = null;
+		}
+		if (routeMarkerOverlay != null) {
+			// routeMarkerOverlay.stop();
+			routeMarkerOverlay = null;
+		}
+	}
+
+	protected String SyncSynthesizeToFile(String text, String id,
+			String root_utterance) {
+		// String audio_dir = tippleActivity.audioDirectory;
+		String audio_dir = "/sdcard/";
+		File tts_file = new File(audio_dir, id + "-" + root_utterance
+				+ "-TTS.wav");
+		String tts_filename = tts_file.getAbsolutePath();
+
+		if (tts_file.exists()) {
+			// already synthesized this
+			return tts_filename;
+		}
+
+		// Rendering the supplied text of the id+utterance derived WAV file
+		HashMap<String, String> hashRender = new HashMap<String, String>();
+		hashRender.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, text);
+
+		String UTTERANCE = root_utterance + "-utterance";
+
+		hashRender.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, UTTERANCE);
+		UtteranceWaitListener listener = new UtteranceWaitListener(UTTERANCE);
+		tts_.setOnUtteranceCompletedListener(listener);
+
+		tts_.synthesizeToFile(text, hashRender, tts_filename);
+
+		try {
+			listener.waitForComplete();
+		} catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+
+		return tts_filename;
+	}
+
+	boolean genPrevVisited = true;
+
+	public boolean textToSpeechToLocation(tippleLocation curtip_location,
+			boolean visited_previously) {
+		if (genPrevVisited) {
+			prevVisitedFilename = SyncSynthesizeToFile("Previously visited.",
+					"Previously-visited", "cue");
+			System.err
+					.println("** Prev visisted file = " + prevVisitedFilename);
+			genPrevVisited = false;
+		}
+		// get updated location and talk to DL, update locations content data
+		// tippleLocation tip_location = loadLocationContent(curtip_location);
+		String title = curtip_location.getTitle();
+		String text = curtip_location.getContent();
+		String id = curtip_location.getID();
+
+		String title_filename = SyncSynthesizeToFile(title, id, "title");
+		String text_filename = SyncSynthesizeToFile(text, id, "text");
+
+		if ((title_filename != null) && (text_filename != null)) {
+			String audio_dir = tippleActivity.audioDirectory;
+			File ding_file = new File(audio_dir, "DingExtended.wav");
+			String ding_filename = ding_file.getAbsolutePath();
+			//
+			if (audio_player_view_.addAudio(id)) {
+				// tippleActivity.log.optMessage("Queue Audio", title);
+				audio_player_view_.queueAudio(title_filename, id, title,
+						visited_previously);
+				audio_player_view_.queueAudio(text_filename, id, text);
+				audio_player_view_
+						.queueAudio(ding_filename, id, "[Audio Bing]");
+
+				audio_player_view_.updateTextViewIfHeadIsNewLocation();
+				System.out
+						.println("the size of audio player view queue should be at least 1"
+								+ audio_player_view_.audioPlayerQueue_.size());
+			}
+		}
+		System.out.println("the size "
+				+ audio_player_view_.audioPlayerQueue_.size());
+		return true;
+	}
+
+	private static class UtteranceWaitListener implements
+			OnUtteranceCompletedListener {
+		private boolean mIsComplete = false;
+		private final String mExpectedUtterance;
+
+		public UtteranceWaitListener(String expectedUtteranceId) {
+			mExpectedUtterance = expectedUtteranceId;
+		}
+
+		public void onUtteranceCompleted(String utteranceId) {
+			if (mExpectedUtterance.equals(utteranceId)) {
+				synchronized (this) {
+					mIsComplete = true;
+					notify();
+				}
+			}
+		}
+
+		public boolean waitForComplete() throws InterruptedException {
+			if (mIsComplete) {
+				return true;
+			}
+			//
+			synchronized (this) {
+				int TTS_SPEECH_MAX_WAIT_TIME = 5 * 1000;
+				wait(TTS_SPEECH_MAX_WAIT_TIME);
+				return mIsComplete;
+			}
+		}
+
+	}
+
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/locationListener.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/locationListener.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/locationListener.java	(revision 26526)
@@ -0,0 +1,354 @@
+package org.tipple.mapDisplay;
+
+import java.io.File;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.mapsforge.android.maps.ArrayItemizedMarkerOverlay;
+import org.mapsforge.android.maps.CircleOverlay;
+import org.mapsforge.android.maps.GeoPoint;
+import org.mapsforge.android.maps.MapController;
+import org.mapsforge.android.maps.MapView;
+import org.mapsforge.android.maps.OverlayMarkerItem;
+import org.mapsforge.android.maps.OverlayTextAudioItem;
+import org.mapsforge.android.maps.Projection;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.graphics.drawable.Drawable;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.media.MediaPlayer;
+import android.os.Bundle;
+import android.os.Vibrator;
+import android.widget.TextView;
+
+public class locationListener implements LocationListener {
+	public static Location lastKnownLocation = null;
+
+	protected ArrayList<tippleLocation> locations;
+
+	protected ArrayList<tippleLocation> locations_;
+	Drawable highlight_marker2;
+	Drawable highlight_marker1;
+	Drawable marker;
+
+	protected Activity activity_;
+	protected MapView map_view_;
+	protected TextView text_view_;
+	protected LocationManager tip_location_manager_;
+	protected TippleLocationManagerVersion2 tipManager;
+	// protected tippleLocationManager tipManager;
+	protected MapController map_controller_;
+	protected CircleOverlay here_overlay_;
+	protected ArrayItemizedMarkerOverlay highlight_marker_overlay_;
+
+	protected Vibrator vibrator_;
+
+	protected Set<tippleLocation> curr_locations_;
+	protected Set<tippleLocation> prev_locations_;
+	HashMap<Integer, OverlayMarkerItem> highlight_marker_hash_;
+
+	public locationListener(Activity activity, MapView map_view,
+			TextView text_view, LocationManager location_manager,
+			TippleLocationManagerVersion2 tipManager,
+			ArrayList<tippleLocation> locations) {
+		activity_ = activity;
+		map_view_ = map_view;
+		text_view_ = text_view;
+		this.tipManager = tipManager;
+		tip_location_manager_ = location_manager;
+		locations_ = locations;
+
+		// location aware
+		Paint circleFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+		circleFillPaint.setStyle(Paint.Style.FILL);
+		circleFillPaint.setColor(Color.GREEN);
+		circleFillPaint.setAlpha(64);
+
+		Paint circleOutlinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+		circleOutlinePaint.setStyle(Paint.Style.STROKE);
+		circleOutlinePaint.setColor(Color.GREEN);
+		circleOutlinePaint.setAlpha(128);
+		circleOutlinePaint.setStrokeWidth(3);
+
+		Drawable highlightMarker = activity_.getResources().getDrawable(
+				R.drawable.markerhighlightbook1);
+
+		highlight_marker_overlay_ = new ArrayItemizedMarkerOverlay(
+				highlightMarker, activity);
+
+		map_view_.getOverlays().add(highlight_marker_overlay_);
+
+		vibrator_ = (Vibrator) activity
+				.getSystemService(Context.VIBRATOR_SERVICE);
+
+		curr_locations_ = new HashSet<tippleLocation>();
+		prev_locations_ = new HashSet<tippleLocation>();
+		highlight_marker_hash_ = new HashMap<Integer, OverlayMarkerItem>();
+
+	}
+
+	ArrayList<tippleLocation> getLocations() {
+		return locations_;
+	}
+
+	void setLocations(ArrayList<tippleLocation> locations) {
+		this.locations_ = locations;
+	}
+
+	Activity getActivity() {
+		return activity_;
+	}
+
+	void resetOverlayThreadsOnListener() {
+
+		if (highlight_marker_overlay_ != null) {
+			highlight_marker_overlay_.clear();
+			highlight_marker_overlay_ = null;
+		}
+		if (highlight_marker_hash_ != null)
+
+		{
+			highlight_marker_hash_.clear();
+			highlight_marker_hash_ = null;
+		}
+		if (locations_ != null)
+
+		{
+			locations_.clear();
+			locations_ = null;
+		}
+
+		if (curr_locations_ != null) {
+			curr_locations_.clear();
+			curr_locations_ = null;
+		}
+		if (prev_locations_ != null) {
+			prev_locations_.clear();
+			prev_locations_ = null;
+		}
+
+	}
+
+	boolean checking_location_ = false;
+
+	synchronized protected boolean getLock() {
+		if (!checking_location_) {
+			checking_location_ = true;
+		}
+
+		return checking_location_;
+	}
+
+	synchronized protected void freeLock() {
+		checking_location_ = false;
+	}
+
+	protected double pointDistance(Point place_point, Point here_point) {
+		double delta_x = place_point.x - here_point.x;
+		double delta_y = place_point.y - here_point.y;
+		double pixel_distance = Math.sqrt((delta_x * delta_x)
+				+ (delta_y * delta_y));
+
+		return pixel_distance;
+	}
+
+	Point lastLoggedPoint_ = null;
+
+	protected void updateActiveLocations(Location loc) {
+		// Find out if the current GPS location lies within the boundaries
+		// of any of the tour locations
+		Projection projection = map_view_.getProjection();
+		byte zoom_level = map_view_.getZoomLevel();
+		// byte zoom_level = 10; // work at a reasonable level of scale
+
+		float in_out_gap_meters = 3.0f;
+		float in_out_gap_pixels = projection.metersToPixels(in_out_gap_meters,
+				zoom_level);
+
+		double here_latitude = loc.getLatitude();
+		double here_longitude = loc.getLongitude();
+		GeoPoint here_geopoint = new GeoPoint(here_latitude, here_longitude);
+		Point here_point = projection.toPoint(here_geopoint, null, zoom_level);
+
+		if (lastLoggedPoint_ == null) {
+			lastLoggedPoint_ = here_point;
+			// tippleActivity.log.optMessage("GPS Location Reading");
+		} else {
+			float far_enough_meters = 3.0f; // 3 meters
+			float far_enough_pixels = projection.metersToPixels(
+					far_enough_meters, zoom_level);
+			if (pointDistance(here_point, lastLoggedPoint_) > far_enough_pixels) {
+				// tippleActivity.log.optMessage("GPS Location Reading");
+			}
+		}
+
+		for (int i = 0; i < locations_.size(); i++) {
+
+			tippleLocation place = locations_.get(i);
+
+			double place_latitude = place.getlatitude();
+			double place_longitude = place.getlongitude();
+			double radius_meters = place.getradius() * 1000.0;
+
+			GeoPoint place_geopoint = new GeoPoint(place_latitude,
+					place_longitude);
+			Point place_point = projection.toPoint(place_geopoint, null,
+					zoom_level);
+
+			float radius_pixel_distance = projection.metersToPixels(
+					(float) radius_meters, zoom_level);
+
+			double delta_x = place_point.x - here_point.x;
+			double delta_y = place_point.y - here_point.y;
+			double pixel_distance = Math.sqrt((delta_x * delta_x)
+					+ (delta_y * delta_y));
+
+			double outside_pixel_distance = radius_pixel_distance
+					+ in_out_gap_pixels;
+			double inside_pixel_distance = radius_pixel_distance;
+
+			if (pixel_distance <= inside_pixel_distance) {
+
+				if (!curr_locations_.contains(place)) {
+					// User has entered new location on tour
+
+					curr_locations_.add(place);
+					vibrator_.vibrate(1000);
+					Bundle bundle = new Bundle();
+					bundle.putString("placeName", place.getTitle());
+
+					boolean visited_previously = prev_locations_
+							.contains(place);
+					tipManager
+							.textToSpeechToLocation(place, visited_previously);
+
+					OverlayTextAudioItem here_marker_item = (OverlayTextAudioItem) TippleLocationManagerVersion2.itemizedMarkerOverlayArrayList
+							.get(i);
+					GeoPoint dm_geopoint = here_marker_item.getPoint();
+					String title = here_marker_item.getTitle();
+					String[] nodeId = here_marker_item.getNodeID().split("\\.");
+					if (nodeId[0]
+							.equalsIgnoreCase(TippleLocationManagerVersion2.stationOfCrossURL)) {// hamiltonGardenURL
+						marker = activity_.getResources().getDrawable(
+								R.drawable.markerhighlightbook2);
+
+					}
+
+					else {
+						marker = activity_.getResources().getDrawable(
+								R.drawable.markerhighlightbook1);// red+yellow
+
+					}
+					OverlayMarkerItem highlight_marker_item = new OverlayMarkerItem(
+							dm_geopoint, title);
+					highlight_marker_item.setMarker(marker);
+					highlight_marker_hash_.put(i, highlight_marker_item);
+					highlight_marker_overlay_.addOverlay(highlight_marker_item);
+
+					try {
+						// Cue up audio alert
+						String audio_dir = "/sdcard/";// currently all file
+						// String audio_dir = tippleActivity.audioDirectory;
+						File alert_file = new File(audio_dir,
+								"BeepMorseSonar.wav");
+						String alert_filename = alert_file.getAbsolutePath();
+
+						MediaPlayer mp = new MediaPlayer();
+						mp.setDataSource(alert_filename);
+						mp.prepare();
+						mp.start();
+					} catch (Exception e) {
+						System.err
+								.println("Failed to play audio alert for active GPS location");
+						e.printStackTrace();
+					}
+
+					// Now record the fact we've been here
+					prev_locations_.add(place);
+
+				}
+
+			}
+
+			else if (pixel_distance >= outside_pixel_distance) {
+
+				if (curr_locations_.contains(place)) {
+					curr_locations_.remove(place);
+					OverlayMarkerItem highlight_marker_item = highlight_marker_hash_
+							.remove(i);
+					highlight_marker_overlay_
+							.removeOverlay(highlight_marker_item);
+
+				}
+			}
+		}
+	}
+
+	public void onLocationChanged(Location loc) {
+
+		if (loc != null) {
+
+			System.err
+					.println("TipLocationListener::onLocationChaged -- start");
+			lastKnownLocation = loc;
+
+			if (getLock()) {
+				updateActiveLocations(loc);
+				freeLock();
+			}
+
+			DecimalFormat truncPlaces = new DecimalFormat("0.00000");
+			double longitude = loc.getLongitude();
+			double latitude = loc.getLatitude();
+
+			String trunc_long = truncPlaces.format(longitude);
+			String trunc_lat = truncPlaces.format(latitude);
+
+			String text_mess = "(Long,Lat): (" + trunc_long + "," + trunc_lat
+					+ ")";
+			text_view_.setText(text_mess);
+			// location aware
+			GeoPoint point = new GeoPoint(latitude, longitude);
+			// Use the following line if you want to map to auto center on the
+			// GPS location
+			boolean centre_on_gps_loc = tippleActivity.sharedPreferences
+					.getBoolean("centreOnGPSLoc", false);
+			if (centre_on_gps_loc) {
+				MapController map_controller = map_view_.getController();
+				if (map_controller != null) {
+					map_controller.setCenter(point);
+				}
+			}
+		}
+		// System.err.println("TipLocationListener::onLocationChaged -- finished");
+	}
+
+	@Override
+	public void onProviderDisabled(String provider) {
+		// TODO Auto-generated method stub
+		System.err.println("TipLocationListener::onProviderDisabled()");
+	}
+
+	@Override
+	public void onProviderEnabled(String provider) {
+		// TODO Auto-generated method stub
+		System.err.println("TipLocationListener::onProviderEnabled()");
+
+	}
+
+	@Override
+	public void onStatusChanged(String provider, int status, Bundle extras) {
+		// TODO Auto-generated method stub
+		System.err.println("TipLocationListener::onStatusChanged()");
+
+	}
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/tippleActivity.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/tippleActivity.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/tippleActivity.java	(revision 26526)
@@ -0,0 +1,609 @@
+package org.tipple.mapDisplay;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Locale;
+
+import org.mapsforge.android.maps.MapActivity;
+import org.mapsforge.android.maps.MapView;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.AssetManager;
+import android.graphics.drawable.Drawable;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.os.Bundle;
+import android.os.Environment;
+import android.preference.PreferenceManager;
+import android.speech.tts.TextToSpeech;
+import android.speech.tts.TextToSpeech.OnInitListener;
+import android.text.method.ScrollingMovementMethod;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.LinearLayout.LayoutParams;
+import android.widget.TextView;
+
+public class tippleActivity extends MapActivity implements OnInitListener {// OnSharedPreferenceChangeListener
+	enum TextAudioModeEnum {
+		TEXT_ONLY, TEXT_PLUS_AUDIO, AUDIO_ONLY, AUDIO_PLUS_TEXT
+	};
+
+	enum bookModeEnum {
+		BOOK_A, BOOK_B, BOOK_AB
+	};
+
+	// image loader
+	public ImageLoader loader;
+	public static TippleLog log;
+	public static bookModeEnum current_book_mode;
+	protected tippleActivity.bookModeEnum current_book_mode_;
+	// File storage to run on the emulator initially
+	public static String geodataDirectory = "/sdcard/";
+	public static String logDirectory = "/sdcard/";
+	public static String audioDirectory = "/sdcard/";
+	public static String imageDirectory = "/sdcard/";
+	// File storage to run on the real device
+	// public static String geodataDirectory;
+	// public static String logDirectory;
+	// public static String audioDirectory;
+
+	// Views
+	protected TextView longlat_view_;
+	protected MapView mapview;
+	protected TextView text_view_;
+	protected FrameLayout text_map_composite_;
+
+	protected ArrayList<tippleLocation> locations = null;
+	protected ArrayList<tippleLocation> user_trail_ = null;
+	protected String user_trail_filename_ = null;
+	protected TippleLocationManagerVersion2 tip_location_manager_,
+			my_location_manager;
+	// Preferences
+	public static SharedPreferences sharedPreferences;
+	public static boolean centreOnGPSLocation;
+	public static boolean showScaleBar;
+	public static boolean showSights;
+	public static boolean showUserTrail;
+	public static TextAudioModeEnum textAudioMode;
+	public static bookModeEnum bookMode;
+	public static boolean bookA;
+	public static boolean bookB;
+	public static String bookModeStr;
+	public static Boolean currentShowSights = false;
+	public static Boolean currentShowUserTrail = false;
+
+	// Text to Speech
+	protected TextToSpeech tts_ = null;
+	// Request codes
+	protected final int TTS_DATA_CHECK = 0;
+	private static final int SELECT_LOG_FILE = 1;
+
+	protected LocationListener mylocationListener = null;
+	public static Drawable highlightMarker1;
+	public static Drawable highlightMarker2;
+
+	// Text to Speech
+	private final String MY_DEBUG_TAG = "DL xml data retreive";
+	private static final long MINIMUM_DISTANCE_CHANGE_FOR_UPDATES = 1; // in
+																		// Meters
+	private static final long MINIMUM_TIME_BETWEEN_UPDATES = 1000; // in
+																	// miniseconds
+	protected AudioPlayerView audio_player_view_;
+	protected LocationManager locationManager;
+	protected Button retrieveLocationButton;
+	protected double currentLongitude;
+	protected double currentLantitude;
+	protected double currentNodeId;
+
+	/** Called when the activity is first created. */
+	@Override
+	public void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		// Set up logging
+		log = new TippleLog(this, logDirectory);
+		log.optStartLog();
+
+		refreshPreferences();
+		SharedPreferences.Editor editor = sharedPreferences.edit();
+		editor.putBoolean("showUserTrail", false);
+
+		// Set up Text to Speech
+		Intent checkIntent = new Intent();
+		checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
+		startActivityForResult(checkIntent, TTS_DATA_CHECK);
+
+		mapview = createMapView("/sdcard/hamilton.map");
+		// For running on the real phone,change all file to tipple-store
+		// and asset folder
+		// mapview = createMapViewFromAsset("hamilton.map");
+
+		longlat_view_ = createLongLatView();
+		LinearLayout linearLayout = new LinearLayout(this);
+		linearLayout.setOrientation(LinearLayout.VERTICAL);
+		text_view_ = createTextView();
+		text_map_composite_ = compositTextViewOnMapView(mapview, text_view_);
+		audio_player_view_ = createAudioPlayerView();
+
+		linearLayout.addView(longlat_view_);
+		linearLayout.addView(text_map_composite_);
+		linearLayout.addView(audio_player_view_);
+		setContentView(linearLayout);
+
+		// load image in background and store in sdcard
+		load(this);
+	}
+
+	protected void load(Activity activity) {
+
+		try {
+			for (int i = 0; i < ImageURL.URLS.length; i++) {
+				loader = new ImageLoader(activity);
+				loader.download(ImageURL.URLS[i]);
+			}
+		} catch (Exception ex) {
+			System.out.println("tippleActivity load... error loading");
+		}
+
+	}
+
+	protected boolean assetToExternalStorage(String asset_filename,
+			String external_storage_filename) {
+		boolean status = true;
+
+		try {
+
+			File external_storage_file = new File(external_storage_filename);
+			if (!external_storage_file.exists()) {
+				// Need to create the /sdcard version
+
+				AssetManager assetManager = getAssets();
+
+				InputStream ais = assetManager.open(asset_filename); // ais =
+																		// asset
+																		// input
+																		// stream
+				FileOutputStream fos = new FileOutputStream(
+						external_storage_file); // fos = file output stream
+
+				byte[] buffer = new byte[1024];
+
+				int buflen;
+				while ((buflen = ais.read(buffer)) > 0) {
+					fos.write(buffer, 0, buflen);
+				}
+
+				ais.close();
+				fos.close();
+			}
+
+		} catch (Exception e) {
+			e.printStackTrace();
+			status = false;
+		}
+
+		return status;
+	}
+
+	protected boolean initTippleStore(String location) {
+
+		// Locate map data directory
+		File external_root_file = Environment.getExternalStorageDirectory();
+		String external_root = external_root_file.getAbsolutePath();
+		String tipple_store_dir = external_root + "/tipple-store";
+
+		geodataDirectory = tipple_store_dir + "/geodata/";
+		// logDirectory = tipple_store_dir + "/logs/";
+		audioDirectory = tipple_store_dir + "/audio/";
+
+		File tipple_store_file = new File(tipple_store_dir);
+		if (!tipple_store_file.exists()) {
+			if (!tipple_store_file.mkdir()) {
+				System.err.println("Failed to create directory: "
+						+ tipple_store_dir);
+				return false;
+			}
+		}
+
+		File geodataDirFile = new File(geodataDirectory);
+		if (!geodataDirFile.exists()) {
+			if (!geodataDirFile.mkdir()) {
+				System.err.println("Failed to create directory: "
+						+ geodataDirectory);
+				return false;
+			}
+		}
+
+		File audioDirFile = new File(audioDirectory);
+		if (!audioDirFile.exists()) {
+			if (!audioDirFile.mkdir()) {
+				System.err.println("Failed to create directory: "
+						+ audioDirectory);
+				return false;
+			}
+		}
+
+		// dig out the audio files
+		String[] audio_filenames = { "BeepMorseSonar.wav", "Ding.wav",
+				"DingExtended.wav" };
+		for (String audio_filename : audio_filenames) {
+			String audio_asset_filename = "audio/" + audio_filename;
+			String audio_exstore_filename = audioDirectory + audio_filename;
+
+			if (!assetToExternalStorage(audio_asset_filename,
+					audio_exstore_filename)) {
+				System.err.println("Failed to transfer asset "
+						+ audio_asset_filename + " to "
+						+ audio_exstore_filename);
+				return false;
+			}
+		}
+
+		if ((location != null) && (!location.equals(""))) {
+			// get out map and XML location file
+
+			String map_asset_filename = "geodata/" + location + ".map";
+			String map_exstore_filename = geodataDirectory + location + ".map";
+
+			if (!assetToExternalStorage(map_asset_filename,
+					map_exstore_filename)) {
+				System.err.println("Failed to transfer asset "
+						+ map_asset_filename + " to " + map_exstore_filename);
+				return false;
+			}
+
+		}
+
+		return true;
+	}
+
+	protected boolean initTippleStore() {
+		return initTippleStore(null);
+	}
+
+	protected FrameLayout compositTextViewOnMapView(MapView map_view,
+			TextView text_view) {
+		FrameLayout frame_layout = new FrameLayout(this);
+
+		LayoutParams view_layout = new LinearLayout.LayoutParams(
+				ViewGroup.LayoutParams.WRAP_CONTENT,
+				ViewGroup.LayoutParams.WRAP_CONTENT, 1);
+
+		frame_layout.setLayoutParams(view_layout);
+		frame_layout.addView(map_view);
+		frame_layout.addView(text_view);
+
+		return frame_layout;
+	}
+
+	protected TextView createLongLatView() {
+		// Lat,Long line at top
+		TextView longlat_view = new TextView(this);
+		longlat_view.setText("(Long,Lat): ");
+
+		LayoutParams longlat_view_layout = new LinearLayout.LayoutParams(
+				ViewGroup.LayoutParams.MATCH_PARENT, 35, 0);
+		longlat_view.setLayoutParams(longlat_view_layout);
+
+		return longlat_view;
+	}
+
+	protected TextView createTextView() {
+		// Text view in middle (ultimately on top of map view)
+		TextView text_view = new TextView(this);
+
+		LayoutParams text_view_layout = new LinearLayout.LayoutParams(
+				ViewGroup.LayoutParams.MATCH_PARENT,
+				ViewGroup.LayoutParams.WRAP_CONTENT, 1);
+		text_view.setLayoutParams(text_view_layout);
+
+		text_view.setGravity(Gravity.BOTTOM | Gravity.FILL_HORIZONTAL);
+
+		text_view.setPadding(12, 12, 12, 12);
+		text_view.setTextColor(0xffffffff);
+		text_view.setBackgroundColor(0xCC000000);
+		text_view.setTextSize(20.0f);
+
+		text_view.setVerticalScrollBarEnabled(true);
+		text_view.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
+
+		text_view.setMovementMethod(new ScrollingMovementMethod());
+
+		text_view.setVisibility(View.INVISIBLE);
+
+		return text_view;
+	}
+
+	protected MapView createMapView(String map_filename) {
+		// Map view in middle
+		MapView mapview = new MapView(this);
+		mapview.setClickable(true);
+		mapview.setBuiltInZoomControls(true);
+		// String full_map_filename = geodataDirectory + map_filename;
+		// mapview.setMapFile(full_map_filename);
+		mapview.setMapFile(map_filename);
+		LayoutParams map_view_layout = new LinearLayout.LayoutParams(
+				ViewGroup.LayoutParams.WRAP_CONTENT,
+				ViewGroup.LayoutParams.WRAP_CONTENT, 1);
+		mapview.setLayoutParams(map_view_layout);
+		return mapview;
+
+	}
+
+	protected MapView createMapViewFromAsset(String map_filename) {
+		// Transfer asset to file in dataDirectory if it does not already exist
+		String asset_filename = "geodata" + File.separator + map_filename;
+		String external_storage_filename = geodataDirectory + map_filename;
+
+		assetToExternalStorage(asset_filename, external_storage_filename);
+
+		return createMapView(map_filename);
+
+	}
+
+	protected AudioPlayerView createAudioPlayerView() {
+		// Player at the bottom
+		AudioPlayerView audio_player_view = new AudioPlayerView(this,
+				text_view_);
+
+		LayoutParams audio_player_layout = new LinearLayout.LayoutParams(
+				ViewGroup.LayoutParams.MATCH_PARENT, 100, 0);
+		audio_player_view.setLayoutParams(audio_player_layout);
+
+		return audio_player_view;
+	}
+
+	protected void refreshPreferences() {
+		// Restore preferences
+		sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
+
+		showScaleBar = sharedPreferences.getBoolean("showScaleBar", false);
+		centreOnGPSLocation = sharedPreferences.getBoolean("centreOnGPSLoc",
+				false);
+
+		showSights = sharedPreferences.getBoolean("showSights", true);
+		showUserTrail = sharedPreferences.getBoolean("showUserTrail", false);
+
+		String textAudioModeStr = sharedPreferences.getString("textAudioMode",
+				"AUDIO_PLUS_TEXT");
+		textAudioMode = Enum.valueOf(TextAudioModeEnum.class, textAudioModeStr);
+
+		// change book selection from radio button to check box
+		bookA = sharedPreferences.getBoolean("showBookA", false);
+		bookB = sharedPreferences.getBoolean("showBookB", false);
+
+		if (bookA) {
+			if (!bookB)
+				bookModeStr = "BOOK_A";
+			else
+				bookModeStr = "BOOK_AB";
+		} else {
+			if (!bookB)
+				bookModeStr = "BOOK_B";// by default, show one books
+			else
+				bookModeStr = "BOOK_B";
+
+		}
+
+		bookMode = Enum.valueOf(bookModeEnum.class, bookModeStr);
+	}
+
+	protected void displayLocationOnMap() {
+		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
+		tip_location_manager_ = new TippleLocationManagerVersion2(this,
+				mapview, longlat_view_, locationManager, audio_player_view_,
+				tts_);
+
+	}
+
+	Boolean isActive = true;
+	Boolean showPath = true;
+
+	@Override
+	protected void onResume() {
+		System.err.println("*** TippleActivity::onResume()");
+		super.onResume();
+		refreshPreferences();
+		audio_player_view_.refreshView();// try this way can we get locations
+		mapview.setScaleBar(showScaleBar);
+		if (tip_location_manager_ != null) {
+			refreshMapView();
+
+		}
+
+	}
+
+	@Override
+	protected void onStop() {
+		System.err.println("*** TippleActivity::onStop()");
+		super.onStop();
+
+		SharedPreferences.Editor editor = sharedPreferences.edit();
+		editor.commit();
+
+	}
+
+	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+		System.err
+				.println("*** TippleActivity::onActivityResult(), requestCode: "
+						+ requestCode);
+
+		if (requestCode == TTS_DATA_CHECK) {
+			if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
+				// success, create the TTS instance
+				tts_ = new TextToSpeech(this,
+						(TextToSpeech.OnInitListener) this);
+				tts_.setLanguage(Locale.UK);
+				displayLocationOnMap();
+				load(this);
+
+			} else {
+				// missing data, install it
+				Intent installIntent = new Intent();
+				installIntent
+						.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
+				startActivity(installIntent);
+			}
+		}
+
+		else if (requestCode == SELECT_LOG_FILE) {
+
+		}
+
+	}
+
+	public void onInit(int status) {
+		System.err
+				.println("*** TippleActivity::onInit(), status (zero == good): "
+						+ status);
+
+		if (status == TextToSpeech.SUCCESS) {
+			Log.d("TippleActivity::onInit()",
+					"Text-to-speech engine initialized");
+		} else if (status == TextToSpeech.ERROR) {
+			Log.e("TippleActivity::onInit()",
+					"Text-to-speech engine failed initialized");
+			System.err
+					.println("Error occured while initializing text-to-speech engine");
+		}
+
+	}
+
+	protected void onDestroy() {
+		System.err.println("*** TippleActivity::onDestroy()");
+		super.onDestroy();
+
+		tts_.shutdown();
+		tts_ = null;
+
+		// Switch off location updates
+		if (locationManager != null) {
+
+			if (mylocationListener != null) {
+
+				locationManager.removeUpdates(mylocationListener);
+				mylocationListener = null;
+			}
+			mylocationListener = null;
+
+		}
+
+		tip_location_manager_.stopOverlayThreads();
+
+	}
+
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu) {
+		getMenuInflater().inflate(R.menu.options_menu, menu);
+		return true;
+	}
+
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item) {
+		switch (item.getItemId()) {
+
+		case R.id.menu_preferences:
+			startActivity(new Intent(this, EditPreferences.class));
+			return true;
+
+		default:
+			return false;
+		}
+	}
+
+	// @Override
+	public void refreshMapView() {
+
+		if (current_book_mode_ != tippleActivity.bookMode) {
+			// book mode has beeen changed
+			tip_location_manager_.resetOverlayThreads();// reset overlay item
+			System.out.println("Clear all arraylist");
+			if (tippleActivity.bookMode == tippleActivity.bookModeEnum.BOOK_A) {
+
+				locations = tip_location_manager_.loadTour(true);
+
+			}
+
+			else if (tippleActivity.bookMode == tippleActivity.bookModeEnum.BOOK_B) {
+				locations = tip_location_manager_.loadTour(false);
+
+			} else if (tippleActivity.bookMode == tippleActivity.bookModeEnum.BOOK_AB) {
+				locations = tip_location_manager_.loadTourDescription();
+
+			}
+			current_book_mode_ = bookMode;
+			displayLocationOnMapDynamically(locations);
+
+		}
+		showTour();
+		System.out.println("refreshMapView when mode not changed ");
+	}
+
+	protected void displayLocationOnMapDynamically(
+			ArrayList<tippleLocation> locations) {
+
+		if (mylocationListener != null) {
+			((locationListener) mylocationListener)
+					.resetOverlayThreadsOnListener();
+			locationManager.removeUpdates(mylocationListener);
+
+		}
+		mylocationListener = null;
+		System.gc();
+		audio_player_view_.resetAudioView();
+		audio_player_view_.refreshView();
+
+		tip_location_manager_.createTourLocationsOverlay(mapview, locations);
+		mylocationListener = new locationListener(this, mapview, longlat_view_,
+				locationManager, tip_location_manager_, locations);
+		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
+				MINIMUM_TIME_BETWEEN_UPDATES,
+				MINIMUM_DISTANCE_CHANGE_FOR_UPDATES, mylocationListener);
+		System.out.println("displayLocationOnmapDy created listener");
+
+		if (showSights) {
+			if (showUserTrail)
+				tip_location_manager_.addTourLocations(mapview, true);
+			else {
+				tip_location_manager_.resetRouteOverlay();
+				tip_location_manager_.addTourLocations(mapview, false);
+			}
+		} else {
+			tip_location_manager_.removeTourLocations(mapview);
+		}
+
+	}
+
+	/*
+	 * when showSignts or showUserTrail has been changed will call this method
+	 */
+	protected void showTour() {
+		if ((currentShowSights != showSights)
+				|| (currentShowUserTrail != showUserTrail)) {
+			if (showSights) {
+				if (showUserTrail)
+					tip_location_manager_.addTourLocations(mapview, true);
+				else {
+					tip_location_manager_.resetRouteOverlay();
+					tip_location_manager_.addTourLocations(mapview, false);
+				}
+			} else {
+				tip_location_manager_.removeTourLocations(mapview);
+			}
+			currentShowSights = showSights;
+			currentShowUserTrail = showUserTrail;
+		}
+	}
+
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/tippleLocation.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/tippleLocation.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/tippleLocation.java	(revision 26526)
@@ -0,0 +1,166 @@
+package org.tipple.mapDisplay;
+
+import java.util.HashMap;
+import java.util.List;
+
+public class tippleLocation {
+	private double radius = 0.0;
+
+	private double longitude = 0.0;
+
+	private String text = null;
+
+	private double latitude = 0.0;
+
+	private String title = null;
+
+	private String nodeID = null;
+	private String tts_text_ = null;
+
+	protected String id_ = null;
+
+	private String audioFilename = null;
+	private List<String> audioPaths;
+	private String chapter = null;
+
+	public tippleLocation() {
+
+	}
+
+	public tippleLocation(String title, double radius, double longitude,
+			double latitude, String content, String tts, String chapter) {
+		this.radius = radius;
+		this.longitude = longitude;
+		this.title = title;
+		this.latitude = latitude;
+		this.text = content;
+		this.tts_text_ = tts;
+		this.chapter = chapter;
+
+	}
+
+	public tippleLocation(HashMap<String, String> hashmap) {
+		latitude = Double.parseDouble(hashmap.get("Latitude"));
+		longitude = Double.parseDouble(hashmap.get("Longitude"));
+		radius = Double.parseDouble(hashmap.get("Radius"));
+		nodeID = hashmap.containsKey("nodeID") ? hashmap.get("nodeID") : null;
+		title = hashmap.containsKey("Title") ? hashmap.get("Title") : null;
+		text = (hashmap.containsKey("text")) ? hashmap.get("text") : null;
+		tts_text_ = (hashmap.containsKey("tts")) ? hashmap.get("tts") : null;
+		chapter = (hashmap.containsKey("Chapter")) ? hashmap.get("Chapter")
+				: null;
+		audioFilename = (hashmap.containsKey("audio")) ? hashmap.get("audio")
+				: null;
+		// Consolidate whitespace
+		title = title.replaceAll("^\\s+", "");
+		title = title.replaceAll("\\s+$", "");
+		title = title.replaceAll("\\s+", " ");
+		if (text != null) {
+			text = text.replaceAll("^\\s+", "");
+			text = text.replaceAll("\\s+$", "");
+			text = text.replaceAll("\\s+", " ");
+		}
+		chapter = chapter.replaceAll("^\\s+", "");
+		chapter = chapter.replaceAll("\\s+$", "");
+		chapter = chapter.replaceAll("\\s+", " ");
+		id_ = title.replaceAll("/\\s+/", "-");
+
+	}
+
+	public String getChapter() {
+		return chapter;
+	}
+
+	public List<String> getAudio() {
+		return audioPaths;
+	}
+
+	public String getAudioFilename() {
+		return audioFilename;
+	}
+
+	public String getID() {
+		return id_;
+	}
+
+	public String getNodeID() {
+
+		return nodeID;
+	}
+
+	public void setNodeID(String nodeID) {
+
+		this.nodeID = nodeID;
+	}
+
+	public String getTitle() {
+		return title;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	public double getlongitude() {
+		return longitude;
+	}
+
+	public void setlongitude(double longitude) {
+		this.longitude = longitude;
+	}
+
+	public double getradius() {
+		return radius;
+	}
+
+	public void setradius(double radius) {
+		this.radius = radius;
+	}
+
+	public double getlatitude() {
+		return latitude;
+	}
+
+	public void setlatitude(double latitude) {
+		this.latitude = latitude;
+	}
+
+	public String getContent() {
+
+		return text;
+	}
+
+	public void setContent(String content) {
+
+		this.text = content;
+	}
+
+	public String getTTSText() {
+		return (tts_text_ != null) ? tts_text_ : text;
+	}
+
+	public String toString() {
+
+		StringBuffer sb = new StringBuffer();
+		sb.append("TippleLocation Details - ");
+		sb.append("Title:" + getTitle());
+		sb.append(", ");
+		sb.append("latitude:" + getlatitude());
+		sb.append(", ");
+		sb.append("longitude:" + getlongitude());
+		sb.append(",");
+		sb.append("Radius" + getradius());
+		sb.append(".");
+		sb.append("nodeID:" + getNodeID());
+		sb.append(", ");
+
+		return sb.toString();
+
+		/*
+		 * return "TippleLocation Details - " + "Title:" + getTitle() +
+		 * "latitude:" + getlatitude() + "Radius" + getradius();
+		 */
+
+	}
+
+}
Index: /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/xmlHandler.java
===================================================================
--- /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/xmlHandler.java	(revision 26526)
+++ /other-projects/tipple-android/tipple-casey/src/org/tipple/mapDisplay/xmlHandler.java	(revision 26526)
@@ -0,0 +1,105 @@
+package org.tipple.mapDisplay;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class xmlHandler extends DefaultHandler {
+	String lockon_element;
+	Boolean locked_on_;
+	ArrayList<HashMap<String, String>> lockon_list;
+	HashMap<String, String> hashmap;
+	String active_element;
+	StringBuffer inner_text;
+	String active_attr;
+	Boolean recordElement;
+	String elementType;
+
+	// ===========================================================
+	// Getter & Setter
+	// ===========================================================
+	public xmlHandler(String lockon_element) {
+		// initial settings to parse a file
+		this.lockon_element = lockon_element;
+		lockon_list = new ArrayList<HashMap<String, String>>();
+		locked_on_ = false;
+		recordElement = false;
+		elementType = "";
+		hashmap = new HashMap<String, String>();
+	}
+
+	public ArrayList<HashMap<String, String>> getHashmapList() {
+		return lockon_list;
+	}
+
+	/**
+	 * Gets be called on opening tags like: <tag> Can provide attribute(s), when
+	 * xml was like: <tag attribute="attributeValue">
+	 */
+
+	public void startElement(String namespaceURI, String localName,
+			String qName, Attributes atts) throws SAXException {
+
+		if ((localName.equalsIgnoreCase(lockon_element))
+				&& (atts.getValue("nodeType")).equalsIgnoreCase("leaf")) {
+
+			hashmap = new HashMap<String, String>();
+			locked_on_ = true; // => covert each child element inside this to a
+			String attrValueNode = atts.getValue("nodeID");
+			hashmap.put("nodeID", attrValueNode);
+
+		} else if (locked_on_) {
+			if (localName.equalsIgnoreCase("metadata")
+					|| localName.equalsIgnoreCase("nodeContent")) {
+				recordElement = true;
+				inner_text = new StringBuffer();
+				if (localName.equalsIgnoreCase("metadata")) {
+					active_element = atts.getValue("name");
+
+				} else if (localName.equalsIgnoreCase("nodeContent")) {
+					active_element = "text";
+
+				}
+			}
+
+		}
+		// else ignore element as outside area of interest
+	}
+
+	/**
+	 * Gets be called on closing tags like: </tag>
+	 */
+	public void endElement(String namespaceURI, String localName, String qName)
+			throws SAXException {
+		if (localName.equalsIgnoreCase(lockon_element)) {
+			// push hashmap onto arraylist
+			lockon_list.add(hashmap);
+			hashmap = null;
+			locked_on_ = false;
+		} else if ((localName.equalsIgnoreCase("metadata"))
+				|| (localName.equalsIgnoreCase("nodeContent"))) {
+			active_element = null;
+			inner_text = null;
+			recordElement = false;
+
+		}
+
+	}
+
+	/**
+	 * Gets be called on the following structure: <tag>characters</tag>
+	 */
+
+	public void characters(char ch[], int start, int length) {
+		if (this.recordElement) {
+			String text = new String(ch, start, length);
+			inner_text.append(text);
+			hashmap.put(active_element, inner_text.toString());
+
+		}
+	}
+
+}
