package com.nuscomputing.ivle.online;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
import android.widget.Toast;
import com.actionbarsherlock.app.SherlockListFragment;
import com.koushikdutta.urlimageviewhelper.UrlImageViewHelper;
import com.nuscomputing.ivle.DataLoader;
import com.nuscomputing.ivle.IVLEUtils;
import com.nuscomputing.ivle.R;
import com.nuscomputing.ivlelapi.FailedLoginException;
import com.nuscomputing.ivlelapi.IVLE;
import com.nuscomputing.ivlelapi.JSONParserException;
import com.nuscomputing.ivlelapi.Lecturer;
import com.nuscomputing.ivlelapi.Module;
import com.nuscomputing.ivlelapi.NetworkErrorException;
import com.nuscomputing.ivlelapi.NoSuchModuleException;
/**
* Fragment to list modules.
* @author yjwong
*/
public class ModuleLecturersFragment extends SherlockListFragment {
// {{{ properties
/** TAG for logging */
public static final String TAG = "ModuleLecturersFragment";
/** The layout inflater */
private LayoutInflater mLayoutInflater;
/** The module IVLE ID */
private String mModuleIvleId;
/** The cached list of photo URLs */
private URL[] mCachedURLs;
// }}}
// {{{ methods
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// If the list is empty, show this.
setEmptyText(getString(R.string.module_lecturers_fragment_no_lecturers));
// Obtain the module ID.
Bundle args = getArguments();
mModuleIvleId = args.getString("moduleIvleId");
if (mModuleIvleId == null) {
throw new IllegalStateException("No module IVLE ID was passed to ModuleLecturersFragment");
}
// Get the layout inflater.
mLayoutInflater = getActivity().getLayoutInflater();
// Load the lecturers.
getLoaderManager().initLoader(DataLoader.LOADER_MODULE_LECTURERS_FRAGMENT, args, new LecturersLoaderCallbacks());
}
// }}}
// {{{ classes
/**
* The list adapter for lecturers.
* @author yjwong
*/
@TargetApi(11)
class LecturerAdapter extends ArrayAdapter<Lecturer> {
// {{{ methods
public LecturerAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
}
public LecturerAdapter(Context context, int textViewResourceId,
List<Lecturer> objects) {
super(context, textViewResourceId, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the item.
final Lecturer lecturer = getItem(position);
// Inflate list item from layout XML.
convertView = mLayoutInflater.inflate(R.layout.module_lecturers_fragment_list_item, null);
// Set the name.
TextView tvName = (TextView) convertView.findViewById(R.id.module_lecturers_fragment_list_name);
tvName.setText(lecturer.user.name);
// Set the role.
TextView tvRole = (TextView) convertView.findViewById(R.id.module_lecturers_fragment_list_role);
tvRole.setText(lecturer.role);
// Set the photo.
ImageView ivPhoto = (ImageView) convertView.findViewById(R.id.module_lecturers_fragment_list_photo);
PhotoURLTask ivPhotoTask = new PhotoURLTask();
ivPhotoTask.execute(ivPhoto, lecturer, position);
// Set the spinner.
Spinner spinner = (Spinner) convertView.findViewById(R.id.module_lecturers_fragment_list_photo_spinner);
LecturerOptionsSpinnerAdapter adapter = new LecturerOptionsSpinnerAdapter(getActivity(), android.R.layout.simple_spinner_dropdown_item, Arrays.asList("Select an item...", "Send email", "Add to contacts"));
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
/** Flag to workaround quirky spinner behaviour */
boolean mInitialLayout = true;
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
// Work around item being selected on layout.
Log.v(TAG, "position = " + position);
if (mInitialLayout) {
mInitialLayout = false;
return;
}
// Check the position.
switch (position) {
case 1:
// Set up the email intent.
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("message/rfc822");
intent.putExtra(Intent.EXTRA_EMAIL, new String[] { lecturer.user.email });
startActivity(Intent.createChooser(intent, getString(R.string.module_lecturers_fragment_email_via)));
break;
case 2:
// Handle add to contacts.
intent = new Intent(Intent.ACTION_INSERT);
intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
intent.putExtra(ContactsContract.Intents.Insert.NAME, lecturer.user.name);
intent.putExtra(ContactsContract.Intents.Insert.EMAIL, lecturer.user.email);
startActivity(intent);
break;
}
parent.setSelection(0);
}
@Override
public void onNothingSelected(AdapterView<?> view) {
// Do nothing.
}
});
// Return the view.
return convertView;
}
// }}}
}
// }}}
// {{{ classes
/**
* Helper class for the activity spinner.
* @author yjwong
*/
public class LecturerOptionsSpinnerAdapter extends ArrayAdapter<String>
implements SpinnerAdapter {
// {{{ properties
/** The list of items */
private List<String> mItems;
/** The context */
private Context mContext;
// }}}
// {{{ methods
LecturerOptionsSpinnerAdapter(Context context, int textViewResourceId, List<String> items) {
super(context, textViewResourceId, items);
mContext = context;
mItems = items;
}
public View getView(int position, View convertView, ViewGroup parent) {
// Inflate the layout for the item.
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.sherlock_spinner_item, null);
}
TextView tvItem = (TextView) convertView.findViewById(android.R.id.text1);
tvItem.setVisibility(View.GONE);
return convertView;
}
public View getDropDownView(int position, View convertView, ViewGroup parent) {
// Return a empty view for position 0.
if (position == 0) {
LinearLayout layout = new LinearLayout(mContext);
layout.setVisibility(View.GONE);
return layout;
}
// Inflate the layout.
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(android.R.layout.simple_list_item_1, null);
String item = mItems.get(position);
if (item != null) {
TextView tvItem = (TextView) convertView.findViewById(android.R.id.text1);
if (tvItem != null) {
tvItem.setText(item);
}
}
return convertView;
}
// }}}
}
/**
* AsyncTask to get the display photo REAL url.
* @author yjwong
*/
class PhotoURLTask extends AsyncTask<Object, Object, URL> {
// {{{ properties
/** The ImageView */
private ImageView mImageView;
/** The lecturer */
private Lecturer mLecturer;
/** The position */
private Integer mPosition;
// }}}
// {{{ methods
@Override
protected URL doInBackground(Object... params) {
// Check arguments.
if (params.length != 3 || !(params[0] instanceof ImageView)
|| !(params[1] instanceof Lecturer
|| !(params[2] instanceof Integer))) {
throw new IllegalArgumentException();
}
// Set arguments.
mImageView = (ImageView) params[0];
mLecturer = (Lecturer) params[1];
mPosition = (Integer) params[2];
// Obtain the HTML content.
if (mCachedURLs[mPosition] == null) {
Log.v(TAG, "URL not found in cache, requesting");
try {
URL url = mLecturer.user.getDisplayPhotoURL(mModuleIvleId);
return url;
} catch (MalformedURLException e) {
// Ignore.
} catch (IOException e) {
// Ignore.
}
} else {
Log.v(TAG, "URL found in cache, returning");
return mCachedURLs[mPosition];
}
return null;
}
@Override
protected void onPostExecute(URL url) {
// Cache the URL.
mCachedURLs[mPosition] = url;
UrlImageViewHelper.setUrlDrawable(mImageView, url.toString());
}
// }}}
}
/**
* The loader callbacks for module information.
* @author yjwong
*/
class LecturersLoaderCallbacks implements
LoaderManager.LoaderCallbacks<List<Lecturer>> {
// {{{ methods
@Override
public Loader<List<Lecturer>> onCreateLoader(int id, Bundle args) {
return new LecturersLoader(getActivity(), args);
}
@Override
public void onLoadFinished(Loader<List<Lecturer>> loader, List<Lecturer> result) {
// Set the view data.
if (result != null) {
if (result.size() == 0) {
// Hide the list.
getListView().setVisibility(View.GONE);
} else {
// Create list of cached URLs.
mCachedURLs = new URL[result.size()];
// Create new list adapter.
LecturerAdapter adapter = new LecturerAdapter(getActivity(), R.id.module_lecturers_fragment_list_name, result);
setListAdapter(adapter);
}
} else {
Toast.makeText(getActivity(), R.string.module_lecturers_fragment_unable_to_load, Toast.LENGTH_SHORT)
.show();
}
}
@Override
public void onLoaderReset(Loader<List<Lecturer>> loader) {
// Do nothing.
}
// }}}
}
/**
* The module information loader.
* @author yjwong
*/
static class LecturersLoader extends AsyncTaskLoader<List<Lecturer>> {
// {{{ properties
/** Arguments to this loader */
private Bundle mArgs;
/** The context */
private Context mContext;
/** The list of lecturers */
private List<Lecturer> mLecturers;
// }}}
// {{{ methods
LecturersLoader(Context context, Bundle args) {
super(context);
mContext = context;
mArgs = args;
}
@Override
public void onStartLoading() {
if (mLecturers != null ) {
deliverResult(mLecturers);
}
if (takeContentChanged() || mLecturers == null) {
forceLoad();
}
}
@Override
public List<Lecturer> loadInBackground() {
// Obtain the IVLE ID.
String moduleIvleId = mArgs.getString("moduleIvleId");
// Acquire a new IVLE object.
IVLE ivle = IVLEUtils.getIVLEInstance(mContext);
try {
Module module = ivle.getModule(moduleIvleId);
Lecturer[] lecturers = module.getLecturers();
mLecturers = Arrays.asList(lecturers);
return mLecturers;
} catch (NetworkErrorException e) {
Log.e(TAG, "NetworkErrorException encountered while loading lecturers");
} catch (FailedLoginException e) {
Log.e(TAG, "FailedLoginException encountered while loading lecturers");
} catch (JSONParserException e) {
Log.e(TAG, "JSONParserException encountered while loading lecturers");
} catch (NoSuchModuleException e) {
Log.e(TAG, "NoSuchModuleException encountered while loading lecturers");
}
return null;
}
// }}}
}
// }}}
}