package vandy.mooc.view;
import vandy.mooc.MVP;
import vandy.mooc.R;
import vandy.mooc.common.GenericActivity;
import vandy.mooc.common.Utils;
import vandy.mooc.presenter.ImagePresenter;
import android.app.ActionBar.LayoutParams;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.webkit.URLUtil;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
/**
* This Activity prompts the user for URLs of images to download
* concurrently via the ImagePresenter and view via the
* DisplayImagesActivity. It plays the role of the "View" in the
* Model-View-Presenter (MVP) pattern. It extends GenericActivity
* that provides a framework to automatically handle runtime
* configuration changes of an ImagePresenter object, which plays the
* role of the "Presenter" in the MVP pattern. The
* MPV.RequiredViewOps and MVP.ProvidedPresenterOps interfaces are
* used to minimize dependencies between the View and Presenter
* layers.
*/
public class DownloadImagesActivity
extends GenericActivity<MVP.RequiredViewOps,
MVP.ProvidedPresenterOps,
ImagePresenter>
implements MVP.RequiredViewOps {
/**
* EditText field for entering the desired URL to an image.
*/
protected EditText mUrlEditText;
/**
* Linear layout to store TextViews displaying URLs.
*/
protected LinearLayout mLinearLayout;
/**
* Display progress to the user.
*/
protected ProgressBar mLoadingProgressBar;
/**
* Menu on main screen
*/
protected Menu mServiceMenu;
/**
* Hook method called when a new instance of Activity is created.
* One time initialization code goes here, e.g., UI layout
* initialization and initializing the GenericActivity framework.
*
* @param savedInstanceState
* Object that contains saved state information.
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
// Perform first part of initializing the super class.
super.onCreate(savedInstanceState);
// Set the default layout.
setContentView(R.layout.download_images_activity);
// (Re)initialize all the View fields.
initializeViewFields();
// Perform second part of initializing the super class,
// passing in the ImagePresenter class to instantiate/manage
// and "this" to provide ImagePresenter with the
// MVP.RequiredViewOps instance.
super.onCreate(ImagePresenter.class,
this);
}
/**
* Hook method called by Android when this Activity becomes
* invisible.
*/
@Override
protected void onDestroy() {
// Destroy the presenter layer, passing in whether this is
// triggered by a runtime configuration or not.
getPresenter().onDestroy(isChangingConfigurations());
// Always call super class for necessary operations when
// stopping.
super.onDestroy();
}
/**
* Initialize the View fields.
*/
private void initializeViewFields() {
// Store the ProgressBar in a field for fast access.
mLoadingProgressBar =
(ProgressBar) findViewById(R.id.progressBar_loading);
// Store the EditText that holds the urls entered by the user
// (if any).
mUrlEditText =
(EditText) findViewById(R.id.url);
// Store the linear layout displaying URLs entered.
mLinearLayout =
(LinearLayout) findViewById(R.id.linearLayout);
}
/**
* Called by the Android Activity framework when the user presses
* the "Download" button in the UI.
*
* @param view The view.
*/
public void downloadImages(View view) {
getPresenter().startProcessing();
}
/**
* Add whatever URL has been entered into the text field if that
* URL is valid when user presses the "Add URL" button in UI.
*/
public void addUrl(View view) {
// Get the user input (if any).
final String url =
mUrlEditText.getText().toString();
// Do sanity check for syntactic validity of the URL.
if (URLUtil.isValidUrl(url)) {
// Add valid URL to running list for download.
getPresenter().getUrlList().add(Uri.parse(url));
// (Re)display all the URLs.
displayUrls();
} else
Utils.showToast(this,
"Invalid URL "
+ url);
}
/**
* Delete the previously downloaded pictures and directories when
* user presses the "Delete Downloaded Image(s)" button in the UI.
*/
public void deleteDownloadedImages(View view) {
getPresenter().deleteDownloadedImages();
}
/**
* Make the ProgressBar visible.
*/
@Override
public void displayProgressBar() {
mLoadingProgressBar.setVisibility(View.VISIBLE);
}
/**
* Make the ProgressBar invisible.
*/
@Override
public void dismissProgressBar() {
mLoadingProgressBar.setVisibility(View.INVISIBLE);
}
/**
* Handle failure to download an image at @a url.
*/
@Override
public void reportDownloadFailure(Uri url,
boolean downloadsComplete) {
Utils.showToast(this,
"Invalid URL: image at "
+ url.toString()
+ " failed to download!");
// Remove the URL that failed from the UI.
removeUrl(url,
downloadsComplete);
if (downloadsComplete)
// Dismiss the progress bar.
mLoadingProgressBar.setVisibility(View.INVISIBLE);
}
/**
* Remove a URL that couldn't be downloaded.
*/
private void removeUrl(Uri url,
boolean downloadsComplete) {
// Check if passed URL is in the list of URLs.
if (getPresenter().getUrlList().contains(url)) {
// Remove the invalid URL from the list.
getPresenter().getUrlList().remove(url);
} else {
// Warn caller that URL was not in the list.
Log.w(TAG,
"RemoveUrl() - passed URL ("
+ (url == null ? "null" : url.toString())
+ ") is not in URL list.");
}
// If there are no more downloads pending dismiss the progress
// bar.
if (downloadsComplete)
mLoadingProgressBar.setVisibility(View.INVISIBLE);
// (Re)display the URLs provided by the user thus far.
displayUrls();
}
/**
* Display the URLs provided by the user thus far.
*/
@Override
public void displayUrls() {
// First remove all URL views in the parent LinearLayout
mLinearLayout.removeAllViews();
// Add a each URL list entry as a text view child of the
// parent LinearLayout.
for (Uri url: getPresenter().getUrlList()) {
TextView urlTextView = new TextView(this);
urlTextView.setLayoutParams
(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
urlTextView.setText(url.toString());
mLinearLayout.addView(urlTextView);
}
// Clear the URL input view.
mUrlEditText.setText("");
}
/**
* Start the DisplayImagesActivity to display the results of the
* download to the user.
*/
@Override
public void displayResults(Uri directoryPathname) {
// Create an Activity for displaying the images.
final Intent intent =
DisplayImagesActivity.makeIntent
(directoryPathname);
Log.d(TAG,
"starting DisplayImageActivity at "
+ directoryPathname.toString());
// Verify that the intent will resolve to an Activity.
if (intent.resolveActivity(getPackageManager()) != null)
// Launch Activity to display the results.
startActivity(intent);
}
}