new download manager \o/ hedgeroid
authorXeli
Thu, 24 Nov 2011 13:44:30 +0100
branchhedgeroid
changeset 6350 41b0a9955c47
parent 6348 162fec525764
child 6415 af2047bb4f70
child 7855 ddcdedd3330b
new download manager \o/
project_files/Android-build/SDL-android-project/AndroidManifest.xml
project_files/Android-build/SDL-android-project/res/drawable-mdpi/arrow.png
project_files/Android-build/SDL-android-project/res/drawable-mdpi/box.9.png
project_files/Android-build/SDL-android-project/res/drawable-mdpi/box_dark.9.png
project_files/Android-build/SDL-android-project/res/layout/download.xml
project_files/Android-build/SDL-android-project/res/layout/download_confirmdialog.xml
project_files/Android-build/SDL-android-project/res/layout/download_info.xml
project_files/Android-build/SDL-android-project/res/layout/download_listactivity.xml
project_files/Android-build/SDL-android-project/res/layout/download_progress.xml
project_files/Android-build/SDL-android-project/res/layout/spinner_textimg_dropdown_entry.xml
project_files/Android-build/SDL-android-project/res/layout/team_creation.xml
project_files/Android-build/SDL-android-project/res/raw/team_one.xml
project_files/Android-build/SDL-android-project/res/raw/team_two.xml
project_files/Android-build/SDL-android-project/res/values/strings.xml
project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadActivity.java
project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAssets.java
project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAsyncTask.java
project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadDialogFragment.java
project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadFragment.java
project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListActivity.java
project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListFragment.java
project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadPackage.java
project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadService.java
project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadTask.java
project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/FrontendDataUtils.java
project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MainActivity.java
project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java
project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/StartGameActivity.java
project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamCreatorActivity.java
project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Utils.java
--- a/project_files/Android-build/SDL-android-project/AndroidManifest.xml	Thu Nov 24 13:40:17 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/AndroidManifest.xml	Thu Nov 24 13:44:30 2011 +0100
@@ -22,15 +22,15 @@
 		  android:screenOrientation='landscape'>
         </activity>
         
-        <activity android:name=".Downloader.DownloadActivity"
+        <activity android:name=".Downloader.DownloadFragment"
                   android:label="@string/app_name"
-				  android:theme="@android:style/Theme.Dialog"
- 		  		  android:launchMode="singleTask">
+				  android:theme="@android:style/Theme.Dialog">
         </activity>
         
         <activity android:name=".Downloader.DownloadListActivity"
                   android:label="@string/app_name"
-				  android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
+				  android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+				  android:screenOrientation='landscape'>
         </activity>
         
         <service android:name=".Downloader.DownloadService"/>
Binary file project_files/Android-build/SDL-android-project/res/drawable-mdpi/arrow.png has changed
Binary file project_files/Android-build/SDL-android-project/res/drawable-mdpi/box.9.png has changed
Binary file project_files/Android-build/SDL-android-project/res/drawable-mdpi/box_dark.9.png has changed
--- a/project_files/Android-build/SDL-android-project/res/layout/download.xml	Thu Nov 24 13:40:17 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-	android:id="@+id/container"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:padding="5dp">
-    <ProgressBar
-    	android:id="@+id/progressbar"
-    	android:layout_width="wrap_content"
-    	android:layout_height="wrap_content"
-    	android:layout_alignLeft="@+id/background"
-    	android:layout_alignRight="@+id/cancelDownload"
-    	android:progressDrawable="@android:drawable/progress_horizontal"
-		android:indeterminate="false" android:indeterminateOnly="false"/>
-	<TextView
-    	android:id="@+id/progressbar_sub"
-    	android:layout_width="wrap_content"
-    	android:layout_height="wrap_content"
-    	android:layout_below="@id/progressbar"
-    	android:layout_alignLeft="@+id/background"
-    	android:layout_alignRight="@+id/cancelDownload"
-    	android:text="@string/notification_title"
-    	android:textColor="#FFF"
-    	android:textSize="14dp"/> 	
-    <Button
-    	android:id="@id/background"
-    	android:layout_width="wrap_content"
-    	android:layout_height="wrap_content"
-    	android:layout_below="@id/progressbar_sub"
-    	android:text="@string/download_background"/>
-    <Button
-    	android:id="@+id/cancelDownload"
-    	android:layout_width="wrap_content"
-    	android:layout_height="wrap_content"
-    	android:layout_below="@id/progressbar_sub"
-    	android:layout_toRightOf="@id/background"
-    	android:text="@string/download_cancel"/>
-    	
-</RelativeLayout>
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/res/layout/download_confirmdialog.xml	Thu Nov 24 13:44:30 2011 +0100
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="match_parent"
+    android:padding="5dip">
+  	<TextView 
+      	android:id="@+id/text"
+       	android:layout_width="200dip"
+       	android:layout_height="wrap_content"
+       	android:padding="5dip"
+       	android:gravity="center"
+       	android:maxWidth="200dip"/>
+
+	<LinearLayout
+	    android:layout_width="match_parent"
+	    android:layout_height="wrap_content"
+	    android:layout_below="@+id/text"
+	    android:layout_alignLeft="@id/text"
+	    android:layout_alignRight="@id/text"
+	    android:orientation="horizontal"
+	    android:gravity="center">
+
+	    <Button
+	        android:id="@+id/yes"
+	        android:layout_width="match_parent"
+	        android:layout_height="match_parent"
+	        android:layout_weight="1"
+	        android:text="@android:string/yes" />
+
+	    <Button
+	        android:id="@+id/no"
+	        android:layout_width="match_parent"
+	        android:layout_height="match_parent"
+	        android:layout_weight="1"
+	        android:text="@android:string/no" />
+	</LinearLayout>
+   	
+</RelativeLayout>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/res/layout/download_info.xml	Thu Nov 24 13:44:30 2011 +0100
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal"
+    android:gravity="center_vertical">
+    <ImageView
+        android:id="@+id/arrow"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="8"
+        android:src="@drawable/arrow"
+        android:adjustViewBounds="true"/>
+    
+    <RelativeLayout
+        android:id="@+id/container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:gravity="center"
+        android:background="@drawable/box_dark">        
+        <TextView
+            android:id="@+id/text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="This package will higher quality sounds better sounds"/>
+        
+        <Button 
+            android:id="@+id/download"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignLeft="@id/text"
+            android:layout_below="@id/text"
+            android:text="@string/download_downloadnow"/>        
+        <Button 
+            android:id="@+id/cancel"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignRight="@id/text"
+            android:layout_below="@id/text"
+            android:text="@android:string/no"/>
+            
+    </RelativeLayout>
+    
+
+</LinearLayout>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/res/layout/download_listactivity.xml	Thu Nov 24 13:44:30 2011 +0100
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    
+   <include layout="@layout/background"/>
+    
+	<LinearLayout 
+	    android:layout_width="match_parent"
+	    android:layout_height="match_parent"
+	    android:orientation="horizontal"
+	    android:background="@android:color/transparent">	    
+	    <fragment class="org.hedgewars.hedgeroid.Downloader.DownloadListFragment"
+	        android:id="@+id/downloadList"
+	        android:layout_width="match_parent"
+	        android:layout_height="match_parent"
+	        android:layout_weight="1"/>
+	    
+	    <FrameLayout 
+	        android:id="@+id/downloadFrameLayout"
+	        android:layout_width="match_parent"
+	        android:layout_height="match_parent"
+	        android:layout_weight="1"
+	        android:background="@android:color/transparent">
+	        
+	        <ScrollView
+	            android:layout_width="match_parent"
+	        	android:layout_height="match_parent">
+	            
+	            <LinearLayout
+	                android:id="@+id/downloadQueueContainer"
+	                android:layout_width="match_parent"
+	        		android:layout_height="match_parent"
+	        		android:orientation="vertical"/>	        		
+	        </ScrollView>
+	    </FrameLayout>
+	
+	</LinearLayout>
+</FrameLayout>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/res/layout/download_progress.xml	Thu Nov 24 13:44:30 2011 +0100
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:id="@+id/container"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:padding="5dp"
+    android:background="@drawable/box">
+    <ProgressBar
+    	android:id="@+id/progressbar"
+    	android:layout_width="wrap_content"
+    	android:layout_height="wrap_content"
+    	android:layout_alignLeft="@+id/background"
+    	android:layout_alignRight="@+id/cancelDownload"
+    	android:progressDrawable="@android:drawable/progress_horizontal"
+		android:indeterminate="false" 
+		android:indeterminateOnly="false"/>
+	<TextView
+    	android:id="@+id/progressbar_sub"
+    	android:layout_width="wrap_content"
+    	android:layout_height="wrap_content"
+    	android:layout_below="@id/progressbar"
+    	android:layout_alignLeft="@+id/background"
+    	android:layout_alignRight="@+id/cancelDownload"
+    	android:text="@string/download_queued"
+    	android:textColor="#FFF"
+    	android:textSize="14dp"
+    	android:gravity="center"/> 	
+    <Button
+    	android:id="@id/background"
+    	android:layout_width="wrap_content"
+    	android:layout_height="wrap_content"
+    	android:layout_below="@id/progressbar_sub"
+    	android:text="@string/download_background"/>
+    <Button
+    	android:id="@+id/cancelDownload"
+    	android:layout_width="wrap_content"
+    	android:layout_height="wrap_content"
+    	android:layout_below="@id/progressbar_sub"
+    	android:layout_toRightOf="@id/background"
+    	android:text="@string/download_cancel"/>
+    	
+</RelativeLayout>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/res/layout/spinner_textimg_dropdown_entry.xml	Thu Nov 24 13:44:30 2011 +0100
@@ -0,0 +1,22 @@
+<?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:gravity="center">
+	<ImageView
+		android:id="@+id/spinner_img"
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:layout_gravity="center"
+		android:adjustViewBounds="true"
+		android:scaleType="centerInside"
+		android:layout_marginRight="5dip"
+		/>
+	<TextView
+		android:id="@+id/spinner_txt"
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:textSize="14dip"
+		android:textColor="#000"
+		android:gravity="center"/>
+</LinearLayout>
\ No newline at end of file
--- a/project_files/Android-build/SDL-android-project/res/layout/team_creation.xml	Thu Nov 24 13:40:17 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/res/layout/team_creation.xml	Thu Nov 24 13:44:30 2011 +0100
@@ -70,7 +70,7 @@
 			  			android:text="@string/grave"/>
 			  		<Spinner
 			  			android:id="@id/spinGrave"
-			  			android:layout_width="fill_parent"
+			  			android:layout_width="wrap_content"
 			  			android:layout_height="wrap_content"
 			  			android:layout_marginLeft="3dip"
 			  			android:background="@drawable/dropdown"/>
--- a/project_files/Android-build/SDL-android-project/res/raw/team_one.xml	Thu Nov 24 13:40:17 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/res/raw/team_one.xml	Thu Nov 24 13:44:30 2011 +0100
@@ -1,49 +1,49 @@
 <?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
 <team>
   <name>Team 1</name>
-  <flag>cm_cog</flag>
-  <fort>Cake</fort>
-  <grave>coffin</grave>
+  <flag>hedgewars</flag>
+  <fort>Lego</fort>
+  <grave>Bone</grave>
   <voice>Classic</voice>
   <hash>0</hash>
   <hog>
     <name>Leonidas</name>
-    <hat>spartan</hat>
+    <hat>NoHat</hat>
     <level>0</level>
   </hog>
   <hog>
     <name>Pipo</name>
-    <hat>clown-copper</hat>
+    <hat>NoHat</hat>
     <level>0</level>
   </hog>
   <hog>
     <name>Sonic</name>
-    <hat>Sonic</hat>
+    <hat>NoHat</hat>
     <level>0</level>
   </hog>
   <hog>
     <name>Xin</name>
-    <hat>StrawHat</hat>
+    <hat>NoHat</hat>
     <level>0</level>
   </hog>
   <hog>
     <name>Arnold</name>
-    <hat>cyborg</hat>
+    <hat>NoHat</hat>
     <level>0</level>
   </hog>
   <hog>
     <name>Jack</name>
-    <hat>Pumpkin_Hat</hat>
+    <hat>NoHat</hat>
     <level>0</level>
   </hog>
   <hog>
     <name>Tom</name>
-    <hat>Samurai</hat>
+    <hat>NoHat</hat>
     <level>0</level>
   </hog>
   <hog>
     <name>Goldie</name>
-    <hat>diglett</hat>
+    <hat>NoHat</hat>
     <level>0</level>
   </hog>
 </team>
\ No newline at end of file
--- a/project_files/Android-build/SDL-android-project/res/raw/team_two.xml	Thu Nov 24 13:40:17 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/res/raw/team_two.xml	Thu Nov 24 13:44:30 2011 +0100
@@ -1,49 +1,49 @@
 <?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
 <team>
   <name>Team 2</name>
-  <flag>cm_42</flag>
-  <fort>Plane</fort>
-  <grave>pyramid</grave>
-  <voice>Singer</voice>
+  <flag>hedgewars</flag>
+  <fort>Lego</fort>
+  <grave>Bone</grave>
+  <voice>Classic</voice>
   <hash>0</hash>
   <hog>
     <name>Paris</name>
-    <hat>pinksunhat</hat>
-    <level>3</level>
+    <hat>NoHat</hat>
+    <level>0</level>
   </hog>
   <hog>
     <name>Knut</name>
-    <hat>sth_Knux</hat>
-    <level>3</level>
+    <hat>NoHat</hat>
+    <level>0</level>
   </hog>
   <hog>
     <name>Ash</name>
-    <hat>RedCap</hat>
-    <level>3</level>
+    <hat>NoHat</hat>
+    <level>0</level>
   </hog>
   <hog>
     <name>Woad</name>
-    <hat>Toad</hat>
-    <level>3</level>
+    <hat>NoHat</hat>
+    <level>0</level>
   </hog>
   <hog>
     <name>Bob</name>
-    <hat>rasta</hat>
-    <level>3</level>
+    <hat>NoHat</hat>
+    <level>0</level>
   </hog>
   <hog>
     <name>Corky</name>
-    <hat>porkey</hat>
-    <level>3</level>
+    <hat>NoHat</hat>
+    <level>0</level>
   </hog>
   <hog>
     <name>Bea</name>
-    <hat>crown</hat>
-    <level>3</level>
+    <hat>NoHat</hat>
+    <level>0</level>
   </hog>
   <hog>
     <name>Silvia</name>
-    <hat>Rambo</hat>
-    <level>3</level>
+    <hat>NoHat</hat>
+    <level>0</level>
   </hog>
 </team>
\ No newline at end of file
--- a/project_files/Android-build/SDL-android-project/res/values/strings.xml	Thu Nov 24 13:40:17 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/res/values/strings.xml	Thu Nov 24 13:44:30 2011 +0100
@@ -12,7 +12,7 @@
         
     <!-- Notification -->
     <string name="notification_title">Downloading hedgewars files...</string>
-    <string name="notification_done">Success - Download complete</string>
+    <string name="notification_done">Successfully downloaded: </string>
     
     <!-- Download Activity -->
     <string name="download_background">Continue in background</string>
@@ -23,6 +23,12 @@
     <string name="download_failed">The download has failed, check the internet connectivity and please try again</string>
     <string name="download_userexplain">Before starting the game we must download some extra files...</string>
     
+    <string name="download_areyousure">Are you sure you want to download this package?</string>
+    <string name="download_alreadydownloaded">You\'ve already downloaded this package, are you sure you want to download it again?</string>
+    <string name="download_downloadnow">Download now!</string>
+    
+    <string name="download_queued">This download has been queued</string>
+    
     <!-- start game -->
     
     <string name="start_gameplay">Style</string>
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadActivity.java	Thu Nov 24 13:40:17 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,178 +0,0 @@
-/*
- * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
- * Copyright (c) 2011 Richard Deurwaarder <xeli@xelification.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-
-package org.hedgewars.hedgeroid.Downloader;
-
-import org.hedgewars.hedgeroid.MainActivity;
-import org.hedgewars.hedgeroid.R;
-
-import android.app.Activity;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-public class DownloadActivity extends Activity{
-	private Messenger messageService;
-	private boolean boundToService = false;
-	
-	private TextView progress_sub;
-	private ProgressBar progress;
-	private Button positive, negative;
-	
-	public static final int MSG_START = 0;
-	public static final int MSG_UPDATE = 1;
-	public static final int MSG_DONE = 2;
-	public static final int MSG_FAILED = 3;
-	private Handler.Callback messageCallback = new Handler.Callback() {
-		
-		public boolean handleMessage(Message msg) {
-			switch(msg.what){
-			case MSG_START:
-				progress.setMax(msg.arg1);
-				progress_sub.setText(String.format("%dkb/%dkb\n%s", 0, msg.arg1, ""));
-				positive.setText(R.string.download_background);
-				positive.setOnClickListener(backgroundClicker);
-				negative.setText(R.string.download_cancel);
-				negative.setOnClickListener(cancelClicker);
-				break;
-			case MSG_UPDATE:
-				progress_sub.setText(String.format("%d%% - %dkb/%dkb\n%s",(msg.arg1*100)/msg.arg2, msg.arg1, msg.arg2, msg.obj));
-				progress.setProgress(msg.arg1);
-				break;
-			case MSG_DONE:
-				progress.setProgress(progress.getMax());
-				progress_sub.setText(R.string.download_done);
-				
-				positive.setText(R.string.download_back);
-				positive.setOnClickListener(doneClicker);
-				
-				negative.setVisibility(View.INVISIBLE);
-				break;
-			case MSG_FAILED:
-				progress.setProgress(progress.getMax());
-				progress_sub.setText(R.string.download_failed);
-				positive.setText(R.string.download_back);
-				positive.setOnClickListener(doneClicker);
-				
-				negative.setText(R.string.download_tryagain);
-				negative.setOnClickListener(tryAgainClicker);
-				break;
-			}
-			return false;
-		}
-	};
-	private Handler messageHandler = new Handler(messageCallback);
-	private Messenger messenger = new Messenger(messageHandler);
-	
-	public void onCreate(Bundle savedInstanceState){
-		super.onCreate(savedInstanceState);
-		setContentView(R.layout.download);
-		
-		progress_sub = (TextView)findViewById(R.id.progressbar_sub);
-		progress = (ProgressBar)findViewById(R.id.progressbar);
-		
-		positive = (Button) findViewById(R.id.background);
-		negative = (Button) findViewById(R.id.cancelDownload);
-		positive.setOnClickListener(backgroundClicker);
-		negative.setOnClickListener(cancelClicker);
-		
-	}
-	
-	private OnClickListener backgroundClicker = new OnClickListener(){
-		public void onClick(View v){
-			finish();
-		}
-	};
-	private OnClickListener cancelClicker = new OnClickListener(){
-		public void onClick(View v){
-			Intent i = new Intent(getApplicationContext(), DownloadService.class);
-			i.putExtra(DownloadService.INTENT_TASKID, DownloadService.TASKID_CANCEL);
-			startService(i);
-			finish();
-		}
-	};
-	private OnClickListener doneClicker = new OnClickListener(){
-		public void onClick(View v){
-			finish();
-			startActivity(new Intent(getApplicationContext(), MainActivity.class));
-		}
-	};
-	
-	private OnClickListener tryAgainClicker = new OnClickListener(){
-		public void onClick(View v){
-			bindToService(DownloadService.TASKID_ADDTASK);
-		}
-	};
-	
-	public void onStart(){
-		super.onStart();
-		bindToService(DownloadService.TASKID_SETUP);
-	}
-	
-	public void onStop(){
-		super.onStop();
-		unBindFromService();
-	}
-	
-	private ServiceConnection connection = new ServiceConnection(){
-
-		public void onServiceConnected(ComponentName name, IBinder service) {
-			messageService = new Messenger(service);
-			
-			try{
-				Message msg = Message.obtain(null, DownloadService.MSG_REGISTER_CLIENT);
-				msg.replyTo = messenger;
-				messageService.send(msg);
-				
-			}catch (RemoteException e){}
-		}
-
-		public void onServiceDisconnected(ComponentName name) {
-			messageService = null;
-		}
-		
-	};
-	
-	private void bindToService(int taskId){
-		Intent i = new Intent(getApplicationContext(), DownloadService.class);
-		i.putExtra(DownloadService.INTENT_TASKID, taskId);
-		startService(i);
-		bindService(new Intent(getApplicationContext(), DownloadService.class), connection, Context.BIND_AUTO_CREATE);
-		boundToService = true;
-	}
-	
-	private void unBindFromService(){
-		if(boundToService){
-			boundToService = false;
-			unbindService(connection);
-		}	
-	}
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAssets.java	Thu Nov 24 13:44:30 2011 +0100
@@ -0,0 +1,95 @@
+package org.hedgewars.hedgeroid.Downloader;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.hedgewars.hedgeroid.MainActivity;
+import org.hedgewars.hedgeroid.Utils;
+
+import android.content.Context;
+import android.content.res.AssetManager;
+import android.os.AsyncTask;
+import android.util.Log;
+
+public class DownloadAssets extends AsyncTask<Object, Long, Long>{
+	
+	private MainActivity act;
+	private static byte[] buffer = null;
+	
+	public DownloadAssets(MainActivity _act){
+		act = _act;
+	}
+	
+	
+	
+	public static Long copyFileOrDir(Context c, String path) {
+	    AssetManager assetManager = c.getAssets();
+	    String assets[] = null;
+	    try {
+	        assets = assetManager.list(path);
+	        if (assets.length == 0) {
+	            return DownloadAssets.copyFile(c, path);
+	        } else {
+	            String fullPath = Utils.getCachePath(c) + path;
+	            File dir = new File(fullPath);
+	            if (!dir.exists())
+	                dir.mkdir();
+	            for (int i = 0; i < assets.length; ++i) {
+	                Long result = DownloadAssets.copyFileOrDir(c, path + "/" + assets[i]);
+	                if(result > 0) return 1l;
+	            }
+	        }
+	    } catch (IOException ex) {
+	    	ex.printStackTrace();
+	        Log.e("tag", "I/O Exception", ex);
+	        return 1l;
+	    }
+	    return 0l;
+	}
+	
+	private static Long copyFile(Context c, String filename) {
+	    AssetManager assetManager = c.getAssets();
+
+	    InputStream in = null;
+	    OutputStream out = null;
+	    try {
+	        in = assetManager.open(filename);
+	        in = new BufferedInputStream(in, 8192);
+	        
+	        String newFileName = Utils.getCachePath(c) + filename;
+	        out = new FileOutputStream(newFileName);
+	        out = new BufferedOutputStream(out, 8192);
+
+	        int read;
+	        while ((read = in.read(buffer)) != -1) {
+	            out.write(buffer, 0, read);
+	        }
+	        in.close();
+	        in = null;
+	        out.flush();
+	        out.close();
+	        out = null;
+	    } catch (Exception e) {
+	    	e.printStackTrace();
+	        Log.e("tag", e.getMessage());
+	        return 1l;
+	    }
+	    return 0l;
+
+	}
+
+	protected Long doInBackground(Object... params) {
+		buffer = new byte[8192];//allocate the buffer
+		return DownloadAssets.copyFileOrDir(act, "Data");
+	}
+	
+	protected void onPostExecute(Long result){
+		act.onAssetsDownloaded(result == 0);
+		buffer = null;
+	}
+}
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAsyncTask.java	Thu Nov 24 13:40:17 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAsyncTask.java	Thu Nov 24 13:44:30 2011 +0100
@@ -31,6 +31,8 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
+import org.hedgewars.hedgeroid.Downloader.DownloadService.DownloadTask;
+
 import android.os.AsyncTask;
 /**
  * This is an AsyncTask which will download a zip from an URL and unzip it to a specified path
@@ -39,35 +41,35 @@
  * @author Xeli
  *
  */
-public class DownloadAsyncTask extends AsyncTask<DownloadTask, Object, Long> {
+public class DownloadAsyncTask extends AsyncTask<DownloadPackage, Object, Long> {
 
 	//private final static String URL_WITHOUT_SUFFIX = "http://www.xelification.com/tmp/firebutton.";
 	private final static String URL_ZIP_SUFFIX = ".zip";
 	private final static String URL_HASH_SUFFIX = ".hash";
 	
-	private DownloadService service;
+	private DownloadTask task;
 	private long lastUpdateMillis = 0;
 
-	public DownloadAsyncTask(DownloadService _service){
-		service = _service;
+	public DownloadAsyncTask(DownloadTask _task){
+		task = _task;
 	}
 
 	/**
 	 * 
 	 * @param params - A {@link}DownloadTask which gives information about where to download from and store the files to 
 	 */
-	protected Long doInBackground(DownloadTask...tasks) {
-		DownloadTask task = tasks[0];//just use one task per execute call for now
+	protected Long doInBackground(DownloadPackage...packages) {
+		DownloadPackage pack = packages[0];//just use one task per execute call for now
 		
 		HttpURLConnection conn = null;
 		MessageDigest digester = null;
-		String rootZipDest = task.getPathToStore();
+		String rootZipDest = pack.getPathToStore();
 
 		File rootDest = new File(rootZipDest);//TODO check for nullpointer, it hints to the absence of an sdcard
 		rootDest.mkdir();
 
 		try {
-			URL url = new URL(task.getURL() + URL_ZIP_SUFFIX);
+			URL url = new URL(pack.getURL() + URL_ZIP_SUFFIX);
 			conn = (HttpURLConnection)url.openConnection();
 		} catch (IOException e) {
 			e.printStackTrace();
@@ -83,7 +85,7 @@
 			int kbytesToProcess = conn.getContentLength()/1024;
 
 			byte[] buffer = new byte[1024];
-			service.start(kbytesToProcess);
+			task.start(kbytesToProcess);
 
 			try {
 				digester = MessageDigest.getInstance("MD5");
@@ -98,7 +100,7 @@
 			}catch(IOException e){
 				e.printStackTrace();
 				if(conn != null) conn.disconnect();
-				return -1l;
+				return -2l;
 			}
 
 			while(entry != null){
@@ -134,11 +136,11 @@
 					} catch (FileNotFoundException e) {
 						e.printStackTrace();
 						if(conn != null) conn.disconnect();
-						return -1l;
+						return -3l;
 					} catch (IOException e) {
 						e.printStackTrace();
 						if(conn != null) conn.disconnect();
-						return -1l;
+						return -4l;
 					}finally{
 						try {
 							if( output != null) output.close();
@@ -161,20 +163,20 @@
 
 		if(conn != null) conn.disconnect();
 
-		if(checkMD5(digester, task))return 0l;
+		if(checkMD5(digester, pack))return 0l;
 		else return -1l;
 	}
 
 	//TODO proper result handling
 	protected void onPostExecute(Long result){
-		service.done(result > -1l);
+		task.done(result > -1l);
 	}
 
 	protected void onProgressUpdate(Object...objects){
-		service.update((Integer)objects[0], (Integer)objects[1], (String)objects[2]);
+		task.update((Integer)objects[0], (Integer)objects[1], (String)objects[2]);
 	}
 
-	private boolean checkMD5(MessageDigest digester, DownloadTask task){
+	private boolean checkMD5(MessageDigest digester, DownloadPackage task){
 		if(digester != null) {
 			byte[] messageDigest = digester.digest();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadDialogFragment.java	Thu Nov 24 13:44:30 2011 +0100
@@ -0,0 +1,69 @@
+package org.hedgewars.hedgeroid.Downloader;
+
+import org.hedgewars.hedgeroid.R;
+
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+
+public class DownloadDialogFragment extends DialogFragment {
+
+	public static final int NUM_ALREADYDOWNLOADED = 0;
+	public static final int NUM_AREYOUSURE = 1;
+
+	private final static String BUNDLE_TASK = "task";
+
+	static DownloadDialogFragment newInstance(DownloadPackage task){
+		DownloadDialogFragment dialog = new DownloadDialogFragment();
+
+		Bundle args = new Bundle();
+		args.putParcelable(DownloadDialogFragment.BUNDLE_TASK, task);
+		dialog.setArguments(args);
+
+		return dialog;
+	}
+
+	public Dialog onCreateDialog(Bundle savedInstanceState){
+		DownloadPackage task = (DownloadPackage)getArguments().getParcelable(DownloadDialogFragment.BUNDLE_TASK);
+
+		Builder builder = new AlertDialog.Builder(getActivity());
+
+		switch(task.getStatus()){
+		case CURRENTVERSION:
+		case NEWERVERSION:
+			builder.setMessage(R.string.download_areyousure);
+			break;
+		case OLDERVERSION:
+			builder.setMessage(R.string.download_alreadydownloaded);
+			break;
+		}
+
+		DownloadClicker clicker = new DownloadClicker(task);
+		builder.setPositiveButton(android.R.string.yes, clicker);
+		builder.setNegativeButton(android.R.string.no, clicker);
+
+		return builder.create();
+	}
+
+	class DownloadClicker implements OnClickListener{
+
+		DownloadPackage task = null;
+
+		public DownloadClicker(DownloadPackage _task){
+			task = _task;
+		}
+
+		public void onClick(DialogInterface dialog, int which) {
+			if(which == Dialog.BUTTON_POSITIVE){
+				Intent i = new Intent(getActivity(), DownloadFragment.class);
+				i.putExtra(DownloadFragment.EXTRA_TASK, task);
+				getActivity().startActivity(i);
+			}
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadFragment.java	Thu Nov 24 13:44:30 2011 +0100
@@ -0,0 +1,216 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (c) 2011 Richard Deurwaarder <xeli@xelification.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+package org.hedgewars.hedgeroid.Downloader;
+
+import org.hedgewars.hedgeroid.R;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+public class DownloadFragment extends Fragment{
+	public static final String EXTRA_TASK = "task";
+
+	public static final int MSG_START = 0;
+	public static final int MSG_UPDATE = 1;
+	public static final int MSG_DONE = 2;
+	public static final int MSG_FAILED = 3;
+
+	private boolean boundToService = false;
+
+	private TextView progress_sub;
+	private ProgressBar progress;
+	private Button positive, negative;
+
+	private DownloadPackage pack;
+
+	private Handler messageHandler;
+	private Messenger messenger, messengerService;
+
+	public static DownloadFragment getInstance(DownloadPackage task){
+		DownloadFragment df = new DownloadFragment();
+		Bundle args = new Bundle();
+		args.putParcelable(DownloadFragment.EXTRA_TASK, task);
+		
+		df.setArguments(args);
+		
+		return df;
+	}
+	
+	public void onActivityCreated(Bundle savedInstanceState){
+		super.onActivityCreated(savedInstanceState);
+		
+		messageHandler = new Handler(messageCallback);
+		messenger = new Messenger(messageHandler);
+		 Intent i = new Intent(getActivity(), DownloadService.class);
+         getActivity().startService(i);
+         getActivity().bindService(new Intent(getActivity(), DownloadService.class), connection, Context.BIND_AUTO_CREATE);
+	}
+	
+	public View onCreateView(LayoutInflater inflater, ViewGroup viewgroup, Bundle savedInstanceState){
+		View v = inflater.inflate(R.layout.download_progress, viewgroup, false);
+		progress_sub = (TextView)v.findViewById(R.id.progressbar_sub);
+		progress = (ProgressBar)v.findViewById(R.id.progressbar);
+
+		positive = (Button) v.findViewById(R.id.background);
+		negative = (Button) v.findViewById(R.id.cancelDownload);
+		positive.setOnClickListener(backgroundClicker);
+		negative.setOnClickListener(cancelClicker);
+
+		pack = getArguments().getParcelable(DownloadFragment.EXTRA_TASK);
+
+		return v;
+	}
+
+	private OnClickListener backgroundClicker = new OnClickListener(){
+		public void onClick(View v){
+			getActivity().finish();
+		}
+	};
+	private OnClickListener cancelClicker = new OnClickListener(){
+		public void onClick(View v){
+			if(messenger != null){
+				Message message = Message.obtain(messageHandler, DownloadService.MSG_CANCEL, pack);
+				try {
+					messengerService.send(message);
+				} catch (RemoteException e) {}
+			}
+			getActivity().finish();
+		}
+	};
+	private OnClickListener doneClicker = new OnClickListener(){
+		public void onClick(View v){
+			getActivity().finish();
+		}
+	};
+
+	private OnClickListener tryAgainClicker = new OnClickListener(){
+		public void onClick(View v){
+			if(messenger != null){
+				Message message = Message.obtain(messageHandler, DownloadService.MSG_ADDTASK, pack);
+				message.replyTo = messenger;
+				try {
+					messengerService.send(message);
+				} catch (RemoteException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+	};
+
+	public void onStop(){
+		super.onStop();
+		unBindFromService();
+	}
+
+	private ServiceConnection connection = new ServiceConnection(){
+
+		public void onServiceConnected(ComponentName name, IBinder service) {
+			messengerService = new Messenger(service);
+
+			try{
+				//give the service a task
+				if(messenger != null){
+					Message message = Message.obtain(messageHandler, DownloadService.MSG_ADDTASK, pack);
+					message.replyTo = messenger;
+					messengerService.send(message);
+				}
+
+			}catch (RemoteException e){}
+		}
+
+		public void onServiceDisconnected(ComponentName name) {
+			messengerService = null;
+		}
+
+	};
+
+	private void unBindFromService(){
+		if(boundToService){
+			if(messenger != null){
+				try {
+					Message message = Message.obtain(messageHandler, DownloadService.MSG_UNREGISTER_CLIENT, pack);
+					message.replyTo = messenger;
+					messengerService.send(message);
+				} catch (RemoteException e) {
+					e.printStackTrace();
+				}
+			}
+			
+			boundToService = false;
+			getActivity().unbindService(connection);
+		}	
+	}
+
+	private Handler.Callback messageCallback = new Handler.Callback() {
+
+		public boolean handleMessage(Message msg) {
+			switch(msg.what){
+			case MSG_START:
+				progress.setMax(msg.arg1);
+				progress_sub.setText(String.format("%dkb/%dkb\n%s", 0, msg.arg1, ""));
+				positive.setText(R.string.download_background);
+				positive.setOnClickListener(backgroundClicker);
+				negative.setText(R.string.download_cancel);
+				negative.setOnClickListener(cancelClicker);
+				break;
+			case MSG_UPDATE:
+				progress_sub.setText(String.format("%d%% - %dkb/%dkb\n%s",(msg.arg1*100)/msg.arg2, msg.arg1, msg.arg2, msg.obj));
+				progress.setProgress(msg.arg1);
+				break;
+			case MSG_DONE:
+				progress.setProgress(progress.getMax());
+				progress_sub.setText(R.string.download_done);
+
+				positive.setText(R.string.download_back);
+				positive.setOnClickListener(doneClicker);
+
+				negative.setVisibility(View.INVISIBLE);
+				break;
+			case MSG_FAILED:
+				progress.setProgress(progress.getMax());
+				progress_sub.setText(R.string.download_failed);
+				positive.setText(R.string.download_back);
+				positive.setOnClickListener(doneClicker);
+
+				negative.setText(R.string.download_tryagain);
+				negative.setOnClickListener(tryAgainClicker);
+				break;
+			}
+			return false;
+		}
+	};
+
+}
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListActivity.java	Thu Nov 24 13:40:17 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListActivity.java	Thu Nov 24 13:44:30 2011 +0100
@@ -1,36 +1,114 @@
 package org.hedgewars.hedgeroid.Downloader;
 
-import android.app.ListActivity;
+import org.hedgewars.hedgeroid.R;
+
 import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Gravity;
 import android.view.View;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ArrayAdapter;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+
+public class DownloadListActivity extends FragmentActivity implements OnItemMovementListener{
 
-public class DownloadListActivity extends ListActivity implements OnItemClickListener{
+	private FrameLayout layout = null;
+	private LinearLayout downloadQueueContainer = null;
+	private View infoView = null;
+	private ImageView arrow = null;
+	private int halfSize = 0;
+	private DownloadPackage task = null;
 
-	
 	public void onCreate(Bundle savedInstanceState){
 		super.onCreate(savedInstanceState);
-		
-		DownloadTask[] tasks = new DownloadTask[3];
-		tasks[0] = new DownloadTask("url1", "/home/path/1", 1, "entry 1");
-		tasks[1] = new DownloadTask("url2", "/home/path/2", 1, "entry 2");
-		tasks[2] = new DownloadTask("url3", "/home/path/3", 1, "entry 3");
-		
-		ArrayAdapter<DownloadTask> adapter = new ArrayAdapter<DownloadTask>(this, android.R.layout.simple_list_item_1, tasks);
-		this.setListAdapter(adapter);
-		this.getListView().setOnItemClickListener(this);
-		
+
+		setContentView(R.layout.download_listactivity);
+		//FragmentManager fm = this.getSupportFragmentManager();
+		//if(fm.findFragmentById(android.R.id.content) == null){
+		//	DownloadListFragment listfrag = new DownloadListFragment();
+		//	fm.beginTransaction().add(android.R.id.content, listfrag).commit();
+		//}
+
+		layout = (FrameLayout)findViewById(R.id.downloadFrameLayout);
+		downloadQueueContainer = (LinearLayout) findViewById(R.id.downloadQueueContainer);
+	}
+
+	public void onNewItemSelected(DownloadPackage _task, int x, int minX, int maxX, int size) {
+		if(layout != null){
+			if(!_task.equals(task)){//if it's a new task refresh the whole thing
+				task = _task;
+				layout.removeView(infoView);
+				infoView = null;
+			}
+			
+			if(infoView == null){//build iv if it hasn't been created yet
+				infoView = this.getLayoutInflater().inflate(R.layout.download_info, layout, false);
+				FrameLayout.LayoutParams params = (android.widget.FrameLayout.LayoutParams) infoView.getLayoutParams();
+				params.gravity = Gravity.NO_GRAVITY;
+				params.height = size;
+				arrow = (ImageView)infoView.findViewById(R.id.arrow);
+				arrow.setVisibility(View.INVISIBLE);
+				halfSize = size/2;
+				
+				Button yes = (Button)infoView.findViewById(R.id.download);
+				Button no = (Button)infoView.findViewById(R.id.cancel);
+				yes.setOnClickListener(yesClicker);
+				no.setOnClickListener(noClicker);
+				
+				layout.addView(infoView, params);
+			}
+		}
+	}
+
+	public void onViewMoved(int x, int minX, int maxX) {
+		if(halfSize == -1){
+			if(infoView.getHeight() != 0){
+				halfSize = infoView.getHeight()/2;
+			}
+		}
+		if(layout != null && infoView != null){
+			FrameLayout.LayoutParams params = ((FrameLayout.LayoutParams)infoView.getLayoutParams());
+			if(x - halfSize < minX){
+				params.topMargin = 0;
+				arrow.setVisibility(View.INVISIBLE);
+				params.gravity = Gravity.TOP;
+			}else if (x + halfSize >= maxX){
+				params.topMargin = 0;
+				arrow.setVisibility(View.INVISIBLE);
+				params.gravity = Gravity.BOTTOM;
+			}else{
+				params.topMargin = x - halfSize;
+				params.gravity = Gravity.NO_GRAVITY;
+				arrow.setVisibility(View.VISIBLE);
+			}
+			
+			infoView.requestLayout();
+			
+		}
 	}
 	
-	public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
-		DownloadTask task = (DownloadTask)arg0.getAdapter().getItem(position);
-	}
+	private OnClickListener yesClicker = new OnClickListener(){
+		public void onClick(View v){
+			FragmentManager fm = getSupportFragmentManager();
+			FragmentTransaction ft= fm.beginTransaction();
+			DownloadFragment df = DownloadFragment.getInstance(task);
+			
+			ft.add(R.id.downloadQueueContainer, df).commit();
+			//ft.show(new DownloadFragment());
+			
+			task = null;
+			layout.removeView(infoView);
+		}
+	};
 	
-//	public static class Dialog extends DialogFragment{
-		
-//	}
-	
+	private OnClickListener noClicker = new OnClickListener(){
+		public void onClick(View v){
+			task = null;
+			layout.removeView(infoView);
+		}
+	};
 }
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListFragment.java	Thu Nov 24 13:44:30 2011 +0100
@@ -0,0 +1,188 @@
+package org.hedgewars.hedgeroid.Downloader;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.ArrayList;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import android.graphics.Color;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v4.app.ListFragment;
+import android.util.Log;
+import android.view.View;
+import android.widget.AbsListView;
+import android.widget.AbsListView.OnScrollListener;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
+
+public class DownloadListFragment extends ListFragment implements OnItemClickListener, OnScrollListener, Runnable{
+
+	private View targetView = null;
+	private ArrayList<OnItemMovementListener> listeners = new ArrayList<OnItemMovementListener>(); 
+
+	public void onActivityCreated(Bundle savedInstanceState){
+		super.onActivityCreated(savedInstanceState);
+
+		ArrayList<DownloadPackage> tasks = new ArrayList<DownloadPackage>();
+
+		ArrayAdapter<DownloadPackage> adapter = new ArrayAdapter<DownloadPackage>(getActivity().getApplicationContext(), android.R.layout.simple_list_item_1, tasks);
+		setListAdapter(adapter);
+		getListView().setOnItemClickListener(this);
+		getListView().setOnScrollListener(this);
+
+		if(getActivity() instanceof OnItemMovementListener){
+			listeners.add((OnItemMovementListener)getActivity());
+		}
+
+		getListView().setCacheColorHint(Color.TRANSPARENT);//To prevent a blackish background while scrolling
+		
+		
+		Thread t = new Thread(this, "DownloadListParser");
+		t.start();
+	}
+
+	public void run(){
+		XmlPullParserFactory xmlPullFactory;
+		try {
+			xmlPullFactory = XmlPullParserFactory.newInstance();
+			XmlPullParser xmlPuller = xmlPullFactory.newPullParser();
+
+			URL url = new URL("http://www.xelification.com/tmp/downloads.xml");
+			HttpURLConnection conn = (HttpURLConnection)url.openConnection();
+
+			BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()), 1024);
+			xmlPuller.setInput(br);
+
+			final ArrayAdapter<DownloadPackage> adapter = (ArrayAdapter<DownloadPackage>) getListAdapter();
+			
+			int eventType = xmlPuller.getEventType();
+			while(eventType != XmlPullParser.END_DOCUMENT){
+			
+				if(eventType == XmlPullParser.START_TAG){
+					if(xmlPuller.getName().toLowerCase().equals("task")){
+						final DownloadPackage task = DownloadPackage.getTaskFromXML(getActivity(), xmlPuller);
+						
+						getActivity().runOnUiThread(new Runnable(){
+							public void run() {
+								adapter.add(task);								
+							}
+						});
+					}
+				}
+				eventType = xmlPuller.nextTag();
+			}
+			
+			
+		} catch (XmlPullParserException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+
+	}
+
+	public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
+		FragmentTransaction ft = getFragmentManager().beginTransaction();
+		Fragment prev = getFragmentManager().findFragmentByTag("dialog");
+
+		//remove any old dialogs
+		if(prev != null) ft.remove(prev);
+		ft.addToBackStack(null);
+
+		//create a new dialog based on this task
+		DownloadPackage task = (DownloadPackage)arg0.getAdapter().getItem(position);
+		DialogFragment newFragment = DownloadDialogFragment.newInstance(task);
+
+		//show it
+		//newFragment.show(ft, "dialog");
+
+		targetView = arg1;
+
+		//determine state
+		int min = arg0.getTop();
+		int max = arg0.getBottom();
+		int top = targetView.getTop();
+
+		previousXCoord = top;
+		for(OnItemMovementListener listener : listeners){
+			listener.onNewItemSelected(task, top, min, max, targetView.getHeight()*2);
+		}
+	}
+
+	private int previousXCoord = 0;
+
+	/*
+	 * (non-Javadoc)
+	 * @see android.widget.AbsListView.OnScrollListener#onScroll(android.widget.AbsListView, int, int, int)
+	 * 
+	 * Android renews the Items used in the view, so when a user scroll down the list, 
+	 * as soon as the item has dissapeard from the list it gets reused at the bottom.
+	 * 
+	 * For this reason we cannot just keep sending the targetView.getTop() but we must
+	 *  remember if the view is supposed to be at the top or bottom of the list. We 
+	 *  remember this with int state, 
+	 *     - 0 means we've got accurate reading from getTop()
+	 *     - -1 means it's somewhere at the top of the list
+	 *     - 1 means it's at the bottom somewhere
+	 */
+	public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
+		if(targetView != null){
+			int top = targetView.getTop() + (targetView.getHeight()/2);
+			int min = view.getTop();
+			int max = view.getBottom();
+
+			if(Math.abs(previousXCoord - top) > targetView.getHeight()*2 ){
+				top = previousXCoord;
+			}
+
+			for(OnItemMovementListener listener : listeners){
+				listener.onViewMoved(top, min, max);
+			}
+
+			previousXCoord = top;
+		}
+	}
+
+	public void onScrollStateChanged(AbsListView view, int scrollState) {
+		switch(scrollState){
+		case OnScrollListener.SCROLL_STATE_FLING: Log.d("tag", "fling"); break;
+		case OnScrollListener.SCROLL_STATE_IDLE:Log.d("tag", "idle"); break;
+		case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:Log.d("tag", "scroll"); break;
+
+		}
+
+	}
+}
+
+interface OnItemMovementListener{
+	/**
+	 * When I new item has been selected this method will be called
+	 * @param task The task which goes with this item
+	 * @param x The middle of this item
+	 * @param minX The top of the parent of this item
+	 * @param maxX The bottom of the parent of this item
+	 */
+	void onNewItemSelected(DownloadPackage task, int x, int minX, int maxX, int size);
+
+	/**
+	 * When the item has been moved this method is called
+	 * @param x The middle of this item
+	 * @param minX The top of the parent of this item
+	 * @param maxX The bottom of the parent of this item
+	 */
+	void onViewMoved(int x, int minX, int maxX);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadPackage.java	Thu Nov 24 13:44:30 2011 +0100
@@ -0,0 +1,186 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (c) 2011 Richard Deurwaarder <xeli@xelification.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+package org.hedgewars.hedgeroid.Downloader;
+
+import java.io.IOException;
+
+import org.hedgewars.hedgeroid.Utils;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+public class DownloadPackage implements Parcelable{
+	private String url_without_suffix;
+	private String pathToStore;
+	private String representation;
+	private String description;
+	private int versionNumber;
+	private final Status status;
+	private int uniqueId;
+
+
+	public DownloadPackage(Parcel src){
+		url_without_suffix = src.readString();
+		pathToStore = src.readString();
+		representation = src.readString();
+		versionNumber = src.readInt();
+		status = Status.values()[src.readInt()];
+		description = src.readString();
+		uniqueId = src.readInt();
+	}
+
+	public DownloadPackage(Context c, String _url_without_suffix, String path, int version, String _representation, String _description, int _uniqueId){
+		url_without_suffix = _url_without_suffix;
+		pathToStore = path;
+		representation = _representation;
+		versionNumber = version;
+		description = _description;
+		uniqueId = _uniqueId;
+
+
+		//determine if the user has already downloaded this version
+		SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(c);
+		int currentVersion = sharedPref.getInt(representation, -1);
+		if(currentVersion == versionNumber) status = Status.CURRENTVERSION;
+		else if (currentVersion < versionNumber) status = Status.NEWERVERSION;
+		else status = Status.OLDERVERSION;
+	}
+
+	public Status getStatus(){
+		return status;
+	}
+
+	public String getURL(){
+		return url_without_suffix;
+	}
+
+	public String getPathToStore(){
+		return pathToStore;
+	}
+
+	public String toString(){
+		return representation;
+	}
+
+	public int describeContents() {
+		return 0;
+	}
+	public int getId(){
+		return uniqueId;
+	}
+
+	public void writeToParcel(Parcel dest, int flags) {
+		dest.writeString(url_without_suffix);
+		dest.writeString(pathToStore);
+		dest.writeString(representation);
+		dest.writeInt(versionNumber);
+		dest.writeInt(status.ordinal());
+		dest.writeString(description);
+	}
+
+	public static final Parcelable.Creator<DownloadPackage> CREATOR = new Parcelable.Creator<DownloadPackage>() {
+		public DownloadPackage createFromParcel(Parcel source) {
+			return new DownloadPackage(source);
+		}
+		public DownloadPackage[] newArray(int size) {
+			return new DownloadPackage[size];
+		}
+	};
+
+	/*
+	 * We enter with a XmlPullParser.Start_tag with name "task"
+	 */
+	public static DownloadPackage getTaskFromXML(Context c, XmlPullParser xmlPuller) throws XmlPullParserException, IOException{
+		String url = null;
+		String path = null;
+		String representation = null;
+		String description = null;
+		int uniqueId = -1;
+		int version = -1;
+
+		int eventType = DownloadPackage.getEventType(xmlPuller);//get the next token, should be a start tag
+		while(eventType != XmlPullParser.END_DOCUMENT){
+			switch(eventType){
+			case XmlPullParser.START_TAG:
+				String name = xmlPuller.getName().toLowerCase();
+				if(DownloadPackage.getEventType(xmlPuller) == XmlPullParser.TEXT){
+					String text = xmlPuller.getText().trim();
+					if(name.equals("url")){
+						url = text;
+					}else if(name.equals("version")){
+						try{
+						version = Integer.parseInt(text);
+						}catch (NumberFormatException e){
+							e.printStackTrace();
+							version = -1;
+						}
+					}else if(name.equals("path")){
+						path = Utils.getDataPath(c) + text;
+					}else if(name.equals("representation")){
+						representation = text;
+					}else if(name.equals("description")){
+						description = text;
+					}else if(name.equals("uniqueid")){
+						try{
+							uniqueId = Integer.parseInt(text);
+							}catch (NumberFormatException e){
+								e.printStackTrace();
+								version = -1;
+							}
+					}
+				}				
+				DownloadPackage.getEventType(xmlPuller);//endtag
+				break;
+			case XmlPullParser.END_TAG:
+				if(xmlPuller.getName().toLowerCase().equals("task") && url != null && path != null && version != -1 && representation != null){
+					return new DownloadPackage(c, url, path, version, representation, description, uniqueId);
+				}else{
+					throw new XmlPullParserException("XML download parsing: missing tags");
+				}
+			case XmlPullParser.TEXT:
+				throw new XmlPullParserException("Wrong tag recieved got TEXT : " + xmlPuller.getText());
+			default:
+				throw new XmlPullParserException("Wrong tag recieved got: " + eventType);
+			}
+			eventType = DownloadPackage.getEventType(xmlPuller);
+		}
+		throw new XmlPullParserException("Xml: unexpected endofdocument tag");
+	}
+
+	/**
+	 * Skips whitespaces..
+	 */
+	private static int getEventType(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{
+		int eventType = xmlPuller.next();
+		while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){
+			eventType = xmlPuller.next();
+		}
+		return eventType;
+	}
+}
+
+enum Status{
+	CURRENTVERSION, NEWERVERSION, OLDERVERSION;
+}
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadService.java	Thu Nov 24 13:40:17 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadService.java	Thu Nov 24 13:44:30 2011 +0100
@@ -20,11 +20,12 @@
 package org.hedgewars.hedgeroid.Downloader;
 
 import java.util.ArrayList;
+import java.util.Deque;
 import java.util.LinkedList;
+import java.util.List;
 
 import org.hedgewars.hedgeroid.MainActivity;
 import org.hedgewars.hedgeroid.R;
-import org.hedgewars.hedgeroid.Utils;
 
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -37,104 +38,83 @@
 import android.os.Message;
 import android.os.Messenger;
 import android.os.RemoteException;
-import android.preference.PreferenceManager;
-import android.util.Log;
 import android.widget.RemoteViews;
 
 public class DownloadService extends Service {
-
-	public final static int TASKID_SETUP = 0;
-	public final static int TASKID_CANCEL = 1;
-	public final static int TASKID_ADDTASK = 2;
-
 	public final static String INTENT_TASKID = "taskId";
 	public final static String INTENT_TASK = "task";
 
 	public static final String PREF_DOWNLOADED = "downloaded";
 	public static final int MSG_CANCEL = 0;
-	public static final int MSG_REGISTER_CLIENT = 1;
 	public static final int MSG_UNREGISTER_CLIENT = 2;
+	public final static int MSG_ADDTASK = 4;
 
 	public static final int NOTIFICATION_PROCESSING = 0;
 	public static final int NOTIFICATION_DONE = 1;
 
 	private DownloadAsyncTask asyncExecutor;
-	private final Messenger messenger = new Messenger(new DownloadHandler());
+
+	private DownloadHandler handler = new DownloadHandler();
+	private final Messenger messenger = new Messenger(handler);
+
 	private NotificationManager nM;
 	private RemoteViews contentView;
-	private Notification notification;
 
-	private LinkedList<DownloadTask> downloadTasks = new LinkedList<DownloadTask>();
-	private ArrayList<Messenger> clientList = new ArrayList<Messenger>();
-	private Message onRegisterMessage = null;
+	private Deque<DownloadTask> downloadTasks = new LinkedList<DownloadTask>();
 
-
-	class DownloadHandler extends Handler{
+	public class DownloadHandler extends Handler{
 
 		public void handleMessage(Message msg){
-			switch(msg.what){
-			case MSG_CANCEL:
-				asyncExecutor.cancel(false);
-				break;
-			case MSG_REGISTER_CLIENT:
-				clientList.add(msg.replyTo);
-				if(onRegisterMessage != null){
-					try {
-						msg.replyTo.send(Message.obtain(onRegisterMessage));
-					} catch (RemoteException e) {
-						e.printStackTrace();
+			if(msg.obj != null){
+				DownloadPackage pack = (DownloadPackage) msg.obj;
+				DownloadTask task = null;
+				Messenger replyToMessenger = msg.replyTo;
+				for(DownloadTask _task : downloadTasks){
+					if(_task.getPackage().equals(pack)){
+						task = _task;
+						break;
 					}
 				}
-				break;
-			case MSG_UNREGISTER_CLIENT:
-				clientList.remove(msg.replyTo);
-				break;
+
+				switch(msg.what){
+				case MSG_ADDTASK:
+					if(task == null){
+						task = new DownloadTask(pack);
+						downloadTasks.add(task);
+					}
+
+					task.addClient(replyToMessenger);
+					runNextTask();
+					return;
+				case MSG_CANCEL:
+					if(task != null && task.getPackage().equals(pack) && task.getStatus() == TASK_STATE.RUNNING){
+						asyncExecutor.cancel(false);
+					}
+					return;
+				case MSG_UNREGISTER_CLIENT:
+					if(task != null){
+						task.removeClient(replyToMessenger);
+					}
+					return;
+				}
 			}
 		}
 	}
+
+	public void onCreate(){
+		super.onCreate();
+		nM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+	}
 	public IBinder onBind(Intent intent) {
 		return messenger.getBinder();
 	}
 
-	/**
-	 * This is the main method which controls how DownloadService and DownloadAsyncTask are running
-	 */
-	public int onStartCommand(Intent intent, int flags, int startId){
-		switch(intent.getIntExtra("taskID", TASKID_SETUP)){
-		case TASKID_SETUP:
-			nM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
-
-			notification = new Notification(R.drawable.statusbar, getString(R.string.notification_title), System.currentTimeMillis());
-			notification.flags |= Notification.FLAG_ONGOING_EVENT;
-
-			contentView = new RemoteViews(getPackageName(), R.layout.notification);
-			contentView.setProgressBar(R.id.notification_progress, 100, 34, false);
-			notification.contentView = contentView;
-
-			PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, DownloadActivity.class), Intent.FLAG_ACTIVITY_NEW_TASK);
-			notification.contentIntent = contentIntent;
-
-			asyncExecutor = new DownloadAsyncTask(this);
-			break;
-		case TASKID_ADDTASK:
-			//Add downloadtask to the queue
-			DownloadTask task = intent.getParcelableExtra(DownloadService.INTENT_TASK);
-			downloadTasks.offer(task);
-			runNextTask();
-			break;
-		case TASKID_CANCEL:
-			asyncExecutor.cancel(false);
-			break;
-		}		
-		return 0;
-	}
-
-	private synchronized void runNextTask(){
-		if(!asyncExecutor.getStatus().equals(AsyncTask.Status.RUNNING)){//if the task isnt running right now...
-			DownloadTask task = downloadTasks.poll();
-			if(task == null){
-				startForeground(NOTIFICATION_PROCESSING, notification);
-				asyncExecutor.execute(task);
+	private void runNextTask(){
+		if(asyncExecutor == null){//if (task isnt running right now) ...
+			DownloadTask task = downloadTasks.pollFirst();
+			if(task != null){
+				asyncExecutor = new DownloadAsyncTask(task);
+				asyncExecutor.execute(task.getPackage());
 			}
 		}
 	}
@@ -144,59 +124,101 @@
 		asyncExecutor.cancel(false);	
 	}
 
-	/*
-	 * Callbacks called from the async tasks
-	 */
+	class DownloadTask {
+		private final DownloadPackage pack;
+		private TASK_STATE status = TASK_STATE.PENDING;
+		private Notification progressNotification, doneNotification;
+
+		//I expect little to no removeClient calls that's why we go for a list rather than a map
+		private final List<Messenger> clients;
+
+		public DownloadTask(DownloadPackage _pack){
+			pack = _pack;
+			clients = new LinkedList<Messenger>();
+		}
+
+		public void addClient(Messenger messenger){
+			clients.add(messenger);
+		}
+		public void removeClient(Messenger messenger){
+			clients.remove(messenger);
+		}
+
+		public DownloadPackage getPackage(){
+			return pack;
+		}
+
+		public TASK_STATE getStatus(){
+			return status;
+		}
+
+		public void sendMessageToClients(Message msg){
+			for(Messenger messenger : clients){
+				try {
+					messenger.send(msg);		
+				} catch (RemoteException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+
+		/*
+		 * Callbacks called from the async tasks
+		 */
 
-	//Thread safe method to let clients know the processing is starting and will process int max kbytes
-	public void start(int max){
-		onRegisterMessage = Message.obtain(null, DownloadActivity.MSG_START, max, -1);
-		sendMessageToClients(onRegisterMessage);
-	}
+		//Thread safe method to let clients know the processing is starting and will process int max kbytes
+		public void start(int max){
+			progressNotification = new Notification(R.drawable.statusbar, getString(R.string.notification_title), System.currentTimeMillis());
+			progressNotification.flags |= Notification.FLAG_ONGOING_EVENT;
+
+			contentView = new RemoteViews(getPackageName(), R.layout.notification);
+			contentView.setProgressBar(R.id.notification_progress, 100, 34, false);
+			progressNotification.contentView = contentView;
+
+			PendingIntent contentIntent = PendingIntent.getActivity(DownloadService.this, 0, new Intent(DownloadService.this, DownloadFragment.class), Intent.FLAG_ACTIVITY_NEW_TASK);
+			progressNotification.contentIntent = contentIntent;
+
+			startForeground(NOTIFICATION_PROCESSING, progressNotification);//TODO werkt het?
+
+			Message msg = Message.obtain(null, DownloadFragment.MSG_START, max, 0);
+			sendMessageToClients(msg);
+		}
+
+		//periodically gets called by the ASyncTask, we can't tell for sure when it's called
+		public void update(int progress, int max, String fileName){
+			progress = (progress/1024);
 
-	//periodically gets called by the ASyncTask, we can't tell for sure when it's called
-	public void update(int progress, int max, String fileName){
-		progress = (progress/1024);
-		updateNotification(progress, max, fileName);
+			contentView.setProgressBar(R.id.notification_progress, max, progress, false);
+			contentView.setTextViewText(R.id.progressbar_sub, String.format("%dkb/%dkb (Compressed sizes)", progress, max));
+			nM.notify(NOTIFICATION_PROCESSING, progressNotification);
+
+			sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_UPDATE, progress, max, fileName));
+		}
 
-		sendMessageToClients(Message.obtain(null, DownloadActivity.MSG_UPDATE, progress, max, fileName));
+		//Call back from the ASync task when the task has either run into an error or finished otherwise
+		public void done(boolean succesful){
+			if(succesful){
+				sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_DONE));
+			}else sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_FAILED));
+			stopForeground(true);
+			nM.cancel(NOTIFICATION_PROCESSING);
+
+			String title = getString(R.string.notification_title);
+
+			doneNotification = new Notification(R.drawable.icon, title, System.currentTimeMillis());
+			doneNotification.flags |= Notification.FLAG_AUTO_CANCEL;
+			PendingIntent contentIntent = PendingIntent.getActivity(DownloadService.this, 0, new Intent(DownloadService.this, DownloadListActivity.class), Intent.FLAG_ACTIVITY_NEW_TASK);
+			doneNotification.setLatestEventInfo(DownloadService.this, title, getString(R.string.notification_done) + pack, contentIntent);
+			nM.notify(pack.getId(), doneNotification);
+
+			asyncExecutor = null;
+			runNextTask();//see if there are more tasks
+		}
+
 	}
 
-	//Call back from the ASync task when the task has either run into an error or finished otherwise
-	public void done(boolean succesful){
-		if(succesful){
-			sendMessageToClients(Message.obtain(null, DownloadActivity.MSG_DONE));
-		}else sendMessageToClients(Message.obtain(null, DownloadActivity.MSG_FAILED));
-		nM.cancel(NOTIFICATION_PROCESSING);
-		stopForeground(true);
-		showDoneNotification();
-		runNextTask();//see if there are more tasks
-	}
-
-
-	private void updateNotification(int progress, int max, String fileName){
-
-		contentView.setProgressBar(R.id.notification_progress, max, progress, false);
-		contentView.setTextViewText(R.id.progressbar_sub, String.format("%dkb/%dkb (Compressed sizes)", progress, max));
-		nM.notify(NOTIFICATION_PROCESSING, notification);
-	}
-
-	private void showDoneNotification(){
-		String title = getString(R.string.notification_title);
-
-		notification = new Notification(R.drawable.icon, title, System.currentTimeMillis());
-		notification.flags |= Notification.FLAG_AUTO_CANCEL;
-		PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), Intent.FLAG_ACTIVITY_NEW_TASK);
-		notification.setLatestEventInfo(this, title, getString(R.string.notification_done), contentIntent);
-		nM.notify(NOTIFICATION_DONE, notification);
-	}
-
-	private void sendMessageToClients(Message msg){
-		for(Messenger m : clientList){
-			try {
-				m.send(Message.obtain(msg));
-			} catch (RemoteException e) {}//TODO should we catch this properly?
-		}
+	enum TASK_STATE{
+		RUNNING, FINISHED, PENDING;
 	}
 
 }
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadTask.java	Thu Nov 24 13:40:17 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-/*
- * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
- * Copyright (c) 2011 Richard Deurwaarder <xeli@xelification.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-package org.hedgewars.hedgeroid.Downloader;
-
-import java.io.IOException;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public class DownloadTask implements Parcelable{
-
-	private String url_without_suffix;
-	private String pathToStore;
-	private String representation;
-	private int attempts;
-	private int versionNumber;
-	
-	
-	public DownloadTask(Parcel in){
-		readFromParcel(in);
-	}
-	
-	public DownloadTask(String _url_without_suffix, String path, int version, String _representation){
-		url_without_suffix = _url_without_suffix;
-		pathToStore = path;
-		representation = _representation;
-		versionNumber = version;
-		attempts = 0;
-	}
-	
-	public int getAttempts(){
-		return attempts;
-	}
-	
-	public String getURL(){
-		return url_without_suffix;
-	}
-	
-	public String getPathToStore(){
-		return pathToStore;
-	}
-	
-	public void incrementAttempts(){
-		attempts++;
-	}
-	
-	public String toString(){
-		return representation;
-	}
-	
-	public int describeContents() {
-		return 0;
-	}
-
-	public void writeToParcel(Parcel dest, int flags) {
-		dest.writeString(url_without_suffix);
-		dest.writeString(pathToStore);
-		dest.writeString(representation);
-		dest.writeInt(versionNumber);
-		dest.writeInt(attempts);
-	}
-	
-	private void readFromParcel(Parcel src){
-		url_without_suffix = src.readString();
-		pathToStore = src.readString();
-		representation = src.readString();
-		versionNumber = src.readInt();
-		attempts = src.readInt();
-	}
-	
-	public static final Parcelable.Creator<DownloadTask> CREATOR = new Parcelable.Creator<DownloadTask>() {
-		public DownloadTask createFromParcel(Parcel source) {
-			return new DownloadTask(source);
-		}
-		public DownloadTask[] newArray(int size) {
-			return new DownloadTask[size];
-		}
-	};
-	
-	/*
-	 * We enter with a XmlPullParser.Start_tag with name "task"
-	 */
-	public static DownloadTask getTaskFromXML(XmlPullParser xmlPuller) throws XmlPullParserException, IOException{
-		String url = null;
-		String path = null;
-		String representation = null;
-		int version = -1;
-		
-		int eventType = xmlPuller.getEventType();//get the next token, should be a start tag
-		while(eventType != XmlPullParser.END_DOCUMENT){
-			switch(eventType){
-			case XmlPullParser.START_TAG:
-				String name = xmlPuller.getName().toLowerCase();
-				if(name.equals("url")){
-					if(xmlPuller.getEventType() == XmlPullParser.TEXT){
-						url = xmlPuller.getText();
-					}
-				}else if(name.equals("version")){
-					if(xmlPuller.getEventType() == XmlPullParser.TEXT){
-						version = Integer.parseInt(xmlPuller.getText());
-					}
-				}else if(name.equals("path")){
-					if(xmlPuller.getEventType() == XmlPullParser.TEXT){
-						path = xmlPuller.getText();
-					}
-				}else if(name.equals("representation")){
-					if(xmlPuller.getEventType() == XmlPullParser.TEXT){
-						representation = xmlPuller.getText();
-					}
-				}
-				
-				xmlPuller.getEventType();//endtag
-				break;
-			case XmlPullParser.END_TAG:
-				if(xmlPuller.getName().toLowerCase().equals("task") && url != null && path != null && version != -1 && representation != null){
-					return new DownloadTask(url, path, version, representation);
-				}else{
-					throw new XmlPullParserException(null);
-				}
-			default:
-				throw new XmlPullParserException(null);
-			}
-			eventType = getEventType(xmlPuller);
-		}
-		
-		throw new XmlPullParserException(null);
-	}
-	
-	/**
-	 * Skips whitespaces..
-	 */
-	private static int getEventType(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{
-		int eventType = xmlPuller.next();
-		while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){
-			eventType = xmlPuller.next();
-		}
-		return eventType;
-	}
-}
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/FrontendDataUtils.java	Thu Nov 24 13:40:17 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/FrontendDataUtils.java	Thu Nov 24 13:44:30 2011 +0100
@@ -85,8 +85,8 @@
 	}
 
 	public static ArrayList<HashMap<String, ?>> getGraves(Context c){
-		String pathPrefix = Utils.getDownloadPath(c) + "Graphics/Graves/";
-		ArrayList<String> names = Utils.getFilesFromDirWithSuffix(c, "Graphics/Graves", ".png", true);
+		String pathPrefix = Utils.getDataPath(c) + "Graphics/Graves/";
+		ArrayList<String> names = Utils.getFilesFromDirWithSuffix(c,"Graphics/Graves", ".png", true);
 		ArrayList<HashMap<String, ?>> data = new ArrayList<HashMap<String, ?>>(names.size());
 
 		for(String s : names){
@@ -106,7 +106,7 @@
 	}
 
 	public static ArrayList<HashMap<String, ?>> getFlags(Context c){
-		String pathPrefix = Utils.getDownloadPath(c) + "Graphics/Flags/";
+		String pathPrefix = Utils.getDataPath(c) + "Graphics/Flags/";
 		ArrayList<String> names = Utils.getFilesFromDirWithSuffix(c, "Graphics/Flags", ".png", true);
 		ArrayList<HashMap<String, ?>> data = new ArrayList<HashMap<String, ?>>(names.size());
 
@@ -131,7 +131,7 @@
 	}
 
 	public static ArrayList<String> getForts(Context c){
-		return Utils.getFilesFromDirWithSuffix(c, "Forts", "L.png", true);
+		return Utils.getFilesFromDirWithSuffix(c,"Forts", "L.png", true);
 	}
 	public static ArrayList<HashMap<String, ?>> getTypes(Context c){
 		ArrayList<HashMap<String, ?>> data = new ArrayList<HashMap<String, ?>>(6);
@@ -149,8 +149,8 @@
 	}
 
 	public static ArrayList<HashMap<String, ?>> getHats(Context c){
-		ArrayList<String> files = Utils.getFilesFromDirWithSuffix(c, "Graphics/Hats", ".png", true);
-		String pathPrefix = Utils.getDownloadPath(c) + "Graphics/Hats/";
+		ArrayList<String> files = Utils.getFilesFromDirWithSuffix(c,"Graphics/Hats", ".png", true);
+		String pathPrefix = Utils.getDataPath(c) + "Graphics/Hats/";
 		int size = files.size();
 		ArrayList<HashMap<String, ?>> data = new ArrayList<HashMap<String, ?>>(size);
 
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MainActivity.java	Thu Nov 24 13:40:17 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MainActivity.java	Thu Nov 24 13:44:30 2011 +0100
@@ -18,36 +18,54 @@
 
 package org.hedgewars.hedgeroid;
 
-import org.hedgewars.hedgeroid.Downloader.DownloadActivity;
+import org.hedgewars.hedgeroid.Downloader.DownloadAssets;
+import org.hedgewars.hedgeroid.Downloader.DownloadFragment;
 import org.hedgewars.hedgeroid.Downloader.DownloadListActivity;
 import org.hedgewars.hedgeroid.Downloader.DownloadService;
 
-import android.app.Activity;
+import android.app.ProgressDialog;
 import android.content.Intent;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
+import android.support.v4.app.FragmentActivity;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.Button;
 import android.widget.Toast;
 
-public class MainActivity extends Activity {
+public class MainActivity extends FragmentActivity {
 
-	Button downloader, startGame;
-	
+	private Button downloader, startGame;
+	private ProgressDialog assetsDialog;
+
 	public void onCreate(Bundle sis){
 		super.onCreate(sis);
 		setContentView(R.layout.main);
-		
+
 		downloader = (Button)findViewById(R.id.downloader);
 		startGame = (Button)findViewById(R.id.startGame);
-		
+
 		downloader.setOnClickListener(downloadClicker);
 		startGame.setOnClickListener(startGameClicker);
+
+		boolean assetsCopied = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("assetscopied", false);
+
+		if(!assetsCopied){
+			DownloadAssets assetsAsyncTask = new DownloadAssets(this);
+			assetsDialog = ProgressDialog.show(this, "Please wait a moment", "Moving assets...");
+			assetsAsyncTask.execute((Object[])null);
+		}
 	}
-	
-	
-	
+
+	public void onAssetsDownloaded(boolean result){
+		if(result){
+			PreferenceManager.getDefaultSharedPreferences(this).edit().putBoolean("assetscopied", true).commit();
+		}else{
+			Toast.makeText(this, R.string.download_failed, Toast.LENGTH_LONG);
+		}
+		assetsDialog.dismiss();
+	}
+
 	private OnClickListener downloadClicker = new OnClickListener(){
 		public void onClick(View v){
 			//startActivityForResult(new Intent(getApplicationContext(), DownloadActivity.class), 0);
@@ -57,13 +75,7 @@
 
 	private OnClickListener startGameClicker = new OnClickListener(){
 		public void onClick(View v){
-			if(PreferenceManager.getDefaultSharedPreferences(MainActivity.this).getBoolean(DownloadService.PREF_DOWNLOADED, false))
-				startActivity(new Intent(getApplicationContext(), StartGameActivity.class));
-			else {
-				Toast.makeText(MainActivity.this, R.string.download_userexplain, Toast.LENGTH_LONG).show();
-				startActivityForResult(new Intent(getApplicationContext(), DownloadActivity.class), 0);
-			}
+			startActivity(new Intent(getApplicationContext(), StartGameActivity.class));
 		}
 	};
-	
 }
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java	Thu Nov 24 13:40:17 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java	Thu Nov 24 13:44:30 2011 +0100
@@ -277,7 +277,7 @@
 		//Set up the IPC socket server to communicate with the engine
 		EngineProtocolNetwork ipc = new EngineProtocolNetwork(config);
 
-		String path = Utils.getDownloadPath(SDLActivity.mSingleton);//This represents the data directory
+		String path = Utils.getDataPath(SDLActivity.mSingleton);//This represents the data directory
 		path = path.substring(0, path.length()-1);//remove the trailing '/'
 
 		
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/StartGameActivity.java	Thu Nov 24 13:40:17 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/StartGameActivity.java	Thu Nov 24 13:44:30 2011 +0100
@@ -142,7 +142,7 @@
 
 		public void onItemSelected(AdapterView<?> arg0, View view, int position, long rowId) {
 			String themeName = (String) arg0.getAdapter().getItem(position);
-			Drawable themeIconDrawable = Drawable.createFromPath(Utils.getDownloadPath(StartGameActivity.this) + "Themes/" + themeName + "/icon@2X.png");
+			Drawable themeIconDrawable = Drawable.createFromPath(Utils.getDataPath(StartGameActivity.this) + "Themes/" + themeName + "/icon@2X.png");
 			themeIcon.setImageDrawable(themeIconDrawable);
 			config.theme = themeName;
 		}
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamCreatorActivity.java	Thu Nov 24 13:40:17 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamCreatorActivity.java	Thu Nov 24 13:44:30 2011 +0100
@@ -99,12 +99,11 @@
 			hogName.add((EditText) team_creation_entry
 					.findViewById(R.id.txtTeam1));
 		}
-		ArrayList<HashMap<String, ?>> gravesData = FrontendDataUtils
-				.getGraves(this);
+		ArrayList<HashMap<String, ?>> gravesData = FrontendDataUtils.getGraves(this);
 		SimpleAdapter sa = new SimpleAdapter(this, gravesData,
 				R.layout.spinner_textimg_entry, new String[] { "txt", "img" },
 				new int[] { R.id.spinner_txt, R.id.spinner_img });
-
+		sa.setDropDownViewResource(R.layout.spinner_textimg_dropdown_entry);
 		sa.setViewBinder(viewBinder);
 		grave.setAdapter(sa);
 		grave.setOnFocusChangeListener(focusser);
@@ -114,6 +113,7 @@
 		sa = new SimpleAdapter(this, flagsData, R.layout.spinner_textimg_entry,
 				new String[] { "txt", "img" }, new int[] { R.id.spinner_txt,
 						R.id.spinner_img });
+		sa.setDropDownViewResource(R.layout.spinner_textimg_dropdown_entry);
 		sa.setViewBinder(viewBinder);
 		flag.setAdapter(sa);
 		flag.setOnFocusChangeListener(focusser);
@@ -123,6 +123,7 @@
 		sa = new SimpleAdapter(this, typesData, R.layout.spinner_textimg_entry,
 				new String[] { "txt", "img" }, new int[] { R.id.spinner_txt,
 						R.id.spinner_img });
+		sa.setDropDownViewResource(R.layout.spinner_textimg_dropdown_entry);
 		difficulty.setAdapter(sa);
 		difficulty.setOnFocusChangeListener(focusser);
 
@@ -131,6 +132,7 @@
 		sa = new SimpleAdapter(this, hatsData, R.layout.spinner_textimg_entry,
 				new String[] { "txt", "img" }, new int[] { R.id.spinner_txt,
 						R.id.spinner_img });
+		sa.setDropDownViewResource(R.layout.spinner_textimg_dropdown_entry);
 		sa.setViewBinder(viewBinder);
 		for (Spinner spin : hogHat) {
 			spin.setAdapter(sa);
@@ -138,12 +140,14 @@
 
 		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
 				R.layout.listview_item, FrontendDataUtils.getVoices(this));
+		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 		voice.setAdapter(adapter);
 		voice.setOnFocusChangeListener(focusser);
 		voiceButton.setOnClickListener(voiceClicker);
 
 		adapter = new ArrayAdapter<String>(this, R.layout.listview_item,
 				FrontendDataUtils.getForts(this));
+		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 		fort.setAdapter(adapter);
 		fort.setOnItemSelectedListener(fortSelector);
 		fort.setOnFocusChangeListener(focusser);
@@ -294,7 +298,7 @@
 			settingsChanged = true;
 			String fortName = (String) arg0.getAdapter().getItem(position);
 			Drawable fortIconDrawable = Drawable.createFromPath(Utils
-					.getDownloadPath(TeamCreatorActivity.this)
+					.getDataPath(TeamCreatorActivity.this)
 					+ "Forts/"
 					+ fortName + "L.png");
 			imgFort.setImageDrawable(fortIconDrawable);
@@ -314,7 +318,7 @@
 		public void onClick(View v) {
 			try {
 				File dir = new File(String.format("%sSounds/voices/%s",
-						Utils.getDownloadPath(TeamCreatorActivity.this),
+						Utils.getDataPath(TeamCreatorActivity.this),
 						voice.getSelectedItem()));
 				String file = "";
 				File[] dirs = dir.listFiles();
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Utils.java	Thu Nov 24 13:40:17 2011 +0100
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Utils.java	Thu Nov 24 13:44:30 2011 +0100
@@ -30,29 +30,35 @@
 import android.content.res.TypedArray;
 import android.os.Build;
 import android.os.Environment;
+import android.util.Log;
 import android.widget.Toast;
 
 public class Utils {
 
+	private static final String ROOT_DIR = "Data/";
 	
 	/**
 	 * get the path to which we should download all the data files
 	 * @param c context 
 	 * @return absolute path
 	 */
-	public static String getDownloadPath(Context c){
+	public static String getCachePath(Context c){
 		if(Build.VERSION.SDK_INT < 8){//8 == Build.VERSION_CODES.FROYO
-			return PreFroyoSDCardDir.getDownloadPath(c);
+			return PreFroyoSDCardDir.getDownloadPath(c) + '/';
 		}else{
-			return FroyoSDCardDir.getDownloadPath(c);
+			return FroyoSDCardDir.getDownloadPath(c) + '/';
 		}
 	}
 	
+	public static String getDataPath(Context c){
+		return getCachePath(c) + ROOT_DIR;
+	}
+	
 	static class FroyoSDCardDir{
 		public static String getDownloadPath(Context c){
 			File f =  c.getExternalCacheDir();
 			if(f != null){
-				return f.getAbsolutePath() + "/Data/";
+				return f.getAbsolutePath();
 			}else{
 				Toast.makeText(c, R.string.sdcard_not_mounted, Toast.LENGTH_LONG).show();
 				return null;
@@ -78,11 +84,15 @@
 	 * @return string of files
 	 */
 	public static String[] getFileNamesFromRelativeDir(Context c, String dirName){
-		String prefix = getDownloadPath(c);
+		String prefix = getDataPath(c);
 		File f = new File(prefix + dirName);
 		
 		if(f.exists() && f.isDirectory()) return f.list();
-		else throw new IllegalArgumentException("File not a directory or doesn't exist dirName = " + f.getAbsolutePath());
+		else{
+			
+			Log.e("Utils::", "Couldn't find dir: " + dirName);
+			return new String[0];
+		}
 	}
 	
 	/**
@@ -92,11 +102,14 @@
 	 * @return
 	 */
 	public static File[] getFilesFromRelativeDir(Context c, String dirName){
-		String prefix = getDownloadPath(c);
+		String prefix = getDataPath(c);
 		File f = new File(prefix + dirName);
 		
 		if(f.exists() && f.isDirectory()) return f.listFiles();
-		else throw new IllegalArgumentException("File not a directory or doesn't exist dirName = " + f.getAbsolutePath());
+		else {
+			Log.e("Utils::", "Dir not found: " + dirName);
+			return new File[0];
+		}
 	}
 	
 	/**