package net.hockeyapp.android;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.UUID;

import android.app.Activity;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class UpdateActivity extends ListActivity {
  public static int iconDrawableId = -1;

  private DownloadFileTask downloadTask;
  private UpdateInfoAdapter adapter;
  
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setTitle("Application Update");
    setContentView(R.layout.update_view);
    moveViewBelowOrBesideHeader(this, android.R.id.list, R.id.header_view, 23);

    adapter = new UpdateInfoAdapter(this, getIntent().getStringExtra("json"));
    getListView().setDivider(null);
    setListAdapter(adapter);
    configureView();
    
    downloadTask = (DownloadFileTask)getLastNonConfigurationInstance();
    if (downloadTask != null) {
      downloadTask.attach(this);
    }
  }
  
  private void configureView() {
    if (iconDrawableId != -1) {
      ImageView iconView = (ImageView)findViewById(R.id.icon_view);
      iconView.setImageDrawable(getResources().getDrawable(iconDrawableId));
    }
    
    TextView versionLabel = (TextView)findViewById(R.id.version_label);
    versionLabel.setText("Version " + adapter.getVersionString() + "\n" + adapter.getFileInfoString());
  }

  private static void moveViewBelowOrBesideHeader(Activity activity, int viewID, int headerID, float offset) {
    ViewGroup headerView = (ViewGroup)activity.findViewById(headerID); 
    View view = (View)activity.findViewById(viewID);
    float density = activity.getResources().getDisplayMetrics().density; 
    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, activity.getWindowManager().getDefaultDisplay().getHeight() - headerView.getHeight() + (int)(offset * density));
    if (((String)view.getTag()).equalsIgnoreCase("right")) {
      layoutParams.addRule(RelativeLayout.RIGHT_OF, R.id.header_view);
      layoutParams.setMargins(-(int)(offset * density), 0, 0, (int)(10 * density));
    }
    else {
      layoutParams.addRule(RelativeLayout.BELOW, R.id.header_view);
      layoutParams.setMargins(0, -(int)(offset * density), 0, (int)(10 * density));
    }
    view.setLayoutParams(layoutParams);
  }

  @Override
  public Object onRetainNonConfigurationInstance() {
    if (downloadTask != null) {
      downloadTask.detach();
    }
    return downloadTask;
  }
  
  public void onClickUpdate(View v) {
    startDownloadTask();
  }
  
  private void startDownloadTask() {
    downloadTask = new DownloadFileTask(this, getIntent().getStringExtra("url"));
    downloadTask.execute();
  }

  private class DownloadFileTask extends AsyncTask<String, Integer, Void>{
    private Context context;
    private String urlString;
    private String filename;
    private ProgressDialog progressDialog;

    public DownloadFileTask(Context context, String urlString) {
      this.context = context;
      this.urlString = urlString;
      this.filename = "download/" + UUID.randomUUID() + ".apk";
    }
    
    public void attach(Context context) {
      this.context = context;
    }
    
    public void detach() {
      context = null;
      progressDialog = null;
    }

    @Override
    protected Void doInBackground(String... args) {
      try {
        URL url = new URL(getURLString());
        URLConnection connection = url.openConnection();
        connection.connect();

        int lenghtOfFile = connection.getContentLength();

        InputStream input = new BufferedInputStream(connection.getInputStream());
        OutputStream output = new FileOutputStream(new File(Environment.getExternalStorageDirectory(), this.filename));

        byte data[] = new byte[1024];
        int count = 0;
        long total = 0;
        while ((count = input.read(data)) != -1) {
          total += count;
          publishProgress((int)(total * 100 / lenghtOfFile));
          output.write(data, 0, count);
        }

        output.flush();
        output.close();
        input.close();
      } 
      catch (Exception e) {
        e.printStackTrace();
      }
      return null;
    }
  
     @Override
     protected void onProgressUpdate(Integer... args){
       if (progressDialog == null) {
         progressDialog = new ProgressDialog(context);
         progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
         progressDialog.setMessage("Loading...");
         progressDialog.setCancelable(false);
         progressDialog.show();
       }
       progressDialog.setProgress(args[0]);
     }
     
     @Override
     protected void onPostExecute(Void result) {
       if (progressDialog != null) {
         progressDialog.dismiss();
       }
       
       Intent intent = new Intent(Intent.ACTION_VIEW);
       intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory(), this.filename)), "application/vnd.android.package-archive");
       intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
       startActivity(intent);
     }

     private String getURLString() {
       return urlString + "&type=apk";      
     }
  }
}

@@ -3384,16 +3384,45 @@
 lename;%0A
+    private String filePath;%0A
     priv
@@ -3611,22 +3611,8 @@
 me =
- %22download/%22 +
  UUI
@@ -3636,16 +3636,113 @@
 %22.apk%22;%0A
+      this.filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + %22/Download%22;%0A
     %7D%0A  
@@ -4176,24 +4176,141 @@
 tLength();%0A%0A
+        File dir = new File(this.filePath);%0A        dir.mkdirs();%0A        File file = new File(dir, this.filename);%0A%0A
         Inpu
@@ -4434,74 +4434,12 @@
 eam(
-new File(Environment.getExternalStorageDirectory(), this.filename)
+file
 );%0A%0A
@@ -5580,49 +5580,21 @@
 ile(
-Environment.getExternalStorageDirectory()
+this.filePath
 , th

Fix for handling missing Download directory on SD card..